Why is Julia's graphics system so slow?

Hi, all,

I am relatively new to Julia, and am using Julia 1.6.2 as well as newest Plots.jl, pyplot.jl and Gadfly.jl. I am programming Julia using vs code extension.

I find that drawing charts and plots in Julia is particularly slow. Sometimes it takes me 10 seconds to draw a simple scatter plot with 200 points, both using Plots with pyplot back end or Gadfly. This is especially true when compared with base R or ggplot2 solutions.

I am just curious if it is my configuration which causes the time-consuming plotting process, or the graphics solutions in Julia is slow by nature? Is there any possible solutions to this issue?

Thanks.

Do you experience this slowness only on the first invocation of a particular plot or always. The former is expected -it even has a name “time to first plot”- the latter should not happen.

The reduction of “time to first plot” is actively being worked on (yes it was a lot worse). It is caused by Julia compiling the needed functions on the fly (precompilation only does half of all the compile work).

If you search for “time to first plot” you will find a large amount of reading material…

5 Likes

If you google time to first plot julia you can get a lot more information on the topic, including all the work the devs are doing/have done to reduce this lag.

Once I compiled a system image with StatsPlots, DataFrames, StatsBase, and such, it made time to first plot very small… See A Julia DataAnalysis Sysimage from PackageCompiler It’s so easy you should do it too!

3 Likes

You could also give VegaLite.jl a try, it has pretty good startup time.

2 Likes

Hi @aachener,

(Probable) Cause

From what I can tell, it appears the slowness comes from VSCodeServer's SVG rendering facilities.

It is indeed more noticeable for scatter plots — or any plot that requires the rendering engine to generate alot of “plot markers”.

Background

On my own system, it seems like a Plots.jl over VSCode plotting pane solution defaults to SVG (your solution may differ).

I have also noticed that, when generating scatter plots, the VSCode plot pane is significantly slower than what I get for Plots.jl over Jupyter notebooks (in VSCode).

(You might also be interested in knowing Jupyter also renders SVG by default, so the run times should be comparable.)

Quick test/workaround:

As a quick hack, you can remove the "image/svg+xml" mime from the list of mimes supported by the plotting pane (only affects current Julia session):

using Plots

###############################################################################
# ADD THIS BLOCK TO REMOVE SVG FROM LIST OF "DISPLAYABLE_MIMES":
pos = findfirst((x)->(x=="image/svg+xml"), VSCodeServer.DISPLAYABLE_MIMES)
if !isnothing(pos)
    popat!(VSCodeServer.DISPLAYABLE_MIMES, pos)
    println("Popped!")
end
###############################################################################

#A simple test plot here:
x = range(-100, 100, length=1001)
y = 3 * x .* x
p=plot(x, y, line=(2, :red), marker=(:hexagon, 20, 0.6, :green))
display(p)

Follow-up

Does this help with your problem?

If so, maybe @davidanthoff / the VSCode team can propose a better permanent solution.

6 Likes

Ah, very interesting! Could you open an issue over at the Julia extension repo?

My favorite tool to force a given MIME type is GitHub - tkf/DisplayAs.jl, that would probably also work here.

4 Likes

I have noticed this too for SVG content plotted using julia and vscode, and its gotten worse recently for some reason. Plots are much more responsive in the plots pane if I first save the plot and then use display("image/png", my_plot).

1 Like

I am guessing this is what you meant by “Julia extension repo”:

Ah yes. I forgot display allows you to specify the preferred mime-type.

Though I would suggest passing mime information as a MIME object — since I personally feel it is less ambiguous for julia dispatch:

display(MIME("image/png"), my_plot)
1 Like

This really isn’t an issue with VS Code, it’s an issue with large SVGs in general. IIRC Jupyter shows PNGs by default, which we should do as well, I suppose.

Try

julia> open("out.svg", "w") do io
         show(io, "image/svg+xml", Plots.scatter(1:10000, sin.(1:10000)))
       end; run(`firefox out.svg`)

for a pretty and very slow plot in your browser (the produced SVG is 1.8MiB big, so no wonder).

3 Likes

I don’t think that is true, at least not from my basic testing.

3 Likes

It doesn’t look like it on my system either (neither in the normal browser-based Jupyter — or the VSCode version):
image


NOTE: You can see which mimes are evaluated by clicking on [...] on the LHS of your Jupyter plot:
image

Instead, it appears I need to inhibit the “image/svg+xml” show function (as is done in PyPlot with PyPlot.svg(false)) to get PNG output by default.

Yes. It is probably for the best.

I’m just wondering if that will negatively impact backends like Plotly that support interactive SVGs

I’m having this issue when plotting monte carlo simulations with more than 10^5 random points. I will really apreciate if someone knows how to configure the Plots output to png. SVG is really good for quality, but for some plots with huge random points there are huge performance loss. Vscode dont support large svg files.

You should be able to run:

using Plots
default(fmt=:png)

And this should create png output.

3 Likes

Thank you. That save my work here.

Last I checked, Jupyter shows SVG by default.

In PyPlot I worked around this by defining showable(::MIME"image/svg+xml", ::PyPlot.Figure) = false by default (which prevents that MIME type from being sent to Jupyter, even though the SVG show method exists), with a setting to enable SVG output if desired

even with png, vscode hangs :frowning: Too much memory for that

Pluto can plot this withou any issues.

By any chance are there still old svg plots in the VSCode plot pane? Like if you click the arrows, can you see the plots you made before changing the output to png? If so, try closing them.