7.1 Layers

We’ll cover the data layer first, which can be created with the data function:

data_layer = data(grades_2020())
AlgebraOfGraphics.Layer(identity, 4×2 DataFrameColumns
 Row │ name    grade_2020
     │ String  Float64
─────┼────────────────────
   1 │ Sally          1.0
   2 │ Bob            5.0
   3 │ Alice          8.5
   4 │ Hank           4.0, Any[], {})

As you can see, data takes any DataFrame and returns a Layer type. You can see that we do not have any mapping, visual, or statistical transformations information yet. That will need to be specified in different layer type with different functions.

NOTE: data layers can use any Tables.jl data format, including DataFrames and NamedTuples.

Let’s see how to encode data information in a mapping layer with the mapping function. This function has the following signature:

mapping(
    x, y, z;
    color,
    size,
    ...
)

The positional arguments x, y, and z correspond to the X-, Y- and Z-axis mappings and the keyword arguments color, size, and so on, correspond to the aesthetics mappings. The purpose of mapping is to encode in a Layer information about which columns of the underlying data AlgebraOfGraphics.jl will map onto the axis and other visualization aesthetics, e.g. color and size. Let’s use mapping to encode information regarding X- and Y-axis:

mapping_layer = mapping(:name, :grade_2020)
AlgebraOfGraphics.Layer(identity, nothing, Any[:name, :grade_2020], {})

We pass the columns as Symbols in a similar manner as we did for DataFrames.jl (Chapter -Section 4) and DataFramesMeta.jl (Chapter -Section 5). In the output, we see that we have successfully encoded both :name and :grade_2020 columns as the X- and Y-axis, respectively.

Finally, we can use a visual transformation layer to encode which type of plot we want to make. This is done with the visual function which takes a Makie.jl plotting type as a single positional argument. All of the mappings specified in the mapping layer will be passed to the plotting type.

visual_layer = visual(BarPlot)
AlgebraOfGraphics.Layer(AlgebraOfGraphics.Visual(Plot{Makie.barplot}, {}), nothing, Any[], {})

The visual_layer is a visual transformation layer that encodes information about which type of visual transformation you want to use in your visualization plus keyword arguments that might apply to the selected plotting type.

NOTE: We are using the plotting type (BarPlot) instead of the plotting function (barplot). This is due how AlgebraOfGraphics.jl works. You can see all of the available mappings for all of the plotting types by inspecting their functions either using Julia’s help REPL, e.g. ?barplot, or Makie.jl’s documentation on plotting functions.

7.1.1 Drawing Layers

Once we have all of the necessary layers we can fuse them together with * and apply the draw function to get a plot. The draw function will use all of the information from the layer it is being supplied and will send it as plotting instructions to the activated Makie.jl backend:

draw(data_layer * mapping_layer * visual_layer)
Figure 47: AlgebraOfGraphics bar plot.

AlgebraOfGraphics.jl will automatically pass the underlying columns of the mapping layer from the data layer’s DataFrame as the X- and Y-labels.

Note that you can just perform the * operations inside draw if you don’t want to create intermediate variables:

plt = data(grades_2020()) * mapping(:name, :grade_2020) * visual(BarPlot)
draw(plt)
Figure 48: AlgebraOfGraphics bar plot.

7.1.2 Mapping Layer Keyword Arguments

Let’s try to use other mappings such as the keyword arguments color and dodge in our bar plot, since they are supported by the BarPlot plotting type. First, let’s revisit our example all_grades() data defined in Chapter -Section 4 and add a :year column:

df = @transform all_grades() :year = ["2020", "2020", "2020", "2020", "2021", "2021", "2021"]
name grade year
Sally 1.0 2020
Bob 5.0 2020
Alice 8.5 2020
Hank 4.0 2020
Bob 9.5 2021
Sally 9.5 2021
Hank 6.0 2021

Now we can pass the :year column to be mapped as both a color and dodge aesthetic inside mapping:

plt = data(df) *
    mapping(
        :name,
        :grade;
        color=:year,
        dodge=:year) *
    visual(BarPlot)
draw(plt)
Figure 49: AlgebraOfGraphics bar plot with colors as year.

AlgebraOfGraphics.jl creates for us a legend with the underlying information from the color mapping column inside the data layer’s DataFrame.

7.1.3 Transformations Inside Mapping Layers

We can also perform transformations inside the mapping function. It supports the DataFrames.jl’s minilanguage source => transformation => target. Where source is the original column name and target is a String representing the new desired label. If we simply use source => target, the underlying transformation will be the identity function, i.e., no transformation is performed and the data is passed as it is. Here’s an example:

plt = data(df) *
    mapping(
        :name => "Name",
        :grade => "Grade";
        color=:year => "Year",
        dodge=:year) *
    visual(BarPlot)
draw(plt)
Figure 50: AlgebraOfGraphics bar plot with colors as year and custom labels.

Let’s make use of the transformation in source => transformation => target to transform our grades scale from 0-10 to 0-100 and also our names to uppercase:

plt = data(df) *
    mapping(
        :name => uppercase => "Name",
        :grade => (x -> x*10) => "Grade";
        color=:year => "Year",
        dodge=:year) *
    visual(BarPlot)
draw(plt)
Figure 51: AlgebraOfGraphics bar plot with colors as year, custom labels and transformations.

As you can see, we can pass both regular or anonymous functions.

NOTE: By default AlgebraOfGraphics.jl transformations inside mapping are vectorized (broadcasted) by default. Hence, we don’t need to use the dot operator ..



Support this project
CC BY-NC-SA 4.0 Jose Storopoli, Rik Huijzer, Lazaro Alonso