We’ll cover the data layer first, which can be created with the data
function:
data_layer = data(grades_2020())
Layer
transformation: identity
data: AlgebraOfGraphics.Columns{DataFrames.DataFrameColumns{DataFrame}}
positional:
named:
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 anyTables.jl
data format, includingDataFrames
andNamedTuples
.
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)
Layer
transformation: identity
data: Nothing
positional:
1: name
2: grade_2020
named:
We pass the columns as Symbol
s in a similar manner as we did for DataFrames.jl
(Chapter 4) and DataFramesMeta.jl
(Chapter 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)
Layer
transformation: AlgebraOfGraphics.Visual(Plot{Makie.barplot}, {})
data: Nothing
positional:
named:
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 howAlgebraOfGraphics.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
, orMakie.jl
’s documentation on plotting functions.
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)
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)
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"]
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)
AlgebraOfGraphics.jl
creates for us a legend with the underlying information from the color
mapping column inside the data layer’s DataFrame
.
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)
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)
As you can see, we can pass both regular or anonymous functions.
NOTE: By default
AlgebraOfGraphics.jl
transformations insidemapping
are vectorized (broadcasted) by default. Hence, we don’t need to use the dot operator.
.