The VS Code plot navigator and Makie

I want to clarify something that confused me when using CairoMakie and GLMakie in Visual Studio Code. I couldn’t find an explanation in the Makie documentation, so I’ll make a topic here to help anyone else who runs into this.

When using Makie.jl in VS Code, the choice of backend affects whether the plot appears in VS Code’s plot navigator or in a separate window. I’ll cover each one separately.

Using GLMakie

When making a figure in GLMakie, the figure is displayed in a separate window and not in the plot navigator. (This is fine. I’m not complaining. Actually, I like this feature.) As you add code to the figure, the window will update itself, a very nice feature. Here is an example:

f = Figure();
sc = display(f);

##

Evaluating the code until this point will generate a blank window. Continuing,

ax = Axis(f[1, 1], title = "Figure 1", xlabel = "x", ylabel = "y")
x = range(-10, stop=10, length = 20)
y = x.^2
scatter!(ax, x, y, label = "Data")
##

Now a parabola will be added to the figure. A second plot can be added:

ax2 = Axis(f[1, 2], tite = "Figure 2", xlabel = "x", ylabel = "y")
for i in 1:4
    lines!(ax2, cumsum(randn(100)), label = "%i")
end

##

You can change the theme, but you have to re-plot everything afterward:

set_theme!(theme_dark())

When I was watching the JuliaCon2021 Makie talk, I was wondering why there were ## in the code. These tell the editor to evaluate until that point (typing Shift + Enter). Convenient.

Using CairoMakie

With CairoMakie, plots appear in the plot navigator and not in a separate window. Also, you cannot successively add to the figure. Each time you evaluate, a new figure is generated. So if you just evaluate

f = Figure();
sc = display(f);

a blank figure is generated. If you then evaluate

ax = Axis(f[1, 1], title = "Figure 1", xlabel = "x", ylabel = "y")
x = range(-10, stop=10, length = 20)
y = x.^2
scatter!(ax, x, y, label = "Data")
current_figure()

a new figure with the parabola is generated. Note that you have to use either f or current_figure() to show the figure, which should be placed at the end of your code. With CairoMakie, you generate the entire figure at once whereas you can generate the figure piecemeal with GLMakie.

Concluding thoughts

Personally, sometimes I like to see the figure generated as I go in a separate window when I’m doing some kind of analysis. In these cases, I need to check if my analysis is working correctly and I don’t want one hundred useless plots in the plot navigator (e.g. I’m plotting best fit curves and want to plot the data, the guess, and the best fit). Other times, I like the plot navigator because I can browse several versions of a figure. Of course, CairoMakie generates publication-quality plots and should be used for final production and GLMakie emphasizes performance.

I think I got all of that right, but if I missed something or there are more details to add, please add to the discussion. I only just started learning Julia a month ago and welcome feedback on best practices and whatnot.

Versions:
Julia 1.6.2
CairoMakie 0.6.5
GLMakie 0.4.6
Julia VS Code plugin 1.4.0
VS Code 1.60.0

Here's the full code for my example
using CairoMakie
using GLMakie

##

GLMakie.activate!()
# CairoMakie.activate!()

f = Figure(resolution = (800, 600));
sc = display(f);
##

ax = Axis(f[1, 1], title = "Figure 1", xlabel = "x", ylabel = "y")
x = range(-10, stop=10, length = 20)
y = x.^2
scatter!(ax, x, y, label = "Data")

##

ax2 = Axis(f[1, 2], tite = "Figure 2", xlabel = "x", ylabel = "y")
for i in 1:4
    lines!(ax2, cumsum(randn(100)), label = "%i")
end

# current_figure()

##

set_theme!(theme_light())
2 Likes

Note that if you run Makie.inline!(true), GLMakie plots also appear in the navigator. The difference is whether GLMakie routes into its own display system or the normal stack, which has the plot pane if you’re in VSCode and haven’t disabled it.

3 Likes

Thank you for that clarification.

Is there any way to make CairoMakie ‘replace’ a previous plot, if I’m updating a figure? Due to my workflow, a lot of half-finished plots tend to accumulate in the plot navigator, sometimes a couple of hundred, most of them no longer useful.

Even just a way to programmatically delete certain plots, instead of having to push a button would be useful.

That would have to be a VSCode feature, because CairoMakie just hands off its plot data to VSCode. Maybe that would be a good feature request, then one could activate like a “current plot” object that would replace previous ones while active

1 Like

That’s tricky, but I suspect the main issue here is that using a ; to suppress displaying results didn’t work in VSCode for the longest time (it’s fixed now though).

But there is a button that lets me delete plots in a targeted manner. Do you think there is some way to ‘push’ it programmatically?

Not currently, no. We could add a function to VSCodeServer or a special MIME type that would delete the last or all plots, but I’m not convinced that’d be a good idea.The right solution would probably be to let the plotting framework supply a figure id, so that the frontend can make sure to only display a figure once and replace the content on the next display call.

2 Likes