GR vs GLVisualize comparison?



How do you compare GR to GLVisualize.

Which one can deal better with large datasets?
Which one lets you create simple plots with the lesser code?

I’m looking for a replacement to Gadfly, easy to use but faster and able to eal with large datasets.
For example I want to create a 2D scatterplot with one million points (*) and draw in the same plot a regression line, or plot a 3D scatterplot.

As far as I’ve seen if I want to create a simple plot in GR I need to write a lot of code.

I come from R, I’ve moved to Julia because I think R is quite slow and doesn’t manage the memory well.
There I used ggplot (really slow but easy) or sometimes Lattice (needs a lot of code too).

Interactivity is a plus.
Easiness to export the plots easily to pdf is a plus too.

(*) I know I can reduce/soften the number of points .


I suggest using Plots.jl. It’s pretty easy to use and you can switch between different backends without changing any of the plots’ code.

GR is well suited for large datasets and can also be used through the Plots.jl interface.


GR, PyPlot, and GLVisualize are all on Plots.jl. You can make your plot command and just swap between them to see what works best. They will all pay a one-time “first time to plot” cost though because the “backends” are lazily loaded.


For the initial cost, is there a way to plot a figure silently in .juliarc.jl?

For example, in MATLAB I could use the optional keyword visible = 'off'. Anything similar in Julia and/or Plots.jl?

For the comparison, I also suggest beginning with Plots.jl and go into a specific plotting package if this does not work as you want.


Yes, just load the backend.

using Plots; gr()
# Or a different backend
# Etc.

That will load everything and the first time to plot will be essentially fixed.


Then, if I execute

using GR

Will I be getting a GR plot? Or do I need to use specific GR functions?

Is InspectDR able to generate histograms or more complex plots?


What’s the meaning of GR, GLVisualize and InspectDR being “backends” of Plots.jl?
How does affect me? (instead of being just self-contained packages)


Plots.jl is a single API over many different plotting packages. So the same syntax works on a bunch of different packages, but you just “swap the backend” to get the same result plotted differently. For example:

using Plots
pyplot() # Sets up the pyplot backend
gr() # Changes to the GR backend 
plot(rand(10,10)) # the same syntax works

There’s a bunch of different backends. Some plot “normally” to plot windows, some plot to Javascript, some plot even to the terminal or to LaTeX.

The key is that you can write a package to work with plots through its “recipes”, and then the user can choose which plotting backend they want. Many packages have recipes already setup, so if you use plots, my times a type A in some package might already have a default setup for plot(A).


That seems great, that way I only need to learn one syntax.
Though I guess there are different finetuning options.


The options are all the same, though not every backend is compatible with every option. There’s a chart though:


What’s the difference between generating the plot with these two methods:

using GR


using Plots


The first directly uses GR, the second uses the Plots.jl API with the GR backend. The first will have a quicker startup time right now due to precompilation issues in Plots.jl, while the second will have an enhanced API due to recipes and layout macros etc.


In my experience, you have to actually call plot(whatever) to pay the price for time to first plot, i.e., calling gr() is not enough. This plot command can be put in .juliarc.jl followed by, e.g., closeall() to close the plot again.


@baggepinnen: In my experience, you have to actually call plot(whatever) to pay the price for time to first plot, i.e., calling gr() is not enough. This plot command can be put in .juliarc.jl followed by, e.g., closeall() to close the plot again.

Downside: This will significantly increase Julia’s (effective) startup time, assuming you don’t need to plot all the time. This is because Plots.jl currently is slow to load/has a long time-to-first plot).


@Juan: What’s the difference […]

Just clarifying a bit of what @ChrisRackauckas said:

The two examples look very similar for this particular case. Note that the call syntaxes will start looking much more different if you start generating more complex plots.

Alot of thought seems to have been put into the Plots.jl interface so that “it just does what you would expect it to do”.

NOTE: I do not personally always like that kind of “intelligence” - but I must admit that it does seem to work well (and is often much easier to use than my own solution).


@Juan: Is InspectDR able to generate histograms or more complex plots?

InspectDR now has support for histograms - but this feature is currently only available by using Plots.jl, for example:

using Plots

You can indeed generate more complex plots. The Plots.jl documentation includes some sample output:

Note that InspectDR is limited to 2D plots at the moment - and does not support heatmaps.

Despite its limitations, I still highly recommend trying it - especially with larger datasets: InspectDR is designed to plot multi-gigabyte datasets that are often generated by real-world circuit simulations. It does so by “downsampling” the data in order to dispaly it more quickly.

InspectDR also works very well interactively (easy to pan, zoom, etc.).

Recently, I have added “delta” markers so that you can interactively measure x/y distances between two points. These markers will even show up when you export to .png or .svg - a great way to annotate your results.


When I try it I get this error message:

using Plots

type Multiplot has no field frame

[1] _before_layout_calcs(::Plots.Plot{Plots.InspectDRBackend}) at C:\Users\joe.julia\v0.6\Plots\src\backends\inspectdr.jl:402
[2] prepare_output(::Plots.Plot{Plots.InspectDRBackend}) at C:\Users\joe.julia\v0.6\Plots\src\plot.jl:247
[3] show(::Base.AbstractIOBuffer{Array{UInt8,1}}, ::MIME{Symbol(“image/svg+xml”)}, ::Plots.Plot{Plots.InspectDRBackend}) at C:\Users\joe.julia\v0.6\Plots\src\output.jl:196
[4] show(::Base.AbstractIOBuffer{Array{UInt8,1}}, ::MIME{Symbol(“text/html”)}, ::Plots.Plot{Plots.InspectDRBackend}) at C:\Users\joe.julia\v0.6\Plots\src\output.jl:177
[5] show(::Base.AbstractIOBuffer{Array{UInt8,1}}, ::String, ::Plots.Plot{Plots.InspectDRBackend}) at .\multimedia.jl:39
[6] #sprint#228(::Void, ::Function, ::Int64, ::Function, ::String, ::Vararg{Any,N} where N) at .\strings\io.jl:66
[7] display_dict(::Plots.Plot{Plots.InspectDRBackend}) at C:\Users\joe.julia\v0.6\Plots\src\output.jl:266
[8] execute_request(::ZMQ.Socket, ::IJulia.Msg) at C:\Users\joe.julia\v0.6\IJulia\src\execute_request.jl:188
[9] eventloop(::ZMQ.Socket) at C:\Users\joe.julia\v0.6\IJulia\src\eventloop.jl:8
[10] (::IJulia.##11#14)() at .\task.jl:335


@Juan: When I try it I get this error message: […]

Unfortunately, this error is due to the fact that InspectDR is still evolving - and I don’t really have a perfect solution to match revisions of InspectDR with those of Plots.jl.


When adding functionnality to InspectDR, or simply fixing structural flaws, I sometimes need to modify the InspectDR API (and Plots.jl depends on the API being fixed).

Thus, when a change in API happens, I also have to update the inspectdr() glue code in Plots.jl.


Currently, InspectDR v0.2.2 is only supported by the master branch of Plots.jl… Still waiting on the next tagged release.


If ever you find Plots.jl crashes when you use inspectdr()… Simply look at the message you get when you call using InspectDR on a fresh Julia session:

Julia> using InspectDR

INFO: InspectDR not known to be compatible with current version of Plots.jl.

Latest known compatible versions:
    Plots 0.12.0 => InspectDR 0.2.0.
If difficulties occur, you can pin to an older version:
    julia>"InspectDR", v"0.2.0")
...don't forget to free to enable future updates:
See for more details on compatibility.

That basically tells you what to do - which is to “pin” the version of InspectDR to one that is compatible with the current version of plots:

Julia>"InspectDR", v"0.2.0")

Note that, once pinned to InspectDR v0.2.0, you will get a similar INFO message indicating that the last known compatible (Plots, InspectDR) couplet is even older. Please ignore this message. It is due to the fact that v0.2.0 of InspectDR was not actually aware that it was compatible with Plots v0.12.0 when it was published.


Today I’ve being benchmarking different Plot frameworks and sadly found than GR is slower than expected, even slower than R’s base plot function.

scatter(1:100000, (1:100000) .* rand(100000))

First I needed to “hack” a little bit the settings in order to be able to plot a large number of points.

and anyway was slow.

Now I’m trying other options

I’m not able to run GLVisualize, it says:

scatter(1:1000, (1:1000) .* rand(1000))

MethodError: no method matching to_vec(::Type{GeometryTypes.Vec{2,Float32}}, ::Int64)
Closest candidates are:
  to_vec(::Type{T<:(FixedSizeArrays.FixedArray{T,1,Tuple{CARDINALITY}} where T where CARDINALITY)}, ::Number) where T<:(FixedSizeArrays.FixedArray{T,1,Tuple{CARDINALITY}} where T where CARDINALITY) at C:\Users\rmhijjp\.julia\v0.6\Plots\src\backends/glvisualize.jl:216

and InspectDR doesn’t work either:

plot(1:1000, (1:1000) .* rand(1000))
type Multiplot has no field frame

 [1] _before_layout_calcs(::Plots.Plot{Plots.InspectDRBackend}) at C:\Users\rmhijjp\.julia\v0.6\Plots\src\backends\inspectdr.jl:402


@Juan: and InspectDR doesn’t work either: […]

What versions are you using?

It worked for me with Julia v0.6.0-rc2.0 + Windows 7, and the following:

julia> Pkg.installed("InspectDR")

julia> Pkg.installed("Plots")

Also: Have you recently done an update:

julia> Pkg.update()


Dealing with large numbers of points