Intro

Plots.jl is an interface for many different backends. But which backend to choose?

Each one supports different features, outputs slightly differently, and takes up different amounts of resources. Below, you will see three different plots generated for each of the different backends I tried to get working. I have historically used pyplot, gr, and plotlyjs, so those were already working for me. The pdfplots, unicodeplots, and inspectdr did not work out of the box. If you have timing information on these, feel free to contribute to this repsitory.

Julia optimizes and compiles a function the first time it runs, and the macro @time reflects that. Therefore, I run the function twice, and take the data reported on the second run.

Thanks to @jheinan for pointing out that I needed to use backend(show=true) to compute both the interface and the backend computation costs, and not just the interface costs.

Test1

I'll first run on a very simple function:

 plot(x,y)

Remember that though @time returned a time and memory usage for pgfplots, unicodeplots, and inspectdr, none of these backends worked for me.

Backend Time Mem
pyplot .28 452 kB
gr .01 166 kB
plotlyjs .25 743 kB
unicodeplots .18 2.7 Mb

Test2

Next, I'll compare on something more intensize:

   heatmap(z2d,
        title="title",
        xlabel="xlabel",
        ylabel="ylabel",
        seriescolor=:viridis
        ) 
    annotate!(50,50,"Hi! How long with this take?")

Neither pgfplots, unicodeplots, nor inspectdr support heatmap. While for the first test, the plots looked quite similiar, in this test, differences in how they place and render things start to show.

Backend Time Mem
pyplot .98 1.2 MiB
gr .2 5.8 MiB
plotlyjs .11 7.8 Mb

Test 3

My third function

    plot(x,y1,linetype=:sticks)
    plot!(x,y2,line=:dot)
    plot!(x,y3,width=10,linealpha=.2)
    scatter!(x,y4,marker=Shape(custom_marker))

also posed issues for pgfplots, unicodeplots, and inspectdr.

Backend Time Mem
pyplot 1.29 2 MiB
gr .07 1.7 MiB
plotlyjs .03 2.7 MB

Plotlyjs would not support a custom marker.


In [1]:
using Plots

In [2]:
x=collect(0:.1:4π);
y=cos.(x);

In [3]:
pyplot(show=true)
@time plot(x,y)
@time plot(x,y)


 24.487038 seconds (8.08 M allocations: 440.489 MiB, 1.89% gc time)
  0.285459 seconds (11.39 k allocations: 452.063 KiB)
Out[3]:

In [4]:
gr(show=true)
@time plot(x,y)
@time plot(x,y)


  9.297229 seconds (3.76 M allocations: 191.861 MiB, 1.67% gc time)
  0.015427 seconds (3.33 k allocations: 166.797 KiB)
Out[4]:
0.0 2.5 5.0 7.5 10.0 12.5 -0.5 0.0 0.5 1.0 y1

In [5]:
plotlyjs(show=true)
@time plot(x,y)
@time plot(x,y)


Plotly javascript loaded.

To load again call

init_notebook(true)

 
17.322605 seconds (6.19 M allocations: 332.526 MiB, 2.91% gc time)
  0.257461 seconds (16.48 k allocations: 743.716 KiB)
Out[5]:

In [ ]:
pgfplots(show=true)
@time plot(x,y)
@time plot(x,y)

In [6]:
unicodeplots(show=true)
@time plot(x,y)
@time plot(x,y)


WARNING: filter(flt, itr) is deprecated, use Iterators.filter(flt, itr) instead.
Stacktrace:
 [1] depwarn(::String, ::Symbol) at .\deprecated.jl:70
 [2] filter(::Function, ::Base.Iterators.Zip2{Array{Float64,1},Array{Float64,1}}) at .\deprecated.jl:57
 [3] addUnicodeSeries!(::UnicodePlots.Plot{UnicodePlots.AsciiCanvas}, ::Dict{Symbol,Any}, ::Bool, ::Array{Float64,1}, ::Array{Float64,1}) at C:\Users\chris\.julia\v0.6\Plots\src\backends\unicodeplots.jl:161
 [4] rebuildUnicodePlot!(::Plots.Plot{Plots.UnicodePlotsBackend}, ::Int64, ::Int64) at C:\Users\chris\.julia\v0.6\Plots\src\backends\unicodeplots.jl:123
 [5] unicodeplots_rebuild(::Plots.Plot{Plots.UnicodePlotsBackend}) at C:\Users\chris\.julia\v0.6\Plots\src\backends\unicodeplots.jl:200
 [6] _display at C:\Users\chris\.julia\v0.6\Plots\src\backends\unicodeplots.jl:211 [inlined]
 [7] display at C:\Users\chris\.julia\v0.6\Plots\src\output.jl:134 [inlined]
 [8] gui at C:\Users\chris\.julia\v0.6\Plots\src\output.jl:123 [inlined]
 [9] _do_plot_show(::Plots.Plot{Plots.UnicodePlotsBackend}, ::Bool) at C:\Users\chris\.julia\v0.6\Plots\src\output.jl:141
 [10] _plot!(::Plots.Plot{Plots.UnicodePlotsBackend}, ::Dict{Symbol,Any}, ::Tuple{Array{Float64,1},Array{Float64,1}}) at C:\Users\chris\.julia\v0.6\Plots\src\plot.jl:238
 [11] #plot#136(::Array{Any,1}, ::Function, ::Array{Float64,1}, ::Vararg{Array{Float64,1},N} where N) at C:\Users\chris\.julia\v0.6\Plots\src\plot.jl:52
 [12] plot(::Array{Float64,1}, ::Array{Float64,1}, ::Vararg{Array{Float64,1},N} where N) at C:\Users\chris\.julia\v0.6\Plots\src\plot.jl:46
 [13] include_string(::String, ::String) at .\loading.jl:515
 [14] execute_request(::ZMQ.Socket, ::IJulia.Msg) at C:\Users\chris\.julia\v0.6\IJulia\src\execute_request.jl:160
 [15] eventloop(::ZMQ.Socket) at C:\Users\chris\.julia\v0.6\IJulia\src\eventloop.jl:8
 [16] (::IJulia.##11#14)() at .\task.jl:335
while loading In[6], in expression starting on line 237
      +------------------------------------------------------------+   
    1 |\.               ./\.               ,`                      | y1
      | \              ./  l              .`                       |   
      | ",             /   |.             /                        |   
      |  l             /    \            .`                        |   
      |  |,           ,`    |            .                         |   
      |   .           |      |           |                         |   
      |   l           |      |           |                         |   
      |   ",         ,`      |          .                          |   
      |    .         /        |         |                          |   
      |    l         /        \         |                          |   
      |""""\7"""""""=/""""""""]""""""""]""""""""""""""""""""""""""`|   
      |     |       .         ",       |                           |   
      |     |       |          .       |                           |   
      |     |       |          l      ,`                           |   
      |      |     .           ",     /                            |   
      |      \     |            .     |                            |   
      |      |.   ,`            l    ,`                            |   
      |       .   /             ",   |                             |   
      |       \. .`              \  ,`                             |   
   -1 |        \_/                L_/                              |   
      +------------------------------------------------------------+   
      0                                                           20
  6.936971 seconds (1.47 M allocations: 78.595 MiB, 0.82% gc time)
      +------------------------------------------------------------+   
    1 |\.               ./\.               ,`                      | y1
      | \              ./  l              .`                       |   
      | ",             /   |.             /                        |   
      |  l             /    \            .`                        |   
      |  |,           ,`    |            .                         |   
      |   .           |      |           |                         |   
      |   l           |      |           |                         |   
      |   ",         ,`      |          .                          |   
      |    .         /        |         |                          |   
      |    l         /        \         |                          |   
      |""""\7"""""""=/""""""""]""""""""]""""""""""""""""""""""""""`|   
      |     |       .         ",       |                           |   
      |     |       |          .       |                           |   
      |     |       |          l      ,`                           |   
      |      |     .           ",     /                            |   
      |      \     |            .     |                            |   
      |      |.   ,`            l    ,`                            |   
      |       .   /             ",   |                             |   
      |       \. .`              \  ,`                             |   
   -1 |        \_/                L_/                              |   
      +------------------------------------------------------------+   
      0                                                           20
  0.183009 seconds (81.03 k allocations: 2.814 MiB)
StackOverflowError:

In [ ]:
inspectdr(show=true)
@time plot(x,y)
@time plot(x,y)

more elaborate test


In [7]:
x2d=repmat(x,1,length(x))
y2d=repmat(transpose(x),length(x),1)
z2d=sin.(x2d).*sin.(y2d);

function plot2()
   heatmap(z2d,
        title="title",
        xlabel="xlabel",
        ylabel="ylabel",
        seriescolor=:viridis
        ) 
    annotate!(50,50,"Hi! How long with this take?")
    
end


Out[7]:
plot2 (generic function with 1 method)

In [8]:
pyplot(show=true)
@time plot2()
@time plot2()


 12.502414 seconds (2.03 M allocations: 106.664 MiB, 0.87% gc time)
  0.986271 seconds (39.11 k allocations: 1.237 MiB)
Out[8]:

In [9]:
gr(show=true)
@time plot2()
@time plot2()


  7.505258 seconds (2.70 M allocations: 128.041 MiB, 2.33% gc time)
  0.203633 seconds (212.05 k allocations: 5.812 MiB)
Out[9]:
50 100 50 100 title xlabel ylabel - 1.00 - 0.75 - 0.50 - 0.25 0 0.25 0.50 0.75 1.00 Hi! How long with this take?

In [11]:
plotlyjs(show=true)
@time plot2()
@time plot2()


  1.371717 seconds (787.40 k allocations: 22.096 MiB, 1.99% gc time)
  0.118565 seconds (345.65 k allocations: 7.872 MiB)
Out[11]:

In [ ]:
pgfplots()
@time plot2()
@time plot2()

In [ ]:
unicodeplots()
@time plot2()
@time plot2()

In [ ]:
inspectdr()
@time plot2()
@time plot2()

Test number 3


In [12]:
x=collect(0:0.01:5)
y1=x;
y2=x.^2;
y3=10*sin.(x);
y4=randn(length(x));

custom_marker=[(-1,-1),
        (-1,1),
        (1,1),
        (1,-1)];

function plot3()
    plot(x,y1,linetype=:sticks)
    plot!(x,y2,line=:dot)
    plot!(x,y3,width=10,linealpha=.2)
    scatter!(x,y4,marker=Shape(custom_marker))
    
end


Out[12]:
plot3 (generic function with 1 method)

In [13]:
pyplot(show=true)
@time plot3()
@time plot3()


  2.476840 seconds (312.92 k allocations: 15.897 MiB)
  1.290602 seconds (54.34 k allocations: 2.008 MiB)
Out[13]:

In [14]:
gr(show=true)
@time plot3()
@time plot3()


  0.562356 seconds (138.36 k allocations: 6.857 MiB)
  0.079824 seconds (35.40 k allocations: 1.734 MiB)
Out[14]:
0 2 4 -10 0 10 20 y1 y2 y3 y4

In [15]:
plotlyjs(show=true)
@time plot3()
@time plot3()


WARNING: markershape Plots.Shape([-1.0, -1.0, 1.0, 1.0], [-1.0, 1.0, 1.0, -1.0]) is unsupported with Plots.PlotlyJSBackend().  Choose from: Symbol[:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :pentagon, :hexagon, :octagon, :vline, :hline]
  1.528692 seconds (204.80 k allocations: 8.585 MiB, 1.31% gc time)
  0.038036 seconds (86.21 k allocations: 2.743 MiB)
WARNING: markershape Plots.Shape([-1.0, -1.0, 1.0, 1.0], [-1.0, 1.0, 1.0, -1.0]) is unsupported with Plots.PlotlyJSBackend().  Choose from: Symbol[:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :pentagon, :hexagon, :octagon, :vline, :hline]
Out[15]:

In [ ]:
pgfplots()
@time plot3()
@time plot3()

In [ ]:
unicodeplots()
@time plot3()
@time plot3()

In [ ]:
inspectdr()
@time plot3()
@time plot3()

In [ ]: