Visualize with Makie

In Julia, there are several packages for plotting. One of the prefered options is Makie.jl which is mainly written in Julia. There is also high-level packages written over Makie.jl to make coding easier: AlgebraOfGraphics.jl and TidierPlots.jl.

Packages and data

using DataFrames
using CairoMakie
using AlgebraOfGraphics
import Random

Random.seed!(11)

df = DataFrame(id = 1:100, x = randn(100), y = randn(100))
first(df, 5)
5×3 DataFrame
Rowidxy
Int64Float64Float64
11-0.3675391.67104
22-0.686468-0.253313
33-0.3600261.90599
44-0.6610771.0981
55-1.14227-0.490607

Makie.jl

Let's start with a lines graph:

fig = lines(df.x, df.y)

You can add a geometry over this current graph:

scatter!(df.x, df.y, color = :red)
fig

To customize the graph we need to understand we have the following the componentes are:

  • Figure: Is the main container with custom attributes like backgroundcolor.
  • Axis: Is the object where a geometry can be added and it is contained in a Figure.
fig = Figure(backgroundcolor = :tomato)
Axis(fig[1,1], title = "First figure")
scatter!(df.x, df.y, color = :red)
Axis(fig[1,2], title = "Second figure")
lines!(df.x, df.y, color = :blue)
Axis(fig[2,1:2], title = "Third figure")
scatter!(df.x, df.y, color = :red)
lines!(df.x, df.y, color = :blue)
fig

Common arguments for the Axis elements are title, xlabel, ylabel.

Now let's create a figure with legends:

fig = scatter(df.x, df.y, color = :red, label = "Normal(0,1)")
scatter!(rand(100), rand(100), color = :blue, label = "Uniform(0,1)")
axislegend()
fig

A figure with colorbar:

X = rand(100, 80)
fig, ax, hm = heatmap(X, colormap = Reverse(:RdBu))
Colorbar(fig[1,2], hm)
fig

You can pass the Figure and Axis attributes to the plotting function:

hist(df.x, color = (:orange, 0.7), strokewidth = 1,
    axis = (title = "Histogram", xlabel = "x", ylabel = "π(x)"),
    figure = (backgroundcolor = (:green, 0.6),)
)

Check Makie.jl to find all available plots.

Algebra of Graphics

In practice, Makie.jl is used for developers and custom plots for publication. We can use AlgebraOfGraphics.jl for a high level syntax.

df.group = rand(string.(1:4), 100)
first(df, 5)
5×4 DataFrame
Rowidxygroup
Int64Float64Float64String
11-0.3675391.671044
22-0.686468-0.2533133
33-0.3600261.905991
44-0.6610771.09814
55-1.14227-0.4906074

Let's see a basic graph using AlgebraOfGraphics.jl.

g = data(df) * mapping(:x, :y)
draw(g)

You can use DataFrames.jl syntax to transform variables:

g = data(df) * mapping(:x => (z -> 10z) => "First variable", :y => "Second variable")
draw(g)

We can use another geometry with visual:

g = data(df) * mapping(:x, :y) * visual(Lines, color = :red, linewidth = 3)
draw(g)

Notice that the order does not matter:

g = mapping(:x, :y) * data(df) * visual(Lines, color = :red, linewidth = 3)
draw(g)

We can use the + operator to combine graphs:

g = data(df) * mapping(:x, :y, color = :group) * visual(Lines) +
    data(df) * mapping(:x, :y) * visual(Scatter)
draw(g)

Why is it called AlgebraOfGraphics.jl?

g = data(df) * mapping(:x, :y, color = :group) *
    (visual(Lines) + visual(Scatter))
draw(g)

You can factorize any part:

addnoise(x) = x + rand()
g = data(df) *
    (mapping(:x, :y, color = :group) + mapping(:x, :y => addnoise))
draw(g)

Let's separating the plots by group:

g = data(df) * mapping(:x, :y, layout = :group, color = :group) *
    (visual(Scatter) + visual(Lines))
fig = draw(g)
g = data(df) * mapping(:x, :y, row = :group, color = :group) *
    (visual(Scatter) + visual(Lines))
fig = draw(g, axis = (width = 130, height = 130))
g = data(df) * mapping(:x, :y, col = :group, color = :group) *
    (visual(Scatter) + visual(Lines))
fig = draw(g, axis = (width = 130, height = 130))