[ANN] Makie v.0.13

Hi everybody,

We’ve got another Makie update for you! This one includes one big change and a couple smaller ones. Although we’ve tagged breaking releases across the board, the effort on your side to update your code should be minimal. Thanks to @sdanisch @ffreyer and @piever for their work on this and AlgebraOfGraphics, that makes use of some of the new features in its upcoming version.

Here’s a quick rundown of the biggest changes:

AbstractPlotting renamed to Makie

Many people were rightly confused that we advised actively against installing Makie.jl in the last months. The reason was that years ago, there was only the GLMakie backend, the AbstractPlotting infrastructure package, and the Makie.jl package tying those two components up for convenience.

With CairoMakie and WGLMakie maturing, it doesn’t make sense anymore to bundle GLMakie and AbstractPlotting under the main Makie.jl name. Therefore, we have decided to rename AbstractPlotting.jl to Makie.jl. AbstractPlotting is effectively obsolete. There is no more bundle package, all backends should be installed directly. You still don’t have to install Makie.jl explicitly because it comes as a dependency of each backend anyway.

To update your code, it should be enough to search and replace AbstractPlotting with Makie.

Centered heatmaps

Heatmaps are now by default centered on the x and y values passed in. Before, the endpoints of x and y would specify the edges of the heatmap.

heatmap(randn(5, 5), axis = (aspect = 1,))

Irregular heatmaps

The centering change goes together with the new option to plot irregular heatmaps, where the bins are of different rectangular sizes.

heatmap(sqrt.(0:10:100), sqrt.(0:10:100), randn(11, 11),
    axis = (title = "Irregular heatmap", aspect = 1,))

Fixed arrows

Arrows used to work a bit unreliably across CairoMakie and GLMakie. Now, you have data independent arrow tip sizes by default which looks much more polished.

f = Figure(resolution = (700, 700))
Axis(f[1, 1], backgroundcolor = "black")

xs = LinRange(0, 2pi, 20)
ys = LinRange(0, 3pi, 20)
us = [sin(x) * cos(y) for x in xs, y in ys]
vs = [-cos(x) * sin(y) for x in xs, y in ys]
strength = vec(sqrt.(us .^ 2 .+ vs .^ 2))

as = arrows!(xs, ys, us, vs, lengthscale = 0.3,
    arrowcolor = strength, linecolor = strength)

f

Plot object theming

Before, you could not theme specific plot objects separately, this is now fixed. This allows you to set up much more elaborate themes. There are also a couple of changes in the default theme, and a couple of new global attributes, such as linecolor, markercolor, patchcolor, linewidth, markersize, strokewidth, strokecolor, patchstrokewidth, patchstrokecolor. Many recipes inherit these values so you can change them in one place rather than for every recipe.

with_theme(Lines = (linewidth = 5, linestyle = :dash)) do
    lines(cumsum(randn(50)))
end

Cycling

Plot attributes can now be cycled. This is by default enabled for color for a lot of recipes, but can be themed separately. Cycling currently works with Axis and Axis3 only.

You can theme the palettes that cycling chooses from and theme which attributes should be cycled for each plot type. This allows for example to create a black-and-white theme in which lines don’t cycle colors but linestyles.

f = Figure()
ax1 = Axis(f[1, 1])
ax2 = Axis(f[2, 1], palette = (
    color = [:red, :green, :blue, :cyan, :magenta, :orange],))
for ax in [ax1, ax2], i in 1:6
    data = cumsum(randn(50))
    lines!(ax, data)
    scatter!(ax, data, markersize = 7)
end
f

99 Likes

Thank you for all the work, @sdanisch @jules @piever and @ffreyer!

The cycling is really a user experience improvement and the Makie ecosystem looks more polished by the day. It starts to feel like v1.0 is not very far!

13 Likes

This is really nice though it the indices are centers what the 5 is doing at the 2nd example? Or the labels are not obligated to be centered?

Moreover, is anyone working towards data exploration on the output?
Namely being able to travel on the data and for each point see its values?

It is the most missing feature from MATLAB figure’s in Julia (Python as well).

3 Likes

Super exciting update! Installing it now to give it a try. :tada:

Congratulations to the team!

1 Like

Lots of great stuff in there, congratulations on this nice release! :slight_smile:

1 Like

Love this! Thank you for all your hard work!

1 Like

In the irregular case the borders are halfway between the positions you put in. I.e. [1, 3, 4] would produces cells (0, 2), (2, 3.5), (3.5, 4.5).

With respect to data exploration - we also merged DataInspector, which tries to give you helpful tooltips when you hover various plot elements.

Example Code

using GLMakie, FileIO

fig = Figure()
x = DataInspector(fig)
heatmap(fig[1, 1], rand(20, 20))
image(fig[1, 2], rand(20, 20))
hist(fig[2, 1], rand(100))
a = Axis(fig[2, 2])
scatter!(a, rand(10))
lines!(a, rand(10))
fig

fig = Figure()
s = LScene(fig[1, 1])
f = 2
ground = f .* rand(4, 4)
for _ in 1:6
f = 0.5f
new = f .* rand((2 .* size(ground) .- 1)…)
for i in axes(new, 1), j in axes(new, 2)
l = div(i+1, 2); r = div(i+2, 2)
b = div(j+1, 2); t = div(j+2, 2)
new[i, j] += 0.25 * (ground[l, b] + ground[l, t] + ground[r, b] + ground[r, t])
end
ground = new
end

surface!(s, 0…20, 0…20, ground, colormap=:terrain)

cat = load(Makie.assetpath(“cat.obj”))
texture = load(Makie.assetpath(“diffusemap.tga”))
m = mesh!(s, cat, color=texture)
rotate!(m, Vec3f0(1, 0, 0), pi/2)
translate!(m, Vec3f0(10, 10, ground[div(end, 2), div(end, 2)]))

meshscatter!(s, [20 .* rand(Point3f0) .+ Point3f0(0,0,2) for _ in 1:100], markersize = Vec3f0(0.1, 0.1, 0.3), color = :lightblue)
x = DataInspector(s)
fig

inspect2d
inspect3d

There have also been changes to events, which I suppose is more of a backend thing but it fixes some issues with events reaching the wrong things. For example, clicking on a menu item should no longer trigger things below that. If you are using events(scene) to do something you may get some warnings though.

39 Likes

Oh yeah the data inspector is something I had no part in and which I therefore promptly forgot! That is something a lot of people have asked for and which @ffreyer did a great job implementing

5 Likes

There are a lot of plots I don’t use and didn’t write specialized tooltips for. So I expect some of them to be unhelpful. If you find any please open an issue or ask about it on Slack so we can fix it

Another change from my side - 3d arrows are now fully mesh based and use a higher quality mesh (which you can downgrade by passing quality = 10, for example). This also affects 3d streamplots iirc.

6 Likes

This is fantastic! I’ve been following Makie for a while (and used it for some 3D scenes) but I haven’t yet been able to justify using it for everyday plotting - until now. The svg output with CairoMakie solved one problem, MakieLayout and its theming solved another (and for the record, MakieLayout might be best layout/theming experience I’ve had with a plotting packaging, I love being able to link axes and hide the ticks one one of them), but without color cycling I couldn’t make the jump. So excited to try this new release! The other improvements (especially theming plot types) are just icing on the cake for me. Congratulations to everyone who has brought Makie to this point!

6 Likes

I see how to customize “cycling” in the docs but I’m not 100% sure what cycling is: The name makes it sound like it maps between values and Iterators.cycle(colors). Is that right?

If so, I think that breaks the one-to-one correspondence between colors and values if there are more values than colors. This breakage is the same reason that dual-axis plots are hard to read – looking at an aesthetic on the plot, I should be able to uniquely identify the corresponding value in the data. I would generally rather use more colors by default than break that important correspondence.

Yes it is better to have as many colors as you have groups, the cycle name does not suggest to actually cycle colors as in repeat them. It rather “cycles through” a palette that you choose automatically. There can be more than one, for example cycling through colors and linestyles simultaneously if you require that.

with_theme(
    palette = (
        color = [:black, :gray],
        linestyle = [:solid, :dash, :dot],
    ),
    Lines = (
        cycle = [:color, :linestyle],
    )) do

    f = Figure()
    Axis(f[1, 1])

    for i in 1:6
        lines!(cumsum(randn(50)))
    end
    f
end

11 Likes

Sounds good. (That would be helpful for the docs.)

Btw is there a changelog for recent releases in the docs somewhere?

No, we’ve been struggling a bit with a good changelog. Ideally the merged PRs should give you a good idea of what was done, but of course that tends to not be as readable as a manual summary (which is just more work)

Just a thought…some projects use a policy where, in addition to developer-facing commit logs, all changes need a user-facing entry in the changelog/ directory, even if it’s just an annotation that the change is not public-facing, which can be automatically excluded from the rendered changelog at release time.

1 Like

Maybe make an issue? I’d be all for it, if it’s not too much overhead

2 Likes

Wow! This is a great progress!

Now, adding option to add a tool tip by Alt + Click to stay there would make it comparable to MATLAB!

Thank you for that.

I’ve just tried this. The colour cycling is fine (thanks!) but heatmaps are now blank. I have updated to Makie v0.13.1, GLMakie v0.3.0 (Windows 10).

What is the current status on TTFP?