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 .
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.
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
plot(rand(10,10))
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).
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).
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).
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.
Stacktrace:
[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.
Cause:
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.
Remark:
Currently, InspectDR v0.2.2 is only supported by the master branch of Plots.jl… Still waiting on the next tagged release.
Workaround:
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> Pkg.pin("InspectDR", v"0.2.0")
...don't forget to free to enable future updates:
julia> Pkg.free("InspectDR")
See NEWS.md 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> Pkg.pin("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
Stacktrace:
[1] _before_layout_calcs(::Plots.Plot{Plots.InspectDRBackend}) at C:\Users\rmhijjp\.julia\v0.6\Plots\src\backends\inspectdr.jl:402