The differences between Plots.jl and Makie.jl can sometimes be a bit confusing, especially because both use a function called plot
. But Plots’s plot
creates abstract objects which are descriptions of figures with possibly multiple subplots arranged in layouts. When you plot!
into those, you just add to the description, which is at the end converted into a complete visualization in whatever backend you have activated.
In Makie, there’s Figure
(a Scene
with a GridLayout
), which can contain stuff like Axis
, Colorbar
, Legend
, etc, and all of these objects are built up out of Scenes
which contain “plot primitives” such as Lines
, Scatter
, Heatmap
, etc. All plotting functions at their core create such “plot primitives”, but, as a convenience, the containers for these are created as well in the default case. Usually, that’s a Figure
with an Axis
inside. So heatmap(...)
makes a Heatmap
plot object, which is stored inside an Axis
, which is placed inside a Figure
. To pass keyword arguments to the Axis
, you can do heatmap(...; axis = (; title = ...
and for the Figure
you do heatmap(...; figure = (; resolution = ...
.
Remember that in Plots.jl, you don’t control all these different objects, you just make an abstract “plot description”, therefore all keywords are top-level keywords, and Plots.jl sorts out which relate to what would be the Figure
in Makie, or the Axis
, or the Plot
. But in Makie, it’s completely separated, that’s why all Figure
keywords have to be sent in via the special figure
keyword. For example, in principle some plot might have a title
attribute, and this way you could set that plus the axis title via some_plot(...; title = "Plot title", axis = (; title = "Axis title"...
.
If, in Makie, you go the mutation route, the plotting function loses its ability to pass Figure
and Axis
information on, because those have already been created beforehand:
f = Figure(resolution = ...)
ax = Axis(f[1, 1], title = ...)
heatmap!(ax, ...; # no figure or axis keyword allowed here, those already exist