Porting over a matplotlib cyberpunk theme for Julia with Makie
Original article: https://matplotlib.org/matplotblog/posts/matplotlib-cyberpunk-style/
using CairoMakie # CairoMakie.activate!(type = "svg")
makie is as simple as: https://makie.juliaplots.org/v0.17.3/documentation/theming/
fontsize_theme = Theme(fontsize=10, resolution=(300,300)) set_theme!(fontsize_theme) f = Figure() lines!(f, cumsum(randn(50)))
After taking a liking to matplotlib, I started to revisit Julia's
Makie package because it felt similar in how you constructed a plot. But I wanted to make the plots look better just out of the box, and the way to do that was with themes.
Let's see an example:
set_theme!() function example_plot() f = Figure() ax = Axis(f[1,1]) x = [1,3,9,5,2,1,1] y = [4,5,5,7,9,8,6] scatterlines!(ax, x) scatterlines!(ax, y) f end example_plot()
On my MBP, the default theme with makie isn't aesthetically pleasing - the font size is way too big and the figure size is massive. Let's fix those with a basic theme:
first_theme = Theme(fontsize=12, resolution=(640,320)) set_theme!(first_theme) example_plot()
cyberpunk_theme = Theme( # teal/cyan, pink, yellow, matrix green, red, violet palette = (color =["#08F7FE", "#FE53BB", "#F5D300", "#00ff41", :red, "#9467bd"],), backgroundcolor = "#212946", textcolor=:gray90, resolution=(640,320), fontsize=12, font = "Arial", colormap = :cool, cycle = Cycle([:color]), Axis = ( backgroundcolor = "#212946", topspinevisible = false, rightspinevisible = false, xgridcolor = "#2A3459", ygridcolor = "#2A3459", bottomspinecolor = "#2A3459", leftspinecolor = "#2A3459", ytickcolor = "#2A3459", xtickcolor = "#2A3459", titlesize=16, yautolimitmargin=(0.05, 0.1), # Leaves room for label text ), # Note in order to apply specific settings to plot types we need to use the Struct/type # so to theme barplots() you need to use the BarPlot type Lines = ( linewidth=2,), BarPlot = ( cycle=Cycle([:color]), # Interesting that I have to put it here label_size=12, ) ) with_theme(example_plot, cyberpunk_theme, )
Note in order to apply specific settings to plot types we need to use the Struct/type so to theme barplots() you need to use the BarPlot type. This wasn't covered in the documentation and it was weird that I had to repeat the
cycle call for
BarPlot but not
Lines, so maybe to be safe you may have to repeat yourself here and there.
Next, let's temporarily add the glow to this example plot. This is done by repeatedly overdrawing the lines and markers (with
scatterlines) but with a slight dodge effect with a very low alpha
set_theme!(cyberpunk_theme) n_lines = 10 diff_linewidth = 1.05 alpha_value = 0.03 f = Figure() ax = Axis(f[1,1]) colors = ["#08F7FE", "#FE53BB", "#F5D300", "#00ff41", :red, "#9467bd"] x = [1,3,9,5,2,1,1] y = [4,5,5,7,9,8,6] scatterlines!(ax, x) scatterlines!(ax, y) for n in 1:n_lines scatterlines!(ax, x; linewidth=2+(diff_linewidth*n), color = (colors, alpha_value)) scatterlines!(ax, y; linewidth=2+(diff_linewidth*n), color = (colors, alpha_value)) end f
And here we have a decent start towards a better makie theme!
We also added a colormap in there, so we can handle continuous values as well:
t = range(0, stop=1, length=500) # time steps θ = (6π) .* t # angles x = t .* cos.(θ) # x coords of spiral y = t .* sin.(θ) # y coords of spiral p1 = lines( x, y, color = t, # colormap = :cool, linewidth=8)
And here's an example with a
BarPlot where we cycle through the palette:
y = round.(randn(5) .+ 2.5, digits=1) b = Figure() ax = Axis(b[1,1], title="Title") for i in 1:5 barplot!(ax, [i], [y[i]], bar_labels=[y[i]]) end b
Though it may be better to just use the
color parameter and pull from the continuous color map.
barplot(1:3, y[1:3], bar_labels=y[1:3], color=1:3, axis = (title="Barplot with continuous colormap",))
This looks better than the discrete colors. Note in the above example, I used
boxplot instead of the mutating function
boxplot! and note the trailing comma in the
axis parameter call to make sure this creates a
From the docs:
If you set only one attribute, be careful to do axis = (key = value,) (note the trailing comma), otherwise you're not creating a
NamedTuplebut a local variable key.