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.
Let’s see how to encode data information in a mapping layer with the mapping
function. This function has the following signature:
mapping(
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)
We pass the columns as s in a similar manner as we did for DataFrames.jl
(Chapter 4) and DataFramesMeta.jl
(Chapter ). 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(Combined{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.
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 49: 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:
Figure 50: AlgebraOfGraphics bar plot.
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 4 and add a :year
column:
df = @transform all_grades() :year = ["2020", "2020", "2020", "2020", "2021", "2021", "2021"]
Now we can pass the :year
column to be mapped as both a color
and dodge
aesthetic inside :
plt = data(df) *
mapping(
:name,
color=:year,
dodge=:year) *
visual(BarPlot)
draw(plt)
Figure 51: AlgebraOfGraphics bar plot with colors as year.
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 52: 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:
Figure 53: AlgebraOfGraphics bar plot with colors as year, custom labels and transformations.
As you can see, we can pass both regular or anonymous functions.