# Grammar of Graphics with `AlgebraOfGraphics.jl`

Authors

Jose Storopoli

Juan Oneto

This tutorial will be a deep dive into `AoG.jl` grammar and algebraic operations. All revolves around the `AlgebraOfGraphics.Layer` and `AlgebraOfGraphics.Layers` types. They represent a single layer or a list of layers, respectively. These are the types you can add and multiply in `AoG.jl` with `+` and `*`.

Each layer in `AoG.jl` is composed of data, mappings and transformations.

Tip

Even if you do not specify a transformation with `visual()`, `AoG.j` will default to `visual(Scatter)`. So every layer has always these three components.

You can replace data, merge mappings or concatenate transformations. All these operations are defined in a multiplication operation with `*`.

The addition operation `+` is used to superimpose separated layers.

In summary:

• The symbol `*` is used to merge two layers, combining information.
• The symbol `+` adds layers as separate layers (on top of each other).
• Both `+` and `*` obey the distributive law: `a * (b + c) == (a * b) + (a * c)`.

To begin, like before, let’s load `AoG.jl`, data wrangling libraries and the `DataFrame` we’ve used previously:

``````using PharmaDatasets
using DataFramesMeta

df = dataset("demographics_1")
first(df, 5)``````
5×6 DataFrame
Row ID AGE WEIGHT SCR ISMALE eGFR
Int64 Float64 Float64 Float64 Int64 Float64
1 1 34.823 38.212 1.1129 0 42.635
2 2 32.765 74.838 0.8846 1 126.0
3 3 35.974 37.303 1.1004 1 48.981
4 4 38.206 32.969 1.1972 1 38.934
5 5 33.559 47.139 1.5924 0 37.198
``````using CairoMakie
using AlgebraOfGraphics``````

Now let’s create three layers:

1. a `data()` layer with a data structure, e.g., a DataFrame.
2. a `mapping()` layer with the columns `:AGE` and `:eGFR` called `cols`.
3. a transformation `visual()` layer with the `Scatter` plotting type as `geom`.
``df_layer = data(df)``
``cols = mapping(:AGE, :eGFR)``
``geom = visual(Scatter)``

## 1 ✖️ Multiplication of Layers with the `*` Operator

To show how we can merge layers with the `*` operator, see the following example. Here we are combining the information from the `data()` layer, the `mapping()` layer (with the `cols`) and the transformation `visual()` layer (with the `geom`) into a single layer.

You can see that the returned object of the operations with the `*` is a `AlgebraOfGraphics.Layer`:

``new_layer = df_layer * cols * geom;``
``typeof(new_layer)``
``Layer``

And here is the `new_layer` visualization:

``new_layer |> draw``

## 2 ➕ Addition of Layers with the `+` Operator

The addition operator `+` does not combine `AoG.jl`’s `Layer`s objects into a single `Layer` object like the `*`. Instead it returns a `AlgebraOfGraphics.Layers` object (note the s in `Layers`) which is a list of `Layer`s:

``separate_layers = visual(Scatter) + linear();``
``typeof(separate_layers)``
``Layers``

And this is the visualization of the superimposition of `Layer`s with the `+` operator:

``data(df) * cols * separate_layers |> draw``

If we want to combine the `linear()` layer with another, we can do so with the `*` operator:

``````data(df) * cols * (visual(Scatter) + linear() * visual(; linewidth = 3, color = :red)) |>
draw``````

## 3 🧮 Mixing `+` and `*`

Layers can be combined with pairwise products with:

``combined_layer1 * combined_layer2``

This will create all pairwise combinations of the `combined_layer1` with `combined_layer2`. See this example with a `data_layer`, a `scatter_layer` and a `linear_layer`:

``data_layer = data(df) * mapping(:AGE, :eGFR);``
``scatter_layer = visual(Scatter);``
``linear_layer = linear() * visual(; linewidth = 3);``
``data_layer * (scatter_layer + linear_layer) |> draw``

## 4 🪧 Conclusion

Just remember that:

• `*` combines layer into an `AlgebraOfGraphics.Layer`.
• `+` superimposes layers into a list of layers: a `AlgebraOfGraphics.Layers`.
• Be aware that you might need to use parentheses `()` to specify the order and scope of `*` and `+` operations.