The plotting is not the problem. GR or Gtk are loading very fast. Winston is also quite ok in its loading time.
Just an interesting comparison with PackageCompiler Makie speeds v/s official Julia binary Makie speeds:
While using PackageCompiler’s sysimage:
julia> @time using AbstractPlotting
0.000472 seconds (369 allocations: 20.094 KiB)
julia> @time scatter(rand(10), rand(10))
0.421506 seconds (151.97 k allocations: 30.967 MiB, 2.72% gc time)
Scene (960px, 540px):
[...]
[new session]
julia> @time using Makie
0.000343 seconds (819 allocations: 43.156 KiB)
julia> @time scatter(rand(10), rand(10))
0.487969 seconds (174.73 k allocations: 38.544 MiB, 25.24% gc time)
[...]
versus using the base Julia sysimage:
julia> @time using AbstractPlotting
4.563567 seconds (7.82 M allocations: 467.765 MiB, 5.14% gc time)
julia> @time scatter(rand(10), rand(10))
22.975833 seconds (62.87 M allocations: 3.146 GiB, 6.67% gc time)
Scene (960px, 540px):
[...]
[new session]
julia> @time using Makie
13.146121 seconds (27.27 M allocations: 1.463 GiB, 4.47% gc time)
julia> @time scatter(rand(10), rand(10))
25.245235 seconds (63.58 M allocations: 3.183 GiB, 6.43% gc time)
It seems from here that Makie takes significantly longer to load compared to AbstractPlotting.
My experience has been that most of the time is in the initial setup. Is it possible that a more detailed or comprehensive precompilation cache (maybe not to the extent of PackageCompiler, but something resembling a compiled library like what GR uses) could alleviate this?
Cf (from a freshly started Julia process, with relevant packages precompiled already)
julia> @time (using PGFPlotsX; Plot(Table(sort(randn(10)), randn(10))))
2.870682 seconds (4.67 M allocations: 239.522 MiB, 2.88% gc time)
which includes calling LaTeX that compiles everything.
I am thinking along the following lines:
- A pure Julia low-level backend that can create SVG, using a subset of its features. SVG renders fine in the browser, and external programs can be used to convert it to everything else. (PDF could also serve this role).
- A mid-level plotting library which just puts things on a canvas, transformed and clipped appropriately.
- A high-level interface, or multiple ones, that deals with fancy plotting, not unlike Gadfly. But users should be fine with 1-2 above, this should be optional.
Implementation strategy for 1 & 2: restrict and convert arguments to a few concrete types in the exposed interface. Internally, everything is done with, say, integers and Float64
. pgfplots
(the LaTeX package) manages with fixed point floats in LaTeX, so this should be fine.
The only thing preventing me from writing this is that I want to be able to include math in text (axis labels etc) and I think this would be the detail most difficult to get right. Also, currently I am spoiled by PGFPlotsX which works fine.
Making yet-another 2D plotting package for Julia seems like a mistake. Why not spend that effort adding support for SVG to Makie.jl? (Which already does have nice 2D support.)
No worries, I am not going to write one Mainly because of what I said above. Figuring out a way to specify nicely typeset math would make me reconsider though.
But, in general, Makie is so powerful that writing a meaningful backend to it would be a daunting task.
Also, again in general, in the current state of the Julia ecosystem I see no problems with exploring ideas in mini-packages. If they turn out to be useful, ideas can be merged later on, and in the meantime this minimizes development effort.
Yes of course it’s fine to write mini-packages, but proposing a new experimental 2D plots package is not really a reasonable solution to the “time-to-first-plot” issue. Also, for many people the first plot may be 3D.
Also, is SVG actually crucial, or would Makie’s upcoming WebGL support suffice?
Some kind of vector-based output for inclusing into papers is crucial.
Broadly, there are two schools on plotting: 3D, potentially interactive, utilizing a high-resolution computer screen, and 2D, potentially printed on paper, or included in a PDF, with a few colors, if any. My understanding that Makie is targeting the first one.
Correct me if I’m wrong, but my understanding is the publication quality 2d plots are also a target for Makie. There is some rudimentary support for this already in CairoMakie backend, which could be one target for those (me included) who would like to see great looking 2D figures coming out of julia : )
This is correct. Makie is powerful, but it’s not intended just as a powerhouse plotting library, it’s intended to give the user power when they need it but otherwise be for everyday quick 2d-plotting as well. Once the recipe system is really rocking will be as userfriendly as Plots (possibly more). The reason GR is so fast is that it’s a binary written in C. The reason Makie, Plots and Gadfly are slow is that they are written in Julia.
I think it’s a mistake to focus on plotting libraries as such, it makes much more sense to focus on improving Julia’s capabilities in this regard, combining tiered interpretation-compilation and caching of statically compiled methods, as suggested by Jeff and Stefan above.
For the record, I’ve already used Makie.jl to make plots for a paper (see Figure 9 in https://arxiv.org/pdf/1902.04863.pdf). Though usually I just use Matplotlib: Matplotlib is incredibly slow, but speed isn’t really important in the setting of “production-quality” plotting.
There is something I dont get. How can GR be fast, using a C library and Makie is slow. I dont get why the static version of Makie is not the solution. It seems GR can handle most the types I throw at it, so why would a static version Makie would not?
Thanks for mentioning this example, those plots look very nice.
I think it’s just a question of expanding the testing suite of Makie. PackageCompiler compiles static versions of all methods called by the test suite. The GR binary is statically typed so 100% compiled. But yes, statically compiling Makie (or Plots, that works as well) already goes very far towards resolving this.
Very nice, it looks like a mix of Makie (3 left, 5 left, 6 left, 8 and 9) and Plots+GR (3 right, 4, 5 right, 6 right and 7) figures?
Yes I had to mix and match a bit to get things to look right. I think I even needed to use PyPlot.jl directly for the spy plots.
Nobody said that?! It should work perfectly fine, minus the normal issues with static compilation in Julia, which hopefully get fully resolved.
Let me summarize what was brought up here, plus a few corrections:
-
@Tamas_Papp, a pure Julia plotting package will be slow depending on the number of features. Something simple as GR.jl is low-level and fast, but the more you add higher level API features to it, the slower compilation will get. PGFPlotsX.jl is not actually a pure Julia plotting package, but still just a thin wrapper around another plotting API, that actually does the heavy lifting. I haven’t looked thoroughly at PGFPlotsX, so there is a good chance that it does more than I think, and is just written in a way easier digestible by the compiler. If that is the case, your dream of a pure lightweight Julia plotting package is one PR to AbstractPlotting away, to improve compilation times - it is exactly what you describe. Anyone could try to e.g. remove type parameters or add
@no_specialize
to speed up compilation and see how it goes. CairoMakie is exactly the “just put things on an SVG canvas” library, and should compile lightning fast, and will happily draw your AbstractPlotting plots (sorry for the confusing package names, but I decided that Makie should work out of the box, so it’s taking on all heavy dependencies, while AbstractPlotting is the actual implementation of a backend independent plotting library). -
Makie is targeting WebGL, publication ready SVGs & PDFs for 2D/3D and fast interactive 3D/2D plotting. The status of those depends purely on the backends - The fast 3D/2D OpenGL backend is the most developed, followed by the Cairo backend for SVGs & PDFs…The WebGL backend doesn’t exist yet, but just got a great boost forward, since I figured out a way to wrap THREE.js in a much simpler fashion.
-
Creating a backend for Makie is not complicated. A simple prototype can be as little as 100 lines of code written in less than one day. This is because every plot is composed of just a few primitive graphic types - as of now these are just
Mesh
,Lines
,LineSegments
,Scatter
andImage
. If you can draw those, your static backend is done. If you want to add interactivity, you also need to redraw those and hook up window signals, but that’s all there is to a backend Of course covering 100% of Makie’s features will take longer, depending on the state of the drawing framework you use. That’s also why the WebGL backend is taking so long: there simply hasn’t been something like WebGL.jl, that I could just use to draw my primitives.
Just to clarify, I did not claim that it was. I just included it as an example that (mostly) does what I want at the moment.
Thanks for the explanation. I will follow AbstactPlotting with interest, although the dependency on FileIO makes me wonder if it can be made fast, as AFAIK that package had a lot of issues with compilation times.
I think they got resolved:
julia> @time using FileIO
0.119187 seconds (145.57 k allocations: 9.097 MiB)
Have you looked into Compose for this? As a side note I was actually curious whether there could be a Compose backend to Makie for svg (to have a pure julia solution).
Specifically, the Compose native Julia SVG writer is in this file: https://github.com/GiovineItalia/Compose.jl/blob/master/src/svg.jl. If you wanted to avoid whatever overhead might be added by the Compose package, you could rip that out directly and lightly modify it to work independently. That said, if the only reason for doing so is to reduce time-to-first-plot, I don’t think you’ll be too super successful. First SVG output is still slow in Gadfly.