using CairoMakie # no need to import Makie itself
A data visualization ecosystem for Julia
Marie-Hélène Burle
October 26, 2022
Many options:
matplotlib.pyplot
Main package:
Makie
: plots functionalities. Backend needed to render plots into images or vector graphicsBackends:
CairoMakie
: vector graphics or high-quality 2D plots. Creates, but does not display plots (you need an IDE that does or you can use ElectronDisplay.jl)
GLMakie
: based on OpenGL; 3D rendering and interactivity in GLFW window (no vector graphics)
WGLMakie
: web version of GLMakie
(plots rendered in a browser instead of a window)
Installing GLMakie can be challenging. This page may lead you towards solutions
CairoMakie and WGLMakie should install without issues
Load the package (here, we are using CairoMakie):
You can customize a Figure
:
Makie uses the Colors.jl package as a dependency
You can find a list of all named colours here
To use CSS specification (e.g. hex), you need to install Colors explicitly and use its color parsing capabilities:
Axis are customizable:
Finally, we can add a plot:
Of course, there are many plotting functions, e.g. scatterlines!
:
We can also use lines!
:
Let’s add points to get a smoother line:
Now, you don’t have to create the Figure
, Axis
, and plot one at a time
You can create them at the same time with, for instance lines
:
Or even more simply:
This is a lot simpler, but it is important to understand the concepts of the Figure
and Axis
objects as you will need it to customize them:
When you create the Figure
, Axis
, and plot at the same time, you create a FigureAxisPlot
object:
x = LinRange(-10, 10, 1000)
y = cos.(x)
obj = lines(x, y;
figure=(; backgroundcolor=:green),
axis=(; title="Cosinus function",
xlabel="x label",
ylabel="y label"));
typeof(obj)
Makie.FigureAxisPlot
Note the ;
in the figure
and axis
value. This is because these are one-element NamedTuples
The mutating functions (with !
) can be used to add plots to an existing figure, but first, you need to decompose the FigureAxisPlot
object:
Or we can add several plots on different Axis
in the same Figure
:
using CairoMakie
using StatsBase, LinearAlgebra
using Interpolations, OnlineStats
using Distributions
CairoMakie.activate!(type = "png")
function eq_hist(matrix; nbins = 256 * 256)
h_eq = fit(Histogram, vec(matrix), nbins = nbins)
h_eq = normalize(h_eq, mode = :density)
cdf = cumsum(h_eq.weights)
cdf = cdf / cdf[end]
edg = h_eq.edges[1]
interp_linear = LinearInterpolation(edg, [cdf..., cdf[end]])
out = reshape(interp_linear(vec(matrix)), size(matrix))
return out
end
function getcounts!(h, fn; n = 100)
for _ in 1:n
vals = eigvals(fn())
x0 = real.(vals)
y0 = imag.(vals)
fit!(h, zip(x0,y0))
end
end
m(;a=10rand()-5, b=10rand()-5) = [0 0 0 a; -1 -1 1 0; b 0 0 0; -1 -1 -1 -1]
h = HeatMap(range(-3.5,3.5,length=1200), range(-3.5,3.5, length=1200))
getcounts!(h, m; n=2_000_000)
with_theme(theme_black()) do
fig = Figure(figure_padding=0,resolution=(600,600))
ax = Axis(fig[1,1]; aspect = DataAspect())
heatmap!(ax,-3.5..3.5, -3.5..3.5, eq_hist(h.counts); colormap = :bone_1)
hidedecorations!(ax)
hidespines!(ax)
fig
end
using GLMakie, Random
GLMakie.activate!()
Random.seed!(13)
x = -6:0.5:6
y = -6:0.5:6
z = 6exp.( -(x.^2 .+ y' .^ 2)./4)
box = Rect3(Point3f(-0.5), Vec3f(1))
n = 100
g(x) = x^(1/10)
alphas = [g(x) for x in range(0,1,length=n)]
cmap_alpha = resample_cmap(:linear_worb_100_25_c53_n256, n, alpha = alphas)
with_theme(theme_dark()) do
fig, ax, = meshscatter(x, y, z;
marker=box,
markersize = 0.5,
color = vec(z),
colormap = cmap_alpha,
colorrange = (0,6),
axis = (;
type = Axis3,
aspect = :data,
azimuth = 7.3,
elevation = 0.189,
perspectiveness = 0.5),
figure = (;
resolution =(1200,800)))
meshscatter!(ax, x .+ 7, y, z./2;
markersize = 0.25,
color = vec(z./2),
colormap = cmap_alpha,
colorrange = (0, 6),
ambient = Vec3f(0.85, 0.85, 0.85),
backlight = 1.5f0)
xlims!(-5.5,10)
ylims!(-5.5,5.5)
hidedecorations!(ax; grid = false)
hidespines!(ax)
fig
end
While Makie is extremely powerful, its compilation time and its time to first plot are extremely long
For this reason, it might save you a lot of time to create a sysimage (a file containing information from a Julia session such as loaded packages, global variables, compiled code, etc.) with PackageCompiler.jl
The upcoming Julia 1.9 will do this automatically
CairoMakie will run without problem on the Alliance clusters
It is not designed for interactivity, so saving to file is what makes the most sense
Example:
Remember however that CairoMakie is 2D only (for now)
GLMakie relies on GLFW to create windows with OpenGL
GLFW doesn’t support creating contexts without an associated window
The dependency GLFW.jl will thus not install in the clusters—even with X11 forwarding—unless you use VDI nodes, VNC, or Virtual GL
You can setup a server with JSServe.jl as per the documentation
However, this method is intended for the creation of interactive widgets, e.g. for a website
While this is really cool, it isn’t optimized for performance
There might also be a way to create an SSH tunnel to your local browser, although there is no documentation on this
Best probably is to save to file