using CairoMakie # no need to import Makie itself
A data visualization ecosystem for Julia
Marie-Helene Burle
Wednesday, October 26
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
Then, you can create an Axis
Axis with 1 plots:
┗━ Mesh{Tuple{GeometryBasics.Mesh{3, Float32, GeometryBasics.TriangleP{3, Float32, GeometryBasics.PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}}, GeometryBasics.FaceView{GeometryBasics.TriangleP{3, Float32, GeometryBasics.PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}}, GeometryBasics.PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}, GeometryBasics.NgonFace{3, GeometryBasics.OffsetInteger{-1, UInt32}}, StructArrays.StructVector{GeometryBasics.PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}, NamedTuple{(:position, :normals), Tuple{Vector{Point{3, Float32}}, Vector{Vec{3, Float32}}}}, Int64}, Vector{GeometryBasics.NgonFace{3, GeometryBasics.OffsetInteger{-1, UInt32}}}}}}}
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
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
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 at creating interactive widget, 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
2D plots: use CairoMakie and save to file
3D plots: use WGLMakie and save to file