[ANN] AlgebraOfGraphics v0.7

Hello everybody,

I’m excited to present version 0.7 of AlgebraOfGraphics.jl. This is work that I’ve been doing during the last two or three months, as we at PumasAI like to use the package but it had been in need of some refactoring for a while. This refactor is breaking in some aspects but it leaves the basic ideas and framework of the package untouched, so a transition is hopefully straightforward. It mostly adds some semantics on top that make it more flexible and powerful.

For more information about the reasoning behind all of this, please refer to PR 505. For a brief overview of the breaking changes and new features, check Release Notes · Algebra of Graphics. Note that because there are so many of them, not all of Makie’s plotting functions or all plot attributes have been enabled for the new system, yet, if you need a specific one please open an issue or file a PR.

Here are some example plots showcasing the new capabilities because we all like images to look at Hope you enjoy the new release!

Horizontal/vertical bar plots, rainclouds, violins, errorbars, etc.

``````df = (; x = 1:10, y = string.('A':'J'))
data(df) * mapping(:y, :x) * visual(BarPlot, direction = :x) |> draw
``````

``````group = repeat(["A", "B", "C", "D"], inner = 250)
measurements = randn(1000) .* repeat(1:4, inner = 250)
df = (; group, measurements)
data(df) * mapping(:group, :measurements, color = :group) *
visual(RainClouds, orientation = :horizontal) |> draw
``````

`mapping` with raw vectors, not using `data()`:

``````mapping(1:90, cumsum(randn(90)), color = repeat(["A", "B", "C"], inner = 30)) *
visual(Scatter) |> draw
``````

Quickly use data from outside a tabular dataset with `direct`

``````df = (; x = 1:20, group = repeat(["A", "B"], inner = 10))
y = sin.(range(0, 2pi, length = 20))
data(df) * mapping(:x, direct(y), color = :group) |> draw
``````

Markersize mapping with legend

``````t = 0:0.1:10
mapping(cos.(t) .* t, sin.(t) .* t, markersize = t) * visual(Scatter) |> draw
``````

Separate scales of same aesthetic type

``````spec1 = mapping(
1:300,
cumsum(randn(300)) .+ repeat([0, 10, 20], inner = 100),
color = repeat(["A", "B", "C"], inner = 100)
) * visual(Scatter)

spec2 = mapping([30, 80, 178, 260], color = ["X", "Y", "X", "Y"] => scale(:secondary)) *
visual(VLines, linestyle = :dash, linewidth = 2)

draw(spec1 + spec2, scales(secondary = (; palette = [:tomato, :gray60])))
``````

Category additions and modified placement

``````df = (; x = ["A", "C", "D", "missing"], y = [3, 2, 6, 3])
data(df) * mapping(:x, :y) * visual(BarPlot) |>
draw(
scales(
X = (;
categories = ["A", "B", "C", "D", "missing"],
palette = [1, 2, 3, 4, 6]
)
)
)
``````

Map `strokecolor` and other color attributes not named `color`

``````mapping(randn(50), randn(50), strokecolor = rand(["A", "B"], 50)) *
visual(Scatter, color = :gray90, strokewidth = 3, markersize = 20) |> draw
``````

Reorder legends

``````df = (;
x = 1:12,
y = 1:12,
z = 1:12,
group1 = repeat(["A", "B", "C"], inner = 4),
group2 = repeat(["X", "Y"], 6),
)

spec = data(df) *
mapping(:x, :y, markersize = :z, color = :group1, marker = :group2) *
visual(Scatter)

draw(spec; legend = (; order = [:MarkerSize, :Color, :Marker]))
``````

Merge legends

``````df = (;
x = 1:12,
y = 1:12,
z = 1:12,
group1 = repeat(["A", "B", "C"], inner = 4),
group2 = repeat(["X", "Y"], 6),
)

spec = data(df) *
mapping(:x, :y, markersize = :z, color = :group1, marker = :group2) *
visual(Scatter)

draw(spec; legend = (; order = [[:MarkerSize, :Color, :Marker] => "Merged"]))
``````

53 Likes

This is awesome. Thanks for the work

1 Like