[ANN] MakieExtra.jl – more recipes and tools for Makie plots

MakieExtra.jl :crystal_ball:

Announcing a package I released recently, MakieExtra.jl.
It includes a bunch of new stuff for plotting that is either:

  • can only be implemented with some “hacks” at the current state of Makie,
  • or not fleshed out enough to be included into Makie itself,
  • or may be considered too opinionated.

Still, I believe the features in MakieExtra are generally useful and worth packaging to make them readily available for use in both scripts and other packages.

See the documentation for a list of what’s available in MakieExtra.
Below are a few highlights of visual functionality that I consider stable. There’s more – check out docs with examples!
MakieExtra also has some less stable experimental functionality. I’ll probably add separate posts about it, asking for feedback.

Additionally, this is a Request For Collaboration: if you have recipes/tweaks/utilities of reasonably-general use that are unlikely to get into Makie, feel free to contribute to MakieExtra!
It’s intended to have a lower barrier for entry than Makie itself.

Examples

Automatic scalebar and zoom lines


Lines with arrows at either end

Glowing lines and text

Markers with adjustable linewidth

Symlog scale variants

Figure from SkyImages.jl docs using several MakieExtra features

59 Likes

You should showcase the axis tick locator and formatter too, it’s a very common customization request!

1 Like

Thanks!
I also like them and use BaseMulTicks & EngTicks quite often. Example plot from the docs:


It’s unexpectedly difficult to handle all edgecases btw, especially for the locator. Most of rough edges are already smoothed out during my own usage, but some may still remain.

11 Likes

Here’s the first post about more experimental features (:

Very often, I find myself plotting the exact same arguments with two or more recipes – either different recipes like Lines + Band, or the same recipe with different option.
MakieExtra.jl provides simple multiplot() and multiplot!() functions to make this convenient. multiplot() passes its positional arguments to all requested recipes as-is, and can either pass the same or different kwargs/attributes to each recipe.

A few example from the docs:

I’ve been using multiplot() recently, and found it quite convenient. It’s considered experimental for now mostly because I’m not sure whether the current interface is clean and understandable enough. The general concept of multiplot is definitely there to stay though (:
Let me know if you have any thoughts on this!

2 Likes

Thanks, I definitely need the axis zoom functionality here.

cc @asinghvi17 and @lazarusA and “Daniel” (who?); in the Makie discord we were having a discussion about many disparate Makie-based projects popping up for themeing and convenience functions, like my GitHub - Datseris/MakieForProjects.jl: Themeing and convenience tools for accelerating working with Makie.jl . The discussion ended with the common hope being that all these disparate projects become one. We haven’t however concluded on what is the best way to do this.

2 Likes

As far as I am concenred, I am happy to put all functionality from MakieForProjects.jl to another project such as MakieExtras.jl. It appears similar in their type of convenience functionalities they provide, beyond the additional themeing I have, which I can add by itself to MakieThemeing.jl (provided that MakieThemeing.jl is improved in terms of modularity for its themeing; I find the possibility of themeing Axis color, background color, and color cycle all independently to be very nice for my work).

1 Like

As discussed on Zulip, it would be even more useful if some of these recipes were shipped with Makie.jl itself instead of extra packages. Otherwise it becomes difficult to ensure long-term availability and automatic loading with package extensions.

3 Likes

Re long-term availability: there’s no magic in including more stuff into Julia Base, Makie, or whatever, it doesn’t automatically make that stuff easier to maintain. Instead, it increases load on maintainers, and Makie is a large complex project already. Of course, if Makie devs want to upstream something from MakieExtra, they are always free to do so.

The extensions situation may improve at some point if Dependencies of an Extension · Issue #3641 · JuliaLang/Pkg.jl · GitHub and Allow package extensions to have dependencies · Issue #52663 · JuliaLang/julia · GitHub get more support.
For now, one has to make a weakdep on MakieExtra and ask users to load it if some of its features are needed for the package extension. Not too bad IMO, and shouldn’t happen too often: most of MakieExtra features are likely to be called by the enduser, not from packages.

3 Likes

Thanks for pointing this out, I haven’t seen your MakieForProjects!

I agree with you in that whenever possible those features should go into focused packages, like MakieThemeing. Or Colors for these functions: MakieForProjects.jl/src/colormanip.jl at main · Datseris/MakieForProjects.jl · GitHub.
If there remain some Makie-specific functions that are of a general use, they could indeed be put into MakieExtra.jl.

I use axesgrid literally in every plot I do that is work-related. (MakieForProjects · MakieForProjects.jl) . For the final figure of a paper I always have to use MakieForProjects · MakieForProjects.jl! .

In my view such functions are on the same level of functions like your axis zoomin. They aren’t opinionated, but are convenience tools.

Would be good if we can agree on where all such things should be. I think they should be in Makie directly. But another solution Im happy with. What I would prefer is that the final solution is in the Makie github org instead of an individual.

This is really neat! Love it.

I think it’s easiest to include features into Base Makie that are relatively simple and can be composed well with others. A lot of convenience functions people build are somewhere above that, in the composition zone, and the problem is that this space is much larger than the basic component space.

Basically Makie gives you so many possibilities that it’s difficult to decide on “canonical” ones. So that’s why a function like axesgrid is a bit more difficult for me to integrate, it’s no doubt useful but there’s a ton of other ways to assemble axes into grids, so I ask what makes this specific one worth being integrated. If we find however that 90% of users always try to build the same thing manually, then it’d be worth using it to reduce that complexity.

2 Likes

@jules what do you think of the scalebar recipe above? Would it be ok to port it to Makie.jl? Displaying the true scale of physical objects in 2D and 3D is really useful (e.g., 3D digital rock models, 2D maps).

1 Like

Another benefit of having things in a separate package is that it makes it easier to see how these features work / lets them evolve. It also makes it easier for the developer to work on the features instead of being stuck in a PR where it can take ages / demotivate the effort depending on how the PR goes (not that PRs taking time is bad thing, for a project like Makie it should definitely require more care / a higher barrier).

I think it is easier for those not doing the work/maintenace to suggest more work to do and go through that process, but I imagine for example it is easier for @aplavin to make this package and have the features they want in a registered package that is immediately available.

Maybe as the methods mature they could be incorporated into Makie directly but as @jules mentions in some cases it’s not obvious the best way forward anyway.

Anyway: Really nice package! The features are great.

3 Likes

In case someone wants to try upstreaming features from MakieExtra to Makie proper, these are the primary candidates IMO:

@Datseris, I understand that axesgrid turned out very useful for you, and it would be even more widely applicable if:

3 Likes

Yeah it is super easy to modify the function to obtain a grid layout instead. This way it is arbitrarily applicable to a part of an existing figure.

CU!

George

Highlights: new in MakieExtra

Docs with all the examples are available as a Pluto notebook.
Some neat updates over the past months:

  • arrowlines now support lines with any number of points, not just two. Basically, “like lines, but with arrowheads on one/both sides”:
  • zoom_lines should be more reliable for transformed/reversed scales and for different relative positions of axes:
  • added obsmap() to easily compute the full trajectory of an observable, basically one line of code to turn the left plot into the right one:
  • and one more, major and relatively self-contained feature – will post separately soon :slight_smile:

Minor new things that would be nice to just upstream if someone is up to putting some energy into the process:

15 Likes

Regarding changes, there’s already the ignore_equal_values=true option for Observables, not sure if you knew about that.

2 Likes

@aplavin the zoom lines are really neat! Looking forward to trying out this package.

I didn’t know indeed, thanks! This is a cleaner way to implement changes() under the hood, will switch in the next version.
Still, as the user-facing interface, changes(obs) is typically cleaner anyway. For me, a common usage of changes() looks like

all_vals = [...]
x = Observable(0.)
xi = changes(@lift findfirst(>=($x), all_vals))
... use x and xi ...

Record(...) do x_
    x[] = x_
end

which doesn’t have an explicit Observable() call for xi where one could put ignore_equal_values=true.