JunoLab / Weave.jl

Scientific reports/literate programming for Julia
http://weavejl.mpastell.com
MIT License
831 stars 96 forks source link

Native PyPlot support #199

Open marius311 opened 5 years ago

marius311 commented 5 years ago

I was interested in having native PyPlot support for some of the reasons I mentioned here.

After asking that, I was able to hack together something which basically works. Essentially, for any chunk which you give pyplot=true as an option, it automatically inserts a hidden clf() at the start of the chunk and a gcf() at the end, which makes it so that Weave correctly displays the PyPlot figure generated in that chunk.

The code is pretty simple (given below), you just have to call setup_weave_pyplot before weaving, or you can even just do it in a hidden code cell in your report.

I'm curious if there's any interest in me cleaning this up and submitting a PR? Or is it too hacky? I can definitely understand either way.

const weave_hide_str = "weave_hide_line=true"

function weave_pyplot_preexecute_hook(chunk)
    if get(chunk.options, :pyplot, false)
        chunk.content = """
            import PyPlot; PyPlot.clf() #$weave_hide_str
            $(chunk.content)
            if !isempty(PyPlot.gcf().get_axes()); PyPlot.gcf(); end #$weave_hide_str
        """
    end
    return chunk
end

function weave_pyplot_postexecute_hook(chunk)
    if get(chunk.options, :pyplot, false)
        chunk.result = map(chunk.result) do r
            if occursin(weave_hide_str, r.code)
                Weave.ChunkOutput("", r.stdout, r.displayed, r.rich_output, r.figures)
            else
                r
            end
        end
    end
    return chunk
end

function setup_weave_pyplot()
    if !(weave_pyplot_preexecute_hook in Weave.preexecute_hooks)
        Weave.push_preexecute_hook(weave_pyplot_preexecute_hook)
    end
    if !(weave_pyplot_postexecute_hook in Weave.postexecute_hooks)
        Weave.push_postexecute_hook(weave_pyplot_postexecute_hook);
    end
end
asarkar2 commented 1 year ago

@marius311 : Thanks for the code. Unfortunately, I still couldn't make it work, being new to Julia. Here's what I did. Inserted your code into a file called preweave.jl along with the line using Weave at the top of the file. Called the preweave.jl file by running include("preweave.jl") in REPL followed by setup_weave_pyplot(). Ended up with the error UndefVarError: preexecute_hooks not defined. Can you please explain what I need to do to make your code work?