diff --git a/previews/PR593/.documenter-siteinfo.json b/previews/PR593/.documenter-siteinfo.json index f37d4b187..1d4379e2d 100644 --- a/previews/PR593/.documenter-siteinfo.json +++ b/previews/PR593/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.3","generation_timestamp":"2025-01-28T09:43:46","documenter_version":"1.8.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.3","generation_timestamp":"2025-01-29T16:36:09","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/previews/PR593/API/functions/index.html b/previews/PR593/API/functions/index.html index f6c0600d3..0a00d9a80 100644 --- a/previews/PR593/API/functions/index.html +++ b/previews/PR593/API/functions/index.html @@ -15,7 +15,7 @@ - `footnotefont` - `footnotecolor` - `footnotealign` -- `footnotelineheight`source
draw(p::PaginatedLayers; kws...)

Draw each element of PaginatedLayers p and return a Vector{FigureGrid}. Keywords kws are passed to the underlying draw calls.

source
draw(p::PaginatedLayers, i::Int; kws...)

Draw the ith element of PaginatedLayers p and return a FigureGrid. Keywords kws are passed to the underlying draw call.

You can retrieve the number of elements using length(p).

source
AlgebraOfGraphics.draw!Function
draw!(fig, d::AbstractDrawable, scales::Scales = scales(); [axis, facet])

Draw a AlgebraOfGraphics.AbstractDrawable object d on fig. In practice, d will often be a AlgebraOfGraphics.Layer or AlgebraOfGraphics.Layers. fig can be a figure, a position in a layout, or an axis if d has no facet specification. The output can be customized by passing named tuples or dictionaries with settings via the axis or facet keywords.

source
AlgebraOfGraphics.colorbar!Function
colorbar!(figpos, grid; kwargs...)

Compute colorbar for grid (which should be the output of draw!) and draw it in position figpos. Attributes allowed in kwargs are the same as MakieLayout.Colorbar.

source
AlgebraOfGraphics.legend!Function
legend!(figpos, grid; order = nothing, kwargs...)

Compute legend for grid (which should be the output of draw!) and draw it in position figpos. All kwargs are forwarded to Makie's Legend constructor.

The order of scales represented in the legend can be changed with the order keyword. By default, legend sections are ordered the same as they appear in the plot specification. Assuming three scales Color, MarkerSize and custom exist in a spec, you can pass a vector to reorder them like [:MarkerSize, :custom, :Color], or merge multiple entries together with a nested vector like [[:MarkerSize, :custom], :Color], or give merged sections a title with the pair syntax [[:MarkerSize, :custom] => "Merged group", :Color].

source
AlgebraOfGraphics.paginateFunction
paginate(l; layout=nothing, row=nothing, col=nothing)

Paginate l, the Layer or Layers object created by an AlgebraOfGraphics spec, to create a PaginatedLayers object. This contains a vector of layers where each layer operates on a subset of the input data.

The PaginatedLayers object can be passed to draw which will return a Vector{FigureGrid} rather than a single figure.

The keywords that limit the number of subplots on each page are the same that are used to specify facets in mapping:

  • layout: Maximum number of subplots in a wrapped linear layout.
  • row: Maximum number of rows in a 2D layout.
  • col: Maximum number of columns in a 2D layout.

Example

d = data((
+- `footnotelineheight`
source
draw(p::Pagination; kws...)

Draw each element of Pagination p and return a Vector{FigureGrid}. Keywords kws are passed to the underlying draw calls.

source
draw(p::Pagination, i::Int; kws...)

Draw the ith element of Pagination p and return a FigureGrid. Keywords kws are passed to the underlying draw call.

You can retrieve the number of elements using length(p).

source
AlgebraOfGraphics.draw!Function
draw!(fig, d::AbstractDrawable, scales::Scales = scales(); [axis, facet])

Draw a AlgebraOfGraphics.AbstractDrawable object d on fig. In practice, d will often be a AlgebraOfGraphics.Layer or AlgebraOfGraphics.Layers. fig can be a figure, a position in a layout, or an axis if d has no facet specification. The output can be customized by passing named tuples or dictionaries with settings via the axis or facet keywords.

source
AlgebraOfGraphics.colorbar!Function
colorbar!(figpos, grid; kwargs...)

Compute colorbar for grid (which should be the output of draw!) and draw it in position figpos. Attributes allowed in kwargs are the same as MakieLayout.Colorbar.

source
AlgebraOfGraphics.legend!Function
legend!(figpos, grid; order = nothing, kwargs...)

Compute legend for grid (which should be the output of draw!) and draw it in position figpos. All kwargs are forwarded to Makie's Legend constructor.

The order of scales represented in the legend can be changed with the order keyword. By default, legend sections are ordered the same as they appear in the plot specification. Assuming three scales Color, MarkerSize and custom exist in a spec, you can pass a vector to reorder them like [:MarkerSize, :custom, :Color], or merge multiple entries together with a nested vector like [[:MarkerSize, :custom], :Color], or give merged sections a title with the pair syntax [[:MarkerSize, :custom] => "Merged group", :Color].

source
AlgebraOfGraphics.paginateFunction
paginate(l, sc = scales(); layout=nothing, row=nothing, col=nothing)

Paginate l, the Layer or Layers object created by an AlgebraOfGraphics spec, to create a Pagination object.

Info

The pages are created by internally starting with one big facet plot first which includes all the input data, and then splitting it into pages. All scales are fit to the full data, not just the data that is visible on a given page, so a color legend, for example, will show all the categories and not just the ones that happen to be visible on the current page. This behavior changed with version 0.9 - before, each page had separately fit scales. The old behavior had the drawback that palettes were not guaranteed to be consistent across pages, for example, the same category could have different colors on two separate pages.

The Pagination object can be passed to draw which will return a Vector{FigureGrid} rather than a single figure.

The keywords that limit the number of subplots on each page are the same that are used to specify facets in mapping:

  • layout: Maximum number of subplots in a wrapped linear layout.
  • row: Maximum number of rows in a 2D layout.
  • col: Maximum number of columns in a 2D layout.

Example

d = data((
     x = rand(1000),
     y = rand(1000),
     group1 = rand(string.('a':'i'), 1000),
@@ -23,12 +23,12 @@
 ))
 
 layer_1 = d * mapping(:x, :y, layout = :group1) * visual(Scatter)
-paginated_1 = paginate(layer_1, layout = 9)
+paginated_1 = paginate(layer_1, layout = 4)
 figuregrids = draw(paginated_1)
 
 layer_2 = d * mapping(:x, :y, row = :group1, col = :group2) * visual(Scatter)
 paginated_2 = paginate(layer_2, row = 4, col = 3)
-figuregrid = draw(paginated_2, 1) # draw only the first grid
source
AlgebraOfGraphics.scalesFunction
scales(; kwargs...)

Create a Scales object containing properties for aesthetic scales that can be passed to draw and draw!. Each keyword should be the name of a scale in the spec that is being drawn. That can either be a default one like Color, Marker or LineStyle, or a custom scale name defined in a mapping using the scale function.

The values attached to the keywords must be dict-like, with Symbols as keys (such as NamedTuples).

source

Mapping helpers

AlgebraOfGraphics.pregroupedFunction
pregrouped(positional...; named...)

Equivalent to data(Pregrouped()) * mapping(positional...; named...). Refer to mapping for more information.

source
AlgebraOfGraphics.directFunction
direct(x)

Return DirectData(x) which marks x for direct use in a mapping that's used with a table-like data source. As a result, x will be used directly as data, without lookup in the table. If x is not an AbstractArray, it will be expanded like fill(x, n) where n is the number of rows in the data source.

source
AlgebraOfGraphics.renamerFunction
renamer(arr::Union{AbstractArray, Tuple})

Utility to rename a categorical variable, as in renamer([value1 => label1, value2 => label2]). The keys of all pairs should be all the unique values of the categorical variable and the values should be the corresponding labels. The order of arr is respected in the legend.

Examples

julia> r = renamer(["class 1" => "Class One", "class 2" => "Class Two"])
+figuregrid = draw(paginated_2, 1) # draw only the first grid
source
AlgebraOfGraphics.scalesFunction
scales(; kwargs...)

Create a Scales object containing properties for aesthetic scales that can be passed to draw and draw!. Each keyword should be the name of a scale in the spec that is being drawn. That can either be a default one like Color, Marker or LineStyle, or a custom scale name defined in a mapping using the scale function.

The values attached to the keywords must be dict-like, with Symbols as keys (such as NamedTuples).

source

Mapping helpers

AlgebraOfGraphics.pregroupedFunction
pregrouped(positional...; named...)

Equivalent to data(Pregrouped()) * mapping(positional...; named...). Refer to mapping for more information.

source
AlgebraOfGraphics.directFunction
direct(x)

Return DirectData(x) which marks x for direct use in a mapping that's used with a table-like data source. As a result, x will be used directly as data, without lookup in the table. If x is not an AbstractArray, it will be expanded like fill(x, n) where n is the number of rows in the data source.

source
AlgebraOfGraphics.renamerFunction
renamer(arr::Union{AbstractArray, Tuple})

Utility to rename a categorical variable, as in renamer([value1 => label1, value2 => label2]). The keys of all pairs should be all the unique values of the categorical variable and the values should be the corresponding labels. The order of arr is respected in the legend.

Examples

julia> r = renamer(["class 1" => "Class One", "class 2" => "Class Two"])
 AlgebraOfGraphics.Renamer{Vector{String}, Vector{String}}(["class 1", "class 2"], ["Class One", "Class Two"])
 
 julia> println(r("class 1"))
@@ -40,10 +40,10 @@
 AlgebraOfGraphics.Renamer{Nothing, Vector{String}}(nothing, ["Class One", "Class Two"])
 
 julia> println(r(2))
-Class Two
source
AlgebraOfGraphics.sorterFunction
sorter(ks)

Utility to reorder a categorical variable, as in sorter(["low", "medium", "high"]). A vararg method sorter("low", "medium", "high") is also supported. ks should include all the unique values of the categorical variable. The order of ks is respected in the legend.

source
AlgebraOfGraphics.nonnumericFunction
nonnumeric(x)

Transform x into a non numeric type that is printed and sorted in the same way.

source
AlgebraOfGraphics.verbatimFunction
verbatim(x)

Signal that x should not be rescaled, but used in the plot as is.

source
AlgebraOfGraphics.scaleFunction
scale(id::Symbol)

Create a ScaleID object that can be used in a mapping to assign a custom id to the mapped variable. This variable will then not be merged into the default scale for its aesthetic type, but instead be handled separately, leading to a separate legend entry.

source
AlgebraOfGraphics.presortedFunction
presorted(x)

Use within a pair expression in mapping to signal that a categorical column from the data source should be used in the original order and not automatically sorted.

Example:

# normally, categories would be sorted a, b, c but with `presorted`
+Class Two
source
AlgebraOfGraphics.sorterFunction
sorter(ks)

Utility to reorder a categorical variable, as in sorter(["low", "medium", "high"]). A vararg method sorter("low", "medium", "high") is also supported. ks should include all the unique values of the categorical variable. The order of ks is respected in the legend.

source
AlgebraOfGraphics.nonnumericFunction
nonnumeric(x)

Transform x into a non numeric type that is printed and sorted in the same way.

source
AlgebraOfGraphics.verbatimFunction
verbatim(x)

Signal that x should not be rescaled, but used in the plot as is.

source
AlgebraOfGraphics.scaleFunction
scale(id::Symbol)

Create a ScaleID object that can be used in a mapping to assign a custom id to the mapped variable. This variable will then not be merged into the default scale for its aesthetic type, but instead be handled separately, leading to a separate legend entry.

source
AlgebraOfGraphics.presortedFunction
presorted(x)

Use within a pair expression in mapping to signal that a categorical column from the data source should be used in the original order and not automatically sorted.

Example:

# normally, categories would be sorted a, b, c but with `presorted`
 # they stay in the order b, c, a
 
-data((; some_column = ["b", "c", "a"])) * mapping(:some_column => presorted)
source

Theming

AlgebraOfGraphics.set_aog_theme!Function
set_aog_theme!(; kwargs...)

Set the current theme to a predefined and opinionated theme, as defined by the unexported internal function AlgebraOfGraphics.aog_theme.

To tweak the predefined theme, use the function Makie.update_theme!. See the example below on how to change, e.g., default fontsize, title, and markersize.

For more information about setting themes, see the Theming section of the Makie.jl docs.

Examples

julia> using CairoMakie, AlgebraOfGraphics
+data((; some_column = ["b", "c", "a"])) * mapping(:some_column => presorted)
source

Theming

AlgebraOfGraphics.set_aog_theme!Function
set_aog_theme!(; kwargs...)

Set the current theme to a predefined and opinionated theme, as defined by the unexported internal function AlgebraOfGraphics.aog_theme.

To tweak the predefined theme, use the function Makie.update_theme!. See the example below on how to change, e.g., default fontsize, title, and markersize.

For more information about setting themes, see the Theming section of the Makie.jl docs.

Examples

julia> using CairoMakie, AlgebraOfGraphics
 
 julia> set_aog_theme!()                # Sets a prefedined theme
 
@@ -51,4 +51,4 @@
            fontsize=30,
            markersize=40,
            Axis=(title="MyDefaultTitle",)
-       )
source
AlgebraOfGraphics.aog_themeFunction
aog_theme(; fonts=[firasans("Medium"), firasans("Light")])

Return a NamedTuple of theme settings. Intended for internal use. The provided functionality is exposed to the user by the function set_aog_theme!.

source
AlgebraOfGraphics.from_continuousFunction
from_continuous(x)

Mark a colormap as continuous such that AlgebraOfGraphics will sample a categorical palette from start to end in n steps, and not by using the first n colors.

You could also use cgrad(colormap, n; categorical = true), however, this requires you to specify how many levels there are, which from_continuous detects automatically.

Example:

draw(scales(Color = (; palette = from_continuous(:viridis))))
source

Ticks helpers

AlgebraOfGraphics.datetimeticksFunction
datetimeticks(datetimes::AbstractVector{<:TimeType}, labels::AbstractVector{<:AbstractString})

Generate ticks matching datetimes to the corresponding labels. The result can be passed to xticks, yticks, or zticks.

source
datetimeticks(f, datetimes::AbstractVector{<:TimeType})

Compute ticks for the given datetimes using a formatting function f. The result can be passed to xticks, yticks, or zticks.

source

Internal functions

AlgebraOfGraphics.scientific_eltypeFunction
scientific_eltype(v)

Determine whether v should be treated as a continuous, geometrical, or categorical array.

source
AlgebraOfGraphics.scientific_typeFunction
scientific_type(T::Type)

Determine whether T represents a continuous, geometrical, or categorical variable.

source
AlgebraOfGraphics.plottypes_attributesFunction
plottypes_attributes(entries)

Return plottypes and relative attributes, as two vectors of the same length, for the given entries.

source
AlgebraOfGraphics.compute_attributesFunction
compute_attributes(pl::ProcessedLayer, categoricalscales, continuousscales_grid, continuousscales)

Process attributes of a ProcessedLayer. In particular,

  • remove AlgebraOfGraphics-specific layout attributes,
  • opt out of Makie cycling mechanism,
  • customize behavior of color (implementing alpha transparency),
  • customize behavior of bar width (default to one unit when not specified),
  • set correct colorrange.

Return computed attributes.

source
+ )source
AlgebraOfGraphics.aog_themeFunction
aog_theme(; fonts=[firasans("Medium"), firasans("Light")])

Return a NamedTuple of theme settings. Intended for internal use. The provided functionality is exposed to the user by the function set_aog_theme!.

source
AlgebraOfGraphics.from_continuousFunction
from_continuous(x)

Mark a colormap as continuous such that AlgebraOfGraphics will sample a categorical palette from start to end in n steps, and not by using the first n colors.

You could also use cgrad(colormap, n; categorical = true), however, this requires you to specify how many levels there are, which from_continuous detects automatically.

Example:

draw(scales(Color = (; palette = from_continuous(:viridis))))
source

Ticks helpers

AlgebraOfGraphics.datetimeticksFunction
datetimeticks(datetimes::AbstractVector{<:TimeType}, labels::AbstractVector{<:AbstractString})

Generate ticks matching datetimes to the corresponding labels. The result can be passed to xticks, yticks, or zticks.

source
datetimeticks(f, datetimes::AbstractVector{<:TimeType})

Compute ticks for the given datetimes using a formatting function f. The result can be passed to xticks, yticks, or zticks.

source

Internal functions

AlgebraOfGraphics.scientific_eltypeFunction
scientific_eltype(v)

Determine whether v should be treated as a continuous, geometrical, or categorical array.

source
AlgebraOfGraphics.scientific_typeFunction
scientific_type(T::Type)

Determine whether T represents a continuous, geometrical, or categorical variable.

source
AlgebraOfGraphics.plottypes_attributesFunction
plottypes_attributes(entries)

Return plottypes and relative attributes, as two vectors of the same length, for the given entries.

source
AlgebraOfGraphics.compute_attributesFunction
compute_attributes(pl::ProcessedLayer, categoricalscales, continuousscales_grid, continuousscales)

Process attributes of a ProcessedLayer. In particular,

  • remove AlgebraOfGraphics-specific layout attributes,
  • opt out of Makie cycling mechanism,
  • customize behavior of color (implementing alpha transparency),
  • customize behavior of bar width (default to one unit when not specified),
  • set correct colorrange.

Return computed attributes.

source
diff --git a/previews/PR593/API/recipes/index.html b/previews/PR593/API/recipes/index.html index 653d597fb..adcb27398 100644 --- a/previews/PR593/API/recipes/index.html +++ b/previews/PR593/API/recipes/index.html @@ -27,11 +27,11 @@ strokecolormap :batlow strokewidth 0 transparency false - visible truesource
AlgebraOfGraphics.linesfillFunction
linesfill(xs, ys; lower, upper, attributes...)

Line plot with a shaded area between lower and upper. If lower and upper are not given, shaded area is between 0 and ys.

Attributes

Available attributes and their defaults for Plot{AlgebraOfGraphics.linesfill} are:

  color       :gray25
+  visible             true
source
AlgebraOfGraphics.linesfillFunction
linesfill(xs, ys; lower, upper, attributes...)

Line plot with a shaded area between lower and upper. If lower and upper are not given, shaded area is between 0 and ys.

Attributes

Available attributes and their defaults for Plot{AlgebraOfGraphics.linesfill} are:

  color       :gray25
   colormap    :batlow
   colorrange  MakieCore.Automatic()
   fillalpha   0.15
   linestyle   "nothing"
   linewidth   1.5
   lower       MakieCore.Automatic()
-  upper       MakieCore.Automatic()
source
+ upper MakieCore.Automatic()source diff --git a/previews/PR593/API/types/index.html b/previews/PR593/API/types/index.html index e242b62d5..2ec5b302d 100644 --- a/previews/PR593/API/types/index.html +++ b/previews/PR593/API/types/index.html @@ -1,3 +1,3 @@ -Types · Algebra of Graphics

Types

AlgebraOfGraphics.LayerType
Layer(transformation, data, positional::AbstractVector, named::AbstractDictionary)

Algebraic object encoding a single layer of a visualization. It is composed of a dataset, positional and named arguments, as well as a transformation to be applied to those. Layer objects can be multiplied, yielding a novel Layer object, or added, yielding a AlgebraOfGraphics.Layers object.

source
AlgebraOfGraphics.zerolayerFunction
zerolayer()

Returns a Layers with an empty layer list which can act as a zero in the layer algebra.

layer * zerolayer() ~ zerolayer()
-layer + zerolayer() ~ layer
source
AlgebraOfGraphics.ProcessedLayerType
ProcessedLayer(l::Layer)

Process a Layer and return the resulting ProcessedLayer.

Note that this method should not be used anymore as processing a Layer can now potentially return multiple ProcessedLayer objects. Therefore, you should use the plural form ProcessedLayers(layer).

source
AlgebraOfGraphics.EntryType
Entry(plottype::PlotType, positional::Arguments, named::NamedArguments)

Define plottype as well as positional and named arguments for a single plot.

source
AlgebraOfGraphics.AxisEntriesType
AxisEntries(axis::Union{Axis, Nothing}, entries::Vector{Entry}, categoricalscales, continuousscales)

Define all ingredients to make plots on an axis. Each categorical scale should be a CategoricalScale, and each continuous scale should be a ContinuousScale.

source
+Types · Algebra of Graphics

Types

AlgebraOfGraphics.LayerType
Layer(transformation, data, positional::AbstractVector, named::AbstractDictionary)

Algebraic object encoding a single layer of a visualization. It is composed of a dataset, positional and named arguments, as well as a transformation to be applied to those. Layer objects can be multiplied, yielding a novel Layer object, or added, yielding a AlgebraOfGraphics.Layers object.

source
AlgebraOfGraphics.zerolayerFunction
zerolayer()

Returns a Layers with an empty layer list which can act as a zero in the layer algebra.

layer * zerolayer() ~ zerolayer()
+layer + zerolayer() ~ layer
source
AlgebraOfGraphics.ProcessedLayerType
ProcessedLayer(l::Layer)

Process a Layer and return the resulting ProcessedLayer.

Note that this method should not be used anymore as processing a Layer can now potentially return multiple ProcessedLayer objects. Therefore, you should use the plural form ProcessedLayers(layer).

source
AlgebraOfGraphics.EntryType
Entry(plottype::PlotType, positional::Arguments, named::NamedArguments)

Define plottype as well as positional and named arguments for a single plot.

source
AlgebraOfGraphics.AxisEntriesType
AxisEntries(axis::Union{Axis, Nothing}, entries::Vector{Entry}, categoricalscales, continuousscales)

Define all ingredients to make plots on an axis. Each categorical scale should be a CategoricalScale, and each continuous scale should be a ContinuousScale.

source
diff --git a/previews/PR593/FAQs/index.html b/previews/PR593/FAQs/index.html index 2e0ac4eb6..f6edf223f 100644 --- a/previews/PR593/FAQs/index.html +++ b/previews/PR593/FAQs/index.html @@ -18,4 +18,4 @@ hist2 = data(df) * mapping(:x => log => "log(x)") * histogram() fg = draw(hist2; figure = (size = (600, 400),)) -lines(fg.figure[1, 2], 0..2pi, cos)Example block output
Note

When setting the width and height dimensions of each axis manually you will need to call resize_to_layout!(fg) before displaying the figure such that each axis is sized correctly.

+lines(fg.figure[1, 2], 0..2pi, cos)Example block output
Note

When setting the width and height dimensions of each axis manually you will need to call resize_to_layout!(fg) before displaying the figure such that each axis is sized correctly.

diff --git a/previews/PR593/changelog/index.html b/previews/PR593/changelog/index.html index c00312170..4050a4f9e 100644 --- a/previews/PR593/changelog/index.html +++ b/previews/PR593/changelog/index.html @@ -1,2 +1,2 @@ -Changelog · Algebra of Graphics

Changelog

Unreleased

v0.8.14 - 2025-01-16

  • Added automatic alpha forwarding to all legend elements which will have an effect from Makie 0.22.1 on #588.
  • Added the ability to use multiple different X and Y scales within one facet layout. The requirement is that not more than one X and Y scale is used per facet. Row, Col and Layout scales got the ability to set show_labels = false in scales. Also added the zerolayer function which can be used as a basis to build up the required mappings iteratively #586.
  • Increased compat to Makie 0.22 and GeometryBasics 0.5 #587.
  • Increased compat to Colors 0.13 #589.

v0.8.13 - 2024-10-21

  • Added aesthetics for Stairs #573.

v0.8.12 - 2024-10-07

  • Added legend keyword in visual to allow overriding legend element attributes #570.

v0.8.11 - 2024-09-25

  • Fixed lexicographic natural sorting of tuples (this would fall back to default sort order before) #568.

v0.8.10 - 2024-09-24

  • Fixed markercolor in ScatterLines legends when it did not match color #567.

v0.8.9 - 2024-09-24

  • Added ability to include layers in the legend without using scales by adding visual(label = "some label") #565.

v0.8.8 - 2024-09-17

  • Fixed aesthetics of errorbar so that x and y stay labelled correctly when using direction = :x #560.
  • Added ability to specify title, subtitle and footnotes plus settings in the draw function #556.
  • Added dodge_x and dodge_y keywords to mapping that allow to dodge any plot types that have AesX or AesY data #558.

v0.8.7 - 2024-09-06

  • Added ability to return ProcessedLayers from transformations, thereby enabling multi-layer transformations, such as scatter plus errorbars #549.
  • Fixed bug where mergesorted applied on string vectors used isless instead of natural sort #553.

v0.8.6 - 2024-09-02

  • Added bar_labels to BarPlot's aesthetic mapping #544.
  • Added ability to hide legend or colorbar by passing, e.g., legend = (; show = false) to draw #547.

v0.8.5 - 2024-08-27

  • Added presorted helper function to keep categorical data in the order encountered in the source table, instead of sorting it alphabetically #529.
  • Added from_continuous helper function which allows to sample continuous colormaps evenly to use them as categorical palettes without having to specify how many categories there are #541.

v0.8.4 - 2024-08-26

  • Added fillto to BarPlot aesthetics #535.
  • Fixed bug when giving datalimits of density as a (low, high) tuple #536.
  • Fixed bug where facet-local continuous scale limits were used instead of the globally merged ones, possibly leading to mismatches between data and legend #539.

v0.8.3 - 2024-08-23

  • Fixed incorrect x/y axis assignment for the violin plot type #528.

v0.8.2 - 2024-08-21

  • Enable use of LaTeXStrings and rich text in renamer #525.
  • Fixed widths of boxplots with color groupings #524.

v0.8.1 - 2024-08-20

  • Added back support for Hist, CrossBar, ECDFPlot and Density #522.

v0.8.0 - 2024-07-26

  • Breaking: Columns with element types of Union{Missing,T} are not treated as categorical by default anymore, instead T decides if data is seen as categorical, continuous or geometrical. If you relied on numerical vectors with missings being treated as categorical, you can use :columnname => nonnumeric in the mapping instead.
  • Breaking: AbstractString categories are now sorted with natural sort order by default. This means that where you got ["1", "10", "2"] before, you now get ["1", "2", "10"]. You can use sorter, the categories keyword or categorical arrays to sort your data differently if needed.

v0.7.0 - 2024-07-16

  • Breaking: The palette keyword of draw linking palettes to keyword arguments was removed. Instead, palettes need to be passed to specific scales like draw(..., scales(Color = (; palette = :Set1_3)))
  • Breaking: All recipes need to have the new function aesthetic_mapping defined for all sets of positional arguments that should be supported, as can be seen in src/aesthetics.jl. This breaks usage of all custom recipes. Additionally, not all Makie plots have been ported to the new system yet. If you encounter missing plots, or missing attributes of already ported plots, please open an issue.
  • Breaking: All custom recipes that should be displayed in a legend, need to have legend_elements(P, attributes, scale_args) defined as can be seen in src/guides/legend.jl. AlgebraOfGraphics cannot use the same default mechanism as Makie, which can create a legend from an existing plot, because AlgebraOfGraphics needs to create the legend before the plot is instantiated.
  • Breaking: Pregrouped data cannot be passed anymore to the plain mapping(...) without any data(tabular). Instead, you should use pregrouped(...) which is a shortcut for data(Pregrouped()) * mapping(...).
  • Breaking: Contour and Contourf generally do not work anymore with visual(). Instead, the contours() and filled_contours() analyses should be used. Contour can still be used with categorical colors, but not with continuous ones.
  • Breaking: All colormap properties for continuous color scales need to be passed via scales now, and not through visual. This is to have central control over the scale as it can be used by multiple visuals simultaneously.
  • Horizontal barplots, violins, errorbars, rangebars and other plot types that have two different orientations work correctly now. Axis labels switch accordingly when the orientation is changed.
  • Plotting functions whose positional arguments don't correspond to X, Y, Z work correctly now. For example, HLines (1 => Y) or rangebars (1 => X, 2 => Y, 3 => Y).
  • It is possible to add categories beyond those present in the data with the categories keyword within a scale's settings. It is also possible to reorder or otherwise transform the existing categories by passing a function to categories.
  • The supported attributes are not limited anymore to a specific set of names, for example, strokecolor can work the same as color did before, and the two can share a scale via their shared aesthetic type.
  • There can be multiple scales of the same aesthetic now. This allows to have separate legends for different plot types using the same aesthetics. Scale separation works by pairing a variable in mapping with a scale(id_symbol).
  • Legend entries can be reordered using the legend = (; order = ...) option in draw. Specific scales can opt out of the legend by passing legend = false in scales.
  • Labels can now be anything that Makie supports, primarily Strings, LaTeXStrings or rich text.
  • Legend elements now usually reflect all attributes set in their corresponding visual.
  • Simple column vectors of data can now be passed directly to mapping without using data first. Additionally, scalar values are accepted as a shortcut for columns with the same repeated value.
  • Columns from outside a table source in data can now be passed to mapping by wrapping them in the direct function. Scalar values are accepted as a shortcut for columns with the same repeated value. For example, to create a label for columns x and y from a dataframe passed to data, one could now do mapping(:x, :y, color = direct("label")) without having to create a column full of "label" strings first.
  • The numbers at which categorical values are plotted on x and y axis can now be changed via scales(X = (; palette = [1, 2, 4])) or similar.
  • Continuous marker size scales can now be shown in the legend. Numerical values are proportional to area and not diameter now, which makes more sense with respect to human perception. The min and max marker size can be set using the sizerange property for the respective scale in scales.

v0.6.11 - 2022-08-08

  • Added paginate for pagination of large facet plots.

v0.6.8 - 2022-06-14

  • Added choropleth recipe to supersede geodata for geographical data.

v0.6.1 - 2022-01-28

  • Support level in linear analysis for confidence interval.
  • Replaced tuples and named tuples in Layer and Entry with dictionaries from Dictionaries.jl.
  • Split internal Entry type into ProcessedLayer (to be used for analyses) and Entry (to be used for plotting).

v0.6.0 - 2021-10-24

  • Breaking: Default axis linking behavior has changed: now only axes corresponding to the same variable are linked. For consistency with row/col, layout will hide decorations of linked axes and span axis labels if appropriate.
  • Customizable legend and colorbar position and look.
  • Customizable axis linking behavior.

v0.5 - 2021-08-05

  • Breaking: Axis(ae) has been replaced by ae.axis.
  • Breaking: Legend(fg) has been replaced by legend!(fg) and colorbar!(fg).
  • legend! and colorbar! API allows for custom legend placement.

v0.4 - 2021-05-21

  • Breaking: Removed deprecations for style and spec (now only mapping and visual are allowed).
  • Breaking: Analyses now require parentheses (i.e. linear() instead of linear).
  • Breaking: Rename layout_x and layout_y to col and row.
  • Breaking: Rename wts keyword argument to weights.
  • Breaking: categorical has been replaced by nonnumeric.
+Changelog · Algebra of Graphics

Changelog

Unreleased

  • Breaking: paginate now splits facet plots into pages after fitting scales and not before #593. This means that, e.g., categorical color mappings are consistent across pages where before each page could have a different mapping if some groups were not represented on a given page. This change also makes pagination work with the split X and Y scales feature enabled by version 0.8.14. paginate's return type changes from PaginatedLayers to Pagination because no layers are stored in that type anymore. The interface to use Pagination with draw and other functions doesn't change compared to PaginatedLayers. paginate now also accepts an optional second positional argument which are the scales that are normally passed to draw when not paginating, but which must be available prior to pagination to fit all scales accordingly.

v0.8.14 - 2025-01-16

  • Added automatic alpha forwarding to all legend elements which will have an effect from Makie 0.22.1 on #588.
  • Added the ability to use multiple different X and Y scales within one facet layout. The requirement is that not more than one X and Y scale is used per facet. Row, Col and Layout scales got the ability to set show_labels = false in scales. Also added the zerolayer function which can be used as a basis to build up the required mappings iteratively #586.
  • Increased compat to Makie 0.22 and GeometryBasics 0.5 #587.
  • Increased compat to Colors 0.13 #589.

v0.8.13 - 2024-10-21

  • Added aesthetics for Stairs #573.

v0.8.12 - 2024-10-07

  • Added legend keyword in visual to allow overriding legend element attributes #570.

v0.8.11 - 2024-09-25

  • Fixed lexicographic natural sorting of tuples (this would fall back to default sort order before) #568.

v0.8.10 - 2024-09-24

  • Fixed markercolor in ScatterLines legends when it did not match color #567.

v0.8.9 - 2024-09-24

  • Added ability to include layers in the legend without using scales by adding visual(label = "some label") #565.

v0.8.8 - 2024-09-17

  • Fixed aesthetics of errorbar so that x and y stay labelled correctly when using direction = :x #560.
  • Added ability to specify title, subtitle and footnotes plus settings in the draw function #556.
  • Added dodge_x and dodge_y keywords to mapping that allow to dodge any plot types that have AesX or AesY data #558.

v0.8.7 - 2024-09-06

  • Added ability to return ProcessedLayers from transformations, thereby enabling multi-layer transformations, such as scatter plus errorbars #549.
  • Fixed bug where mergesorted applied on string vectors used isless instead of natural sort #553.

v0.8.6 - 2024-09-02

  • Added bar_labels to BarPlot's aesthetic mapping #544.
  • Added ability to hide legend or colorbar by passing, e.g., legend = (; show = false) to draw #547.

v0.8.5 - 2024-08-27

  • Added presorted helper function to keep categorical data in the order encountered in the source table, instead of sorting it alphabetically #529.
  • Added from_continuous helper function which allows to sample continuous colormaps evenly to use them as categorical palettes without having to specify how many categories there are #541.

v0.8.4 - 2024-08-26

  • Added fillto to BarPlot aesthetics #535.
  • Fixed bug when giving datalimits of density as a (low, high) tuple #536.
  • Fixed bug where facet-local continuous scale limits were used instead of the globally merged ones, possibly leading to mismatches between data and legend #539.

v0.8.3 - 2024-08-23

  • Fixed incorrect x/y axis assignment for the violin plot type #528.

v0.8.2 - 2024-08-21

  • Enable use of LaTeXStrings and rich text in renamer #525.
  • Fixed widths of boxplots with color groupings #524.

v0.8.1 - 2024-08-20

  • Added back support for Hist, CrossBar, ECDFPlot and Density #522.

v0.8.0 - 2024-07-26

  • Breaking: Columns with element types of Union{Missing,T} are not treated as categorical by default anymore, instead T decides if data is seen as categorical, continuous or geometrical. If you relied on numerical vectors with missings being treated as categorical, you can use :columnname => nonnumeric in the mapping instead.
  • Breaking: AbstractString categories are now sorted with natural sort order by default. This means that where you got ["1", "10", "2"] before, you now get ["1", "2", "10"]. You can use sorter, the categories keyword or categorical arrays to sort your data differently if needed.

v0.7.0 - 2024-07-16

  • Breaking: The palette keyword of draw linking palettes to keyword arguments was removed. Instead, palettes need to be passed to specific scales like draw(..., scales(Color = (; palette = :Set1_3)))
  • Breaking: All recipes need to have the new function aesthetic_mapping defined for all sets of positional arguments that should be supported, as can be seen in src/aesthetics.jl. This breaks usage of all custom recipes. Additionally, not all Makie plots have been ported to the new system yet. If you encounter missing plots, or missing attributes of already ported plots, please open an issue.
  • Breaking: All custom recipes that should be displayed in a legend, need to have legend_elements(P, attributes, scale_args) defined as can be seen in src/guides/legend.jl. AlgebraOfGraphics cannot use the same default mechanism as Makie, which can create a legend from an existing plot, because AlgebraOfGraphics needs to create the legend before the plot is instantiated.
  • Breaking: Pregrouped data cannot be passed anymore to the plain mapping(...) without any data(tabular). Instead, you should use pregrouped(...) which is a shortcut for data(Pregrouped()) * mapping(...).
  • Breaking: Contour and Contourf generally do not work anymore with visual(). Instead, the contours() and filled_contours() analyses should be used. Contour can still be used with categorical colors, but not with continuous ones.
  • Breaking: All colormap properties for continuous color scales need to be passed via scales now, and not through visual. This is to have central control over the scale as it can be used by multiple visuals simultaneously.
  • Horizontal barplots, violins, errorbars, rangebars and other plot types that have two different orientations work correctly now. Axis labels switch accordingly when the orientation is changed.
  • Plotting functions whose positional arguments don't correspond to X, Y, Z work correctly now. For example, HLines (1 => Y) or rangebars (1 => X, 2 => Y, 3 => Y).
  • It is possible to add categories beyond those present in the data with the categories keyword within a scale's settings. It is also possible to reorder or otherwise transform the existing categories by passing a function to categories.
  • The supported attributes are not limited anymore to a specific set of names, for example, strokecolor can work the same as color did before, and the two can share a scale via their shared aesthetic type.
  • There can be multiple scales of the same aesthetic now. This allows to have separate legends for different plot types using the same aesthetics. Scale separation works by pairing a variable in mapping with a scale(id_symbol).
  • Legend entries can be reordered using the legend = (; order = ...) option in draw. Specific scales can opt out of the legend by passing legend = false in scales.
  • Labels can now be anything that Makie supports, primarily Strings, LaTeXStrings or rich text.
  • Legend elements now usually reflect all attributes set in their corresponding visual.
  • Simple column vectors of data can now be passed directly to mapping without using data first. Additionally, scalar values are accepted as a shortcut for columns with the same repeated value.
  • Columns from outside a table source in data can now be passed to mapping by wrapping them in the direct function. Scalar values are accepted as a shortcut for columns with the same repeated value. For example, to create a label for columns x and y from a dataframe passed to data, one could now do mapping(:x, :y, color = direct("label")) without having to create a column full of "label" strings first.
  • The numbers at which categorical values are plotted on x and y axis can now be changed via scales(X = (; palette = [1, 2, 4])) or similar.
  • Continuous marker size scales can now be shown in the legend. Numerical values are proportional to area and not diameter now, which makes more sense with respect to human perception. The min and max marker size can be set using the sizerange property for the respective scale in scales.

v0.6.11 - 2022-08-08

  • Added paginate for pagination of large facet plots.

v0.6.8 - 2022-06-14

  • Added choropleth recipe to supersede geodata for geographical data.

v0.6.1 - 2022-01-28

  • Support level in linear analysis for confidence interval.
  • Replaced tuples and named tuples in Layer and Entry with dictionaries from Dictionaries.jl.
  • Split internal Entry type into ProcessedLayer (to be used for analyses) and Entry (to be used for plotting).

v0.6.0 - 2021-10-24

  • Breaking: Default axis linking behavior has changed: now only axes corresponding to the same variable are linked. For consistency with row/col, layout will hide decorations of linked axes and span axis labels if appropriate.
  • Customizable legend and colorbar position and look.
  • Customizable axis linking behavior.

v0.5 - 2021-08-05

  • Breaking: Axis(ae) has been replaced by ae.axis.
  • Breaking: Legend(fg) has been replaced by legend!(fg) and colorbar!(fg).
  • legend! and colorbar! API allows for custom legend placement.

v0.4 - 2021-05-21

  • Breaking: Removed deprecations for style and spec (now only mapping and visual are allowed).
  • Breaking: Analyses now require parentheses (i.e. linear() instead of linear).
  • Breaking: Rename layout_x and layout_y to col and row.
  • Breaking: Rename wts keyword argument to weights.
  • Breaking: categorical has been replaced by nonnumeric.
diff --git a/previews/PR593/gallery/covers/custom_scales.png b/previews/PR593/gallery/covers/custom_scales.png index 497d02b5f..0f067e9d5 100644 Binary files a/previews/PR593/gallery/covers/custom_scales.png and b/previews/PR593/gallery/covers/custom_scales.png differ diff --git a/previews/PR593/gallery/covers/density_plots.png b/previews/PR593/gallery/covers/density_plots.png index d3f840e9c..97528e4bd 100644 Binary files a/previews/PR593/gallery/covers/density_plots.png and b/previews/PR593/gallery/covers/density_plots.png differ diff --git a/previews/PR593/gallery/covers/discrete_scales.png b/previews/PR593/gallery/covers/discrete_scales.png index 7d9858e80..91eb8bb12 100644 Binary files a/previews/PR593/gallery/covers/discrete_scales.png and b/previews/PR593/gallery/covers/discrete_scales.png differ diff --git a/previews/PR593/gallery/covers/histograms.png b/previews/PR593/gallery/covers/histograms.png index 1c4e4d3ff..24938c5e4 100644 Binary files a/previews/PR593/gallery/covers/histograms.png and b/previews/PR593/gallery/covers/histograms.png differ diff --git a/previews/PR593/gallery/covers/lines_and_markers.png b/previews/PR593/gallery/covers/lines_and_markers.png index 118e6f351..d6ec37681 100644 Binary files a/previews/PR593/gallery/covers/lines_and_markers.png and b/previews/PR593/gallery/covers/lines_and_markers.png differ diff --git a/previews/PR593/gallery/covers/new_columns_on_the_fly.png b/previews/PR593/gallery/covers/new_columns_on_the_fly.png index 7d335d2d7..f76582c98 100644 Binary files a/previews/PR593/gallery/covers/new_columns_on_the_fly.png and b/previews/PR593/gallery/covers/new_columns_on_the_fly.png differ diff --git a/previews/PR593/gallery/covers/pre_grouped_data.png b/previews/PR593/gallery/covers/pre_grouped_data.png index 242ea366b..28014b1d2 100644 Binary files a/previews/PR593/gallery/covers/pre_grouped_data.png and b/previews/PR593/gallery/covers/pre_grouped_data.png differ diff --git a/previews/PR593/gallery/covers/regression_plots.png b/previews/PR593/gallery/covers/regression_plots.png index d6d7febd5..befadbedf 100644 Binary files a/previews/PR593/gallery/covers/regression_plots.png and b/previews/PR593/gallery/covers/regression_plots.png differ diff --git a/previews/PR593/gallery/covers/time_series.png b/previews/PR593/gallery/covers/time_series.png index 580389704..308658dfa 100644 Binary files a/previews/PR593/gallery/covers/time_series.png and b/previews/PR593/gallery/covers/time_series.png differ diff --git a/previews/PR593/gallery/covers/wide_data.png b/previews/PR593/gallery/covers/wide_data.png index 137a5d4a7..d04ac4131 100644 Binary files a/previews/PR593/gallery/covers/wide_data.png and b/previews/PR593/gallery/covers/wide_data.png differ diff --git a/previews/PR593/gallery/gallery/applications/assets/time_series.png b/previews/PR593/gallery/gallery/applications/assets/time_series.png index 580389704..308658dfa 100644 Binary files a/previews/PR593/gallery/gallery/applications/assets/time_series.png and b/previews/PR593/gallery/gallery/applications/assets/time_series.png differ diff --git a/previews/PR593/gallery/gallery/applications/geographic/index.html b/previews/PR593/gallery/gallery/applications/geographic/index.html index ce14de58c..f9ba1ec5a 100644 --- a/previews/PR593/gallery/gallery/applications/geographic/index.html +++ b/previews/PR593/gallery/gallery/applications/geographic/index.html @@ -15,4 +15,4 @@ # Draw map plt = data(t) * mapping(:geometry, color = :surface) * visual(Choropleth) -fg = draw(plt; axis=(aspect=1,))


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(plt; axis=(aspect=1,))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/applications/geometries/index.html b/previews/PR593/gallery/gallery/applications/geometries/index.html index 1a5e289ce..20507f43e 100644 --- a/previews/PR593/gallery/gallery/applications/geometries/index.html +++ b/previews/PR593/gallery/gallery/applications/geometries/index.html @@ -7,4 +7,4 @@ df = (; geometry, group) plt = data(df) * visual(Poly) * mapping(:geometry, color = :group) -fg = draw(plt; axis=(aspect=1,))


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(plt; axis=(aspect=1,))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/applications/time_series-3.svg b/previews/PR593/gallery/gallery/applications/time_series-3.svg index b12501c63..acc3b8947 100644 --- a/previews/PR593/gallery/gallery/applications/time_series-3.svg +++ b/previews/PR593/gallery/gallery/applications/time_series-3.svg @@ -2,166 +2,172 @@ - + - + - - - - + - - + + - + - - + + - + - - + + + + + - + + + + + + + - - + + + + + - + - + - - - - + - - - - + - - + + - - + + - - + + - + + + + - + - - - - + - + + + + + + + - + - + - + - + - + - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -169,176 +175,176 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + + + + @@ -347,73 +353,73 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/applications/time_series-4.svg b/previews/PR593/gallery/gallery/applications/time_series-4.svg index 764ab5bae..6e9bb63b5 100644 --- a/previews/PR593/gallery/gallery/applications/time_series-4.svg +++ b/previews/PR593/gallery/gallery/applications/time_series-4.svg @@ -2,136 +2,136 @@ - + - - - - - + + - + - - - - + - + + + + - + - + - + - + - + - + + + + - + - - + + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -139,127 +139,127 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + + @@ -268,73 +268,73 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/applications/time_series/index.html b/previews/PR593/gallery/gallery/applications/time_series/index.html index 654917d38..47898633e 100644 --- a/previews/PR593/gallery/gallery/applications/time_series/index.html +++ b/previews/PR593/gallery/gallery/applications/time_series/index.html @@ -26,4 +26,4 @@ return (; date, observation) end plt = data(df) * mapping(:date, :observation) * visual(BoxPlot) -draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

+draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/basic visualizations/assets/lines_and_markers.png b/previews/PR593/gallery/gallery/basic visualizations/assets/lines_and_markers.png index 118e6f351..d6ec37681 100644 Binary files a/previews/PR593/gallery/gallery/basic visualizations/assets/lines_and_markers.png and b/previews/PR593/gallery/gallery/basic visualizations/assets/lines_and_markers.png differ diff --git a/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers-4.svg b/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers-4.svg index 2b551e2b9..cac69322b 100644 --- a/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers-4.svg +++ b/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers-4.svg @@ -2,61 +2,55 @@ - + - + - + - + - - - - - - - + - + - + + + + - + - + - + - + - + - - - - + - + - + - + @@ -64,171 +58,171 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers-9.svg b/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers-9.svg index 5d820938f..d416cf389 100644 --- a/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers-9.svg +++ b/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers-9.svg @@ -2,70 +2,70 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -73,85 +73,85 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - + + + + + + + + + + diff --git a/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers/index.html b/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers/index.html index 07cb6f5d7..a047f42eb 100644 --- a/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers/index.html +++ b/previews/PR593/gallery/gallery/basic visualizations/lines_and_markers/index.html @@ -18,4 +18,4 @@ df1 = (; x, y) df2 = (x=rand(10), y=rand(10)) layers = data(df1) * visual(Lines) + data(df2) * visual(Scatter) -fg = draw(layers * mapping(:x, :y))


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(layers * mapping(:x, :y))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/basic visualizations/statistical_visualizations/index.html b/previews/PR593/gallery/gallery/basic visualizations/statistical_visualizations/index.html index 249beac20..25c26643e 100644 --- a/previews/PR593/gallery/gallery/basic visualizations/statistical_visualizations/index.html +++ b/previews/PR593/gallery/gallery/basic visualizations/statistical_visualizations/index.html @@ -9,4 +9,4 @@ fg = draw(plt, axis=(limits=((0.5, 3.5), nothing),))

data(penguins) * visual(BoxPlot, show_notch=true) *
     mapping(:species, :bill_depth_mm, color=:sex, dodge=:sex) |> draw

data(penguins) *
     mapping(:bill_length_mm, :bill_depth_mm, col=:sex) *
-    visual(QQPlot, qqline=:fit) |> draw


This page was generated using DemoCards.jl and Literate.jl.

+ visual(QQPlot, qqline=:fit) |> draw


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/customization/axis-5.svg b/previews/PR593/gallery/gallery/customization/axis-5.svg index 06f5cbefd..ad5b59d23 100644 --- a/previews/PR593/gallery/gallery/customization/axis-5.svg +++ b/previews/PR593/gallery/gallery/customization/axis-5.svg @@ -2,130 +2,130 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -229,46 +229,46 @@ - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/customization/axis-6.svg b/previews/PR593/gallery/gallery/customization/axis-6.svg index ad5be560a..af4a8de96 100644 --- a/previews/PR593/gallery/gallery/customization/axis-6.svg +++ b/previews/PR593/gallery/gallery/customization/axis-6.svg @@ -2,426 +2,426 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -525,46 +525,46 @@ - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/customization/axis/index.html b/previews/PR593/gallery/gallery/customization/axis/index.html index 5472b145f..d77daddfe 100644 --- a/previews/PR593/gallery/gallery/customization/axis/index.html +++ b/previews/PR593/gallery/gallery/customization/axis/index.html @@ -2,4 +2,4 @@ Axis tweaking · Algebra of Graphics

Axis tweaking

Source code Author

using AlgebraOfGraphics, CairoMakie

To tweak one or more axes, simply use the axis keyword when plotting. For example

df = (x=rand(100), y=rand(100), z=rand(100))
 layers = linear() + mapping(color=:z)
 plt = data(df) * layers * mapping(:x, :y)
-draw(plt, axis=(aspect=1,))

fg = draw(plt, axis=(aspect=1, xticks=0:0.1:1, yticks=0:0.1:1, ylabel="custom label"))


This page was generated using DemoCards.jl and Literate.jl.

+draw(plt, axis=(aspect=1,))

fg = draw(plt, axis=(aspect=1, xticks=0:0.1:1, yticks=0:0.1:1, ylabel="custom label"))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/customization/colorbar-11.svg b/previews/PR593/gallery/gallery/customization/colorbar-11.svg index 69eceac16..18a91b8b8 100644 --- a/previews/PR593/gallery/gallery/customization/colorbar-11.svg +++ b/previews/PR593/gallery/gallery/customization/colorbar-11.svg @@ -2,190 +2,190 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -287,48 +287,48 @@ - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/customization/colorbar-6.svg b/previews/PR593/gallery/gallery/customization/colorbar-6.svg index 0920ab071..43ce7cfce 100644 --- a/previews/PR593/gallery/gallery/customization/colorbar-6.svg +++ b/previews/PR593/gallery/gallery/customization/colorbar-6.svg @@ -2,187 +2,187 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -284,46 +284,46 @@ - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/customization/colorbar-9.svg b/previews/PR593/gallery/gallery/customization/colorbar-9.svg index 48d15d3be..42956cb8e 100644 --- a/previews/PR593/gallery/gallery/customization/colorbar-9.svg +++ b/previews/PR593/gallery/gallery/customization/colorbar-9.svg @@ -2,181 +2,181 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -278,46 +278,46 @@ - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/customization/colorbar/index.html b/previews/PR593/gallery/gallery/customization/colorbar/index.html index 125d892e9..de4c39fae 100644 --- a/previews/PR593/gallery/gallery/customization/colorbar/index.html +++ b/previews/PR593/gallery/gallery/customization/colorbar/index.html @@ -6,4 +6,4 @@ colorrange = (0.25, 0.75), highclip = :cyan, lowclip = :lime, -)))


This page was generated using DemoCards.jl and Literate.jl.

+)))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/customization/figure-5.svg b/previews/PR593/gallery/gallery/customization/figure-5.svg index 3ee453ec4..75efed38a 100644 --- a/previews/PR593/gallery/gallery/customization/figure-5.svg +++ b/previews/PR593/gallery/gallery/customization/figure-5.svg @@ -2,164 +2,164 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -212,31 +212,31 @@ - + - + - + - + - + - + - + - + - + @@ -293,57 +293,57 @@ - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/customization/figure-7.svg b/previews/PR593/gallery/gallery/customization/figure-7.svg index 60924a8b8..f2639c7b6 100644 --- a/previews/PR593/gallery/gallery/customization/figure-7.svg +++ b/previews/PR593/gallery/gallery/customization/figure-7.svg @@ -2,358 +2,358 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -406,31 +406,31 @@ - + - + - + - + - + - + - + - + - + @@ -487,294 +487,294 @@ - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/customization/figure-9.svg b/previews/PR593/gallery/gallery/customization/figure-9.svg index 3806b7404..5931f7202 100644 --- a/previews/PR593/gallery/gallery/customization/figure-9.svg +++ b/previews/PR593/gallery/gallery/customization/figure-9.svg @@ -2,339 +2,339 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -387,31 +387,31 @@ - + - + - + - + - + - + - + - + - + @@ -468,294 +468,294 @@ - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/customization/figure/index.html b/previews/PR593/gallery/gallery/customization/figure/index.html index 77d9052d9..281f3de48 100644 --- a/previews/PR593/gallery/gallery/customization/figure/index.html +++ b/previews/PR593/gallery/gallery/customization/figure/index.html @@ -39,4 +39,4 @@ titlealign = :right, footnotefont = :bold, ) -)


This page was generated using DemoCards.jl and Literate.jl.

+)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/customization/legend/index.html b/previews/PR593/gallery/gallery/customization/legend/index.html index a1884e8de..d5efa1edf 100644 --- a/previews/PR593/gallery/gallery/customization/legend/index.html +++ b/previews/PR593/gallery/gallery/customization/legend/index.html @@ -25,4 +25,4 @@ mapping(:x, :y => y -> y + 5, group = :group => nonnumeric) * visual(Scatter, markersize = 3, label = "Scatter", legend = (; markersize = 12)) -draw(lin + sca)


This page was generated using DemoCards.jl and Literate.jl.

+draw(lin + sca)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/data manipulations/assets/new_columns_on_the_fly.png b/previews/PR593/gallery/gallery/data manipulations/assets/new_columns_on_the_fly.png index 7d335d2d7..f76582c98 100644 Binary files a/previews/PR593/gallery/gallery/data manipulations/assets/new_columns_on_the_fly.png and b/previews/PR593/gallery/gallery/data manipulations/assets/new_columns_on_the_fly.png differ diff --git a/previews/PR593/gallery/gallery/data manipulations/assets/pregrouped_data.png b/previews/PR593/gallery/gallery/data manipulations/assets/pregrouped_data.png index 242ea366b..28014b1d2 100644 Binary files a/previews/PR593/gallery/gallery/data manipulations/assets/pregrouped_data.png and b/previews/PR593/gallery/gallery/data manipulations/assets/pregrouped_data.png differ diff --git a/previews/PR593/gallery/gallery/data manipulations/assets/wide_data.png b/previews/PR593/gallery/gallery/data manipulations/assets/wide_data.png index 137a5d4a7..d04ac4131 100644 Binary files a/previews/PR593/gallery/gallery/data manipulations/assets/wide_data.png and b/previews/PR593/gallery/gallery/data manipulations/assets/wide_data.png differ diff --git a/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly-3.svg b/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly-3.svg index a5378c025..ab3efc22b 100644 --- a/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly-3.svg +++ b/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly-3.svg @@ -2,414 +2,429 @@ - + - + - + - + - + - - - - - - - + - + - + - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - + - + - + - + - + + + + + + + + + + - + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - + + + + + + + + + diff --git a/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly-5.svg b/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly-5.svg index 5d86fa2fa..61c95c94b 100644 --- a/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly-5.svg +++ b/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly-5.svg @@ -2,497 +2,441 @@ - + - - - - - - - - - - + - + - + + + + - - + + - + - + - + - + + + + - + - + - - + + - - - - - + + - + - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly/index.html b/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly/index.html index b2d7efe4a..e2f7852e3 100644 --- a/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly/index.html +++ b/previews/PR593/gallery/gallery/data manipulations/new_columns_on_the_fly/index.html @@ -6,4 +6,4 @@ plt = data(df) * layers * mapping(:x => (x -> x^2) => L"x^2", :y => L"This variable is called $y$") fg = draw(plt)

Use a Tuple to pass combine several columns into a unique operation.

plt = data(df) * layers * mapping(:x, (:x, :y, :z) => (+) => L"the new variable $x + y + z$", layout=:c)
-fg = draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/data manipulations/no_data/index.html b/previews/PR593/gallery/gallery/data manipulations/no_data/index.html index b9c6d1ca7..f3b614ecc 100644 --- a/previews/PR593/gallery/gallery/data manipulations/no_data/index.html +++ b/previews/PR593/gallery/gallery/data manipulations/no_data/index.html @@ -9,4 +9,4 @@ mapping([20, 28, 51], color = "marker" => scale(:secondary)) * visual(VLines, linestyle = :dash) -fg = draw(plt, scales(secondary = (; palette = [:gray80])))


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(plt, scales(secondary = (; palette = [:gray80])))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-3.svg b/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-3.svg index cbe1eb6f9..6bb4d9214 100644 --- a/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-3.svg +++ b/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-3.svg @@ -2,95 +2,92 @@ - + - + - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -98,147 +95,143 @@ - - - - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-4.svg b/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-4.svg index eeaf64a85..8924ef3a7 100644 --- a/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-4.svg +++ b/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-4.svg @@ -2,101 +2,104 @@ - + - + - + - + - + - - - - + - + - + - - + + - + - + + + + - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -104,152 +107,156 @@ - + + + + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-5.svg b/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-5.svg index 33f533c7a..754a43458 100644 --- a/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-5.svg +++ b/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-5.svg @@ -2,37 +2,34 @@ - + - + - + - - - - + - + - + - + - + - + - + @@ -40,108 +37,104 @@ - - - - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + diff --git a/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-6.svg b/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-6.svg index 0a5ff32f9..28bb17ac6 100644 --- a/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-6.svg +++ b/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data-6.svg @@ -2,34 +2,31 @@ - + - + - - - - - - - + - + - + - + - + - + + + + @@ -37,109 +34,105 @@ - - - - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -147,10 +140,10 @@ - + - + diff --git a/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data/index.html b/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data/index.html index 5e79a3f2c..70162b6eb 100644 --- a/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data/index.html +++ b/previews/PR593/gallery/gallery/data manipulations/pre_grouped_data/index.html @@ -12,4 +12,4 @@ draw(m)

m = pregrouped(x, [y z], color=dims(1) => renamer(["a", "b", "c"])) * visual(Scatter)
 draw(m)

m = pregrouped(x, [y z], color=["1" "2"])
 layers = visual(Scatter) + linear()
-fg = draw(m * layers)


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(m * layers)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/data manipulations/presorted_data/index.html b/previews/PR593/gallery/gallery/data manipulations/presorted_data/index.html index 2fa14fb2a..e1af32b50 100644 --- a/previews/PR593/gallery/gallery/data manipulations/presorted_data/index.html +++ b/previews/PR593/gallery/gallery/data manipulations/presorted_data/index.html @@ -15,4 +15,4 @@ fg = draw(spec)

We can also mark multiple variables as presorted, note how the order in the color legend shifts when we do the same for group:

spec = data(df) *
     mapping(:countries => presorted, :some_value, color = :group => presorted) *
     visual(BarPlot, direction = :x)
-draw(spec)


This page was generated using DemoCards.jl and Literate.jl.

+draw(spec)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/data manipulations/wide_data-10.svg b/previews/PR593/gallery/gallery/data manipulations/wide_data-10.svg index 165984646..fe3d2022a 100644 --- a/previews/PR593/gallery/gallery/data manipulations/wide_data-10.svg +++ b/previews/PR593/gallery/gallery/data manipulations/wide_data-10.svg @@ -2,584 +2,590 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - + + + + + - + - - + + - - + + - + - - - - + - + + + + - + - - - - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - + - - + + - - + + - + - + - + - + - + - + - + - + - - + + - + - + - + - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -590,1169 +596,1169 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR593/gallery/gallery/data manipulations/wide_data-3.svg b/previews/PR593/gallery/gallery/data manipulations/wide_data-3.svg index 602010c1c..bc8005b9d 100644 --- a/previews/PR593/gallery/gallery/data manipulations/wide_data-3.svg +++ b/previews/PR593/gallery/gallery/data manipulations/wide_data-3.svg @@ -2,144 +2,144 @@ - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - + - + - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -147,115 +147,115 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - + + + + + + + + + - - - - + + + + @@ -263,67 +263,67 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/data manipulations/wide_data-4.svg b/previews/PR593/gallery/gallery/data manipulations/wide_data-4.svg index a66ab9628..2725cb526 100644 --- a/previews/PR593/gallery/gallery/data manipulations/wide_data-4.svg +++ b/previews/PR593/gallery/gallery/data manipulations/wide_data-4.svg @@ -2,130 +2,148 @@ - + - + - + - + + + + + + + + + + + + + + + + - + - + - + - - + + - - + + - - + + + + + - + + + + - + - + - + - + - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -133,389 +151,409 @@ - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -526,91 +564,91 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/data manipulations/wide_data-7.svg b/previews/PR593/gallery/gallery/data manipulations/wide_data-7.svg index 674c95b7e..aa24326ee 100644 --- a/previews/PR593/gallery/gallery/data manipulations/wide_data-7.svg +++ b/previews/PR593/gallery/gallery/data manipulations/wide_data-7.svg @@ -2,407 +2,407 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - + - + - + - + - + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + + + + - + - + - - - - + - - - - - - - + - + - + - + - + - + - + - - + + - - + + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -412,911 +412,911 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/previews/PR593/gallery/gallery/data manipulations/wide_data-9.svg b/previews/PR593/gallery/gallery/data manipulations/wide_data-9.svg index 1ed8bb86a..e3361fa3e 100644 --- a/previews/PR593/gallery/gallery/data manipulations/wide_data-9.svg +++ b/previews/PR593/gallery/gallery/data manipulations/wide_data-9.svg @@ -2,416 +2,416 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - - - - - - - - + + - + - + - - - - + - + - - - - - - - - + + - + - - + + - + - - - - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - + + + + - + - + + + + - + + + + + + + - + + + + + + + + + + + + + - + + + + + + + - + - + - + - + - - - - + - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -421,991 +421,991 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR593/gallery/gallery/data manipulations/wide_data/index.html b/previews/PR593/gallery/gallery/data manipulations/wide_data/index.html index 3f64aa8c5..23e17f314 100644 --- a/previews/PR593/gallery/gallery/data manipulations/wide_data/index.html +++ b/previews/PR593/gallery/gallery/data manipulations/wide_data/index.html @@ -22,4 +22,4 @@ yvars = ["petal_length" "petal_width"] layers = linear() + visual(Scatter) plt = data(df) * layers * mapping(xvars, yvars, col=dims(1), row=dims(2)) -draw(plt)

Axes can be fully linked or fully unlinked

draw(plt, facet = (; linkxaxes = :all, linkyaxes = :all))

fg = draw(plt, facet = (; linkxaxes = :none, linkyaxes = :none))


This page was generated using DemoCards.jl and Literate.jl.

+draw(plt)

Axes can be fully linked or fully unlinked

draw(plt, facet = (; linkxaxes = :all, linkyaxes = :all))

fg = draw(plt, facet = (; linkxaxes = :none, linkyaxes = :none))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/layout/faceting/index.html b/previews/PR593/gallery/gallery/layout/faceting/index.html index 8536b4cdc..81fb873ab 100644 --- a/previews/PR593/gallery/gallery/layout/faceting/index.html +++ b/previews/PR593/gallery/gallery/layout/faceting/index.html @@ -27,8 +27,8 @@ layers = data(df1) * visual(Scatter) + data(df2) * visual(Lines) fg = draw(layers * mapping(:x, :y, col=:i, row=:j))

Caveats

The faceting variable must be non-numeric. If the source is numeric, you can convert it with nonnumeric.

df = (x=rand(100), y=rand(100), l=rand([1, 2, 3, 4, 5], 100))
 plt = data(df) * mapping(:x, :y, layout=:l => nonnumeric)
-draw(plt)

Pagination

If you have too many facets for one figure, you can use paginate to split the data into several subsets given a maximum number of plots per layout, row or column.

Note that pagination is considered an experimental feature. In the current implementation, scales and layouts are not synchronized across pages. This means that, e.g., linked limits on one page are not influenced by limits of other pages. The exact synchronization behavior can be subject to change in non-breaking versions.

df = (x=rand(500), y=rand(500), l=rand(["a", "b", "c", "d", "e", "f", "g", "h"], 500))
+draw(plt)

Pagination

If you have too many facets for one figure, you can use paginate to split the data into several subsets given a maximum number of plots per layout, row or column.

Scales are synchronized across pages. Note, however, that linked axis limits are currently not synchronized across pages. The exact synchronization behavior can be subject to change in non-breaking versions.

df = (x=rand(500), y=rand(500), l=rand(["a", "b", "c", "d", "e", "f", "g", "h"], 500))
 plt = data(df) * mapping(:x, :y, layout=:l)
-pag = paginate(plt, layout = 4)
PaginatedLayers with 2 entries (layout = 4)

The object returned from draw will be a Vector{FigureGrid}.

figuregrids = draw(pag)
2-element Vector{AlgebraOfGraphics.FigureGrid}:
+pag = paginate(plt, layout = 4)
Pagination with 2 entries (layout = 4)

The object returned from draw will be a Vector{FigureGrid}.

figuregrids = draw(pag)
2-element Vector{AlgebraOfGraphics.FigureGrid}:
  FigureGrid()
- FigureGrid()

You can either extract single figures from this vector...

figuregrids[1]

or use draw with an optional second argument specifying the index of the page to draw.

draw(pag, 2)


This page was generated using DemoCards.jl and Literate.jl.

+ FigureGrid()

You can either extract single figures from this vector...

figuregrids[1]

or use draw with an optional second argument specifying the index of the page to draw.

draw(pag, 2)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/layout/nested_layouts/index.html b/previews/PR593/gallery/gallery/layout/nested_layouts/index.html index cb292e95f..30ba6768a 100644 --- a/previews/PR593/gallery/gallery/layout/nested_layouts/index.html +++ b/previews/PR593/gallery/gallery/layout/nested_layouts/index.html @@ -42,4 +42,4 @@ grid = draw!(ax2, plt) legend!(f[1, 3], grid) -f


This page was generated using DemoCards.jl and Literate.jl.

+f


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/scales/assets/custom_scales.png b/previews/PR593/gallery/gallery/scales/assets/custom_scales.png index 497d02b5f..0f067e9d5 100644 Binary files a/previews/PR593/gallery/gallery/scales/assets/custom_scales.png and b/previews/PR593/gallery/gallery/scales/assets/custom_scales.png differ diff --git a/previews/PR593/gallery/gallery/scales/assets/discrete_scales.png b/previews/PR593/gallery/gallery/scales/assets/discrete_scales.png index 7d9858e80..91eb8bb12 100644 Binary files a/previews/PR593/gallery/gallery/scales/assets/discrete_scales.png and b/previews/PR593/gallery/gallery/scales/assets/discrete_scales.png differ diff --git a/previews/PR593/gallery/gallery/scales/continuous_scales/index.html b/previews/PR593/gallery/gallery/scales/continuous_scales/index.html index 4e8fa15ff..19cc26c59 100644 --- a/previews/PR593/gallery/gallery/scales/continuous_scales/index.html +++ b/previews/PR593/gallery/gallery/scales/continuous_scales/index.html @@ -25,4 +25,4 @@ :x, :y => "y", ) * visual(Lines) -fg = draw(plt, axis=(yscale=log,))


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(plt, axis=(yscale=log,))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/scales/custom_scales-5.svg b/previews/PR593/gallery/gallery/scales/custom_scales-5.svg index 435126aff..6734e611d 100644 --- a/previews/PR593/gallery/gallery/scales/custom_scales-5.svg +++ b/previews/PR593/gallery/gallery/scales/custom_scales-5.svg @@ -2,82 +2,82 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -85,853 +85,853 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - - - - - - - - + + + - - - + + + + + + + + - - + + - - + + + + + + + - - + + + + - - - - - - - - - - + + + + + + + + + + + + + + + - - - - + + - - - + + + + - - - - - - + + + + + + + + + - - - + - - - - - - - - - - - - - - - + + + + + + + + + - - - - + + + - - - - - - - + + + + - + + + - - + + + + - + - - - - + + + - - - - - - - - - + + + - - - + + + + + + + + - - + + - - + + + + + + + - - + + + + - - - - - - - - - - + + + + + + + + + + + + + + + - - - - + + - - - + + + + - - - - - - + + + + + + + + + - - - + - - - - - - - - - - - - - - - + + + + + + + + + - - - - + + + - - - - - - - + + + + - + + + - - + + + + - + - - - - + + + + + + + - - - - - - + + + + + - - - - + + + - - - - - - - - - + - + + + + - - - - - - + + + + - - + + + + - - - - - + + - - - + + + - - - + + + + - - + + + - + - - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - + + - - + + - - - - - - + + + + + + + - - - - - - + + + + + - - - - + + + - - - - - - - - - + - + + + + - - - - - - + + + + - - + + + + - - - - - + + - - - + + + - - - + + + + - - + + + - + - - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - + + - - + + - - - - - - - - + + + + - + + + + - - - - - - - - - - - + + + + + + - - - + + - + + + + - - - - - + + + + - - - + + + + + + + + + - - - - - - - - - + + + + + + + + - - - - - - + + + + - - + + + + - + - + - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - + + - - - - - + + + - + + + + - - - - - - - - - - - + + + + + + - - - + + - + + + + - - - - - + + + + - - - + + + + + + + + + - - - - - - - - - + + + + + + + + - - - - - - + + + + - - + + + + - + - + - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - + + - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - + + + + + + - - + - - - - - + + + - - - + + + - - + + - - - - - - - - - + + + + + - + + - - - - + + - - - + + + + - - - - + + - - - - + + + + - - - + + - + + + + - - - - - + + + + + + + + - + + + + + + + + + - - - - - + + + + - - + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - + + + + + + - - + - - - - - + + + - - - + + + - - + + - - - - - - - - - + + + + + - + + - - - - + + - - - + + + + - - - - + + - - - - + + + + - - - + + - + + + + - - - - - + + + + + + + + - + + + + + + + + + - - - - - + + + + - - + + + + @@ -949,64 +949,64 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/scales/custom_scales-7.svg b/previews/PR593/gallery/gallery/scales/custom_scales-7.svg index fbfbbd488..fefcfea89 100644 --- a/previews/PR593/gallery/gallery/scales/custom_scales-7.svg +++ b/previews/PR593/gallery/gallery/scales/custom_scales-7.svg @@ -2,70 +2,61 @@ - + - + - + - + - - - - + - + - + - + - - + + - + - - - - + - - - - + - + - + - + - + - + - + - + @@ -73,189 +64,189 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/scales/custom_scales-9.svg b/previews/PR593/gallery/gallery/scales/custom_scales-9.svg index 12a698a07..59b513466 100644 --- a/previews/PR593/gallery/gallery/scales/custom_scales-9.svg +++ b/previews/PR593/gallery/gallery/scales/custom_scales-9.svg @@ -2,76 +2,79 @@ - + - + - + - + - - + + - + - + + + + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + @@ -79,271 +82,271 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -353,31 +356,31 @@ - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/scales/custom_scales/index.html b/previews/PR593/gallery/gallery/scales/custom_scales/index.html index d8aeb2894..5b5f69ca8 100644 --- a/previews/PR593/gallery/gallery/scales/custom_scales/index.html +++ b/previews/PR593/gallery/gallery/scales/custom_scales/index.html @@ -25,4 +25,4 @@ z = rand(["a", "b", "c", "d", "e", "f", "g", "h"], 200) df = (; x, y, z) plt = data(df) * mapping(:x, :y, color=:z) -draw(plt, scales(Color = (; palette = from_continuous(:cividis))))


This page was generated using DemoCards.jl and Literate.jl.

+draw(plt, scales(Color = (; palette = from_continuous(:cividis))))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/scales/discrete_scales-10.svg b/previews/PR593/gallery/gallery/scales/discrete_scales-10.svg index f59c5ba9b..12a1bce21 100644 --- a/previews/PR593/gallery/gallery/scales/discrete_scales-10.svg +++ b/previews/PR593/gallery/gallery/scales/discrete_scales-10.svg @@ -2,61 +2,55 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - + - + - + - + @@ -64,93 +58,93 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - - - + + + diff --git a/previews/PR593/gallery/gallery/scales/discrete_scales-12.svg b/previews/PR593/gallery/gallery/scales/discrete_scales-12.svg index bedbd226e..a63a7d80a 100644 --- a/previews/PR593/gallery/gallery/scales/discrete_scales-12.svg +++ b/previews/PR593/gallery/gallery/scales/discrete_scales-12.svg @@ -2,79 +2,73 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - + - + - + - + @@ -82,125 +76,125 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + + - + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + + diff --git a/previews/PR593/gallery/gallery/scales/discrete_scales-14.svg b/previews/PR593/gallery/gallery/scales/discrete_scales-14.svg index bedbd226e..a63a7d80a 100644 --- a/previews/PR593/gallery/gallery/scales/discrete_scales-14.svg +++ b/previews/PR593/gallery/gallery/scales/discrete_scales-14.svg @@ -2,79 +2,73 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - + - + - + - + @@ -82,125 +76,125 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + + - + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + + diff --git a/previews/PR593/gallery/gallery/scales/discrete_scales-16.svg b/previews/PR593/gallery/gallery/scales/discrete_scales-16.svg index ff6135f0a..cb370a684 100644 --- a/previews/PR593/gallery/gallery/scales/discrete_scales-16.svg +++ b/previews/PR593/gallery/gallery/scales/discrete_scales-16.svg @@ -2,70 +2,61 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - + @@ -73,115 +64,102 @@ - - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + diff --git a/previews/PR593/gallery/gallery/scales/discrete_scales-17.svg b/previews/PR593/gallery/gallery/scales/discrete_scales-17.svg index c18c600d9..0a5b7d643 100644 --- a/previews/PR593/gallery/gallery/scales/discrete_scales-17.svg +++ b/previews/PR593/gallery/gallery/scales/discrete_scales-17.svg @@ -2,70 +2,61 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - + @@ -73,115 +64,102 @@ - - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + diff --git a/previews/PR593/gallery/gallery/scales/discrete_scales-5.svg b/previews/PR593/gallery/gallery/scales/discrete_scales-5.svg index 5008582ad..411ef4daa 100644 --- a/previews/PR593/gallery/gallery/scales/discrete_scales-5.svg +++ b/previews/PR593/gallery/gallery/scales/discrete_scales-5.svg @@ -2,46 +2,40 @@ - + - + - + - + - + - + - + - + - - - - - - - + - + - + - + @@ -49,71 +43,71 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - - - + + + diff --git a/previews/PR593/gallery/gallery/scales/discrete_scales-6.svg b/previews/PR593/gallery/gallery/scales/discrete_scales-6.svg index 6331db046..9bfb1a455 100644 --- a/previews/PR593/gallery/gallery/scales/discrete_scales-6.svg +++ b/previews/PR593/gallery/gallery/scales/discrete_scales-6.svg @@ -2,79 +2,73 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - + - + - + - + @@ -82,116 +76,116 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - - - + + + diff --git a/previews/PR593/gallery/gallery/scales/discrete_scales-8.svg b/previews/PR593/gallery/gallery/scales/discrete_scales-8.svg index 6331db046..9bfb1a455 100644 --- a/previews/PR593/gallery/gallery/scales/discrete_scales-8.svg +++ b/previews/PR593/gallery/gallery/scales/discrete_scales-8.svg @@ -2,79 +2,73 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - + - + - + - + @@ -82,116 +76,116 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - - - + + + diff --git a/previews/PR593/gallery/gallery/scales/discrete_scales/index.html b/previews/PR593/gallery/gallery/scales/discrete_scales/index.html index 4dac6ff23..a36f970b5 100644 --- a/previews/PR593/gallery/gallery/scales/discrete_scales/index.html +++ b/previews/PR593/gallery/gallery/scales/discrete_scales/index.html @@ -36,4 +36,4 @@ draw(plt, scales(X = (; categories = cats -> initialed.(sort(cats; by = name -> split(name)[2])) -)))


This page was generated using DemoCards.jl and Literate.jl.

+)))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/scales/dodging/index.html b/previews/PR593/gallery/gallery/scales/dodging/index.html index 118790bea..4a18010a1 100644 --- a/previews/PR593/gallery/gallery/scales/dodging/index.html +++ b/previews/PR593/gallery/gallery/scales/dodging/index.html @@ -22,4 +22,4 @@ draw!(f[2, 1], plt3, scales(DodgeX = (; width = 0.5)); axis = kw(title = "DodgeX = (; width = 0.5)")) draw!(f[3, 1], plt3, scales(DodgeX = (; width = 1.0)); axis = (; title = "DodgeX = (; width = 1.0)")) -f


This page was generated using DemoCards.jl and Literate.jl.

+f


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/scales/legend_merging/index.html b/previews/PR593/gallery/gallery/scales/legend_merging/index.html index 631d6f572..4123016de 100644 --- a/previews/PR593/gallery/gallery/scales/legend_merging/index.html +++ b/previews/PR593/gallery/gallery/scales/legend_merging/index.html @@ -12,4 +12,4 @@ layers = visual(Lines) + visual(Scatter) * mapping(marker = :grp) plt = data(df) * layers * mapping(:x, :y, color = :grp) -fg = draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/scales/multiple_color_scales-5.svg b/previews/PR593/gallery/gallery/scales/multiple_color_scales-5.svg index 541117ffd..0de27f7f8 100644 --- a/previews/PR593/gallery/gallery/scales/multiple_color_scales-5.svg +++ b/previews/PR593/gallery/gallery/scales/multiple_color_scales-5.svg @@ -2,664 +2,664 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -760,52 +760,52 @@ - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -824,13 +824,13 @@ - + - + - + diff --git a/previews/PR593/gallery/gallery/scales/multiple_color_scales/index.html b/previews/PR593/gallery/gallery/scales/multiple_color_scales/index.html index 6f0e3aa00..8069c7cb4 100644 --- a/previews/PR593/gallery/gallery/scales/multiple_color_scales/index.html +++ b/previews/PR593/gallery/gallery/scales/multiple_color_scales/index.html @@ -7,4 +7,4 @@ df = (; x, y, ŷ, z, c) layers = mapping(:y, color=:z) * visual(Lines) + mapping(:ŷ => "y", color=:c) plt = data(df) * mapping(:x) * layers -fg = draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/scales/prescaled_data/index.html b/previews/PR593/gallery/gallery/scales/prescaled_data/index.html index e9f7f31eb..ab31818de 100644 --- a/previews/PR593/gallery/gallery/scales/prescaled_data/index.html +++ b/previews/PR593/gallery/gallery/scales/prescaled_data/index.html @@ -12,4 +12,4 @@ label = rand(["a", "b"], 100) df = (; x, y, label) plt = data(df) * mapping(:x, :y, text=:label => verbatim) * visual(Makie.Text) -fg = draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/scales/secondary_scales/index.html b/previews/PR593/gallery/gallery/scales/secondary_scales/index.html index c96180cfb..ad0e5cd9e 100644 --- a/previews/PR593/gallery/gallery/scales/secondary_scales/index.html +++ b/previews/PR593/gallery/gallery/scales/secondary_scales/index.html @@ -19,4 +19,4 @@ secondary = (; palette = [:gray70, :gray30]) ); legend = (; order = [[:Color, :secondary] => "Legend"]) -)


This page was generated using DemoCards.jl and Literate.jl.

+)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/scales/split_scales_facet-6.svg b/previews/PR593/gallery/gallery/scales/split_scales_facet-6.svg index f391edf7c..9c17104d8 100644 --- a/previews/PR593/gallery/gallery/scales/split_scales_facet-6.svg +++ b/previews/PR593/gallery/gallery/scales/split_scales_facet-6.svg @@ -2,244 +2,244 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -247,70 +247,70 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -322,103 +322,103 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -427,58 +427,58 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -630,82 +630,82 @@ - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/gallery/gallery/scales/split_scales_facet/index.html b/previews/PR593/gallery/gallery/scales/split_scales_facet/index.html index dade8d649..33353894f 100644 --- a/previews/PR593/gallery/gallery/scales/split_scales_facet/index.html +++ b/previews/PR593/gallery/gallery/scales/split_scales_facet/index.html @@ -43,4 +43,4 @@ spec = dat * (layer1 + layer2 + layer3 + layer4) -fg = draw(spec, scales(Row = (; show_labels = false), Col = (; show_labels = false)))


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(spec, scales(Row = (; show_labels = false), Col = (; show_labels = false)))


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/statistical analyses/assets/density_plots.png b/previews/PR593/gallery/gallery/statistical analyses/assets/density_plots.png index d3f840e9c..97528e4bd 100644 Binary files a/previews/PR593/gallery/gallery/statistical analyses/assets/density_plots.png and b/previews/PR593/gallery/gallery/statistical analyses/assets/density_plots.png differ diff --git a/previews/PR593/gallery/gallery/statistical analyses/assets/histograms.png b/previews/PR593/gallery/gallery/statistical analyses/assets/histograms.png index 1c4e4d3ff..24938c5e4 100644 Binary files a/previews/PR593/gallery/gallery/statistical analyses/assets/histograms.png and b/previews/PR593/gallery/gallery/statistical analyses/assets/histograms.png differ diff --git a/previews/PR593/gallery/gallery/statistical analyses/assets/regression_plots.png b/previews/PR593/gallery/gallery/statistical analyses/assets/regression_plots.png index d6d7febd5..befadbedf 100644 Binary files a/previews/PR593/gallery/gallery/statistical analyses/assets/regression_plots.png and b/previews/PR593/gallery/gallery/statistical analyses/assets/regression_plots.png differ diff --git a/previews/PR593/gallery/gallery/statistical analyses/density_plots-3.svg b/previews/PR593/gallery/gallery/statistical analyses/density_plots-3.svg index 3595fad07..88fe7e558 100644 --- a/previews/PR593/gallery/gallery/statistical analyses/density_plots-3.svg +++ b/previews/PR593/gallery/gallery/statistical analyses/density_plots-3.svg @@ -2,73 +2,61 @@ - + - + - + - + - - - - + - + - + - + - + - - - - + - - - - - + + - + - + - - + + - + - + - + - - - - + - + @@ -76,88 +64,88 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - + + + + + + + - - - + + + - + - + - + diff --git a/previews/PR593/gallery/gallery/statistical analyses/density_plots/index.html b/previews/PR593/gallery/gallery/statistical analyses/density_plots/index.html index d6f98a85f..8ca3d18bf 100644 --- a/previews/PR593/gallery/gallery/statistical analyses/density_plots/index.html +++ b/previews/PR593/gallery/gallery/statistical analyses/density_plots/index.html @@ -6,4 +6,4 @@ plt = data(df) * mapping(:x, color=:c) * density(bandwidth=0.5) fg = draw(plt)

df = (x=randn(1000), c=rand(["a", "b"], 1000))
 plt = data(df) * mapping(:x, color=:c) * density(bandwidth=0.5) * visual(orientation=:vertical)
-"Not yet supported" # hide
"Not yet supported"

This page was generated using DemoCards.jl and Literate.jl.

+"Not yet supported" # hide
"Not yet supported"

This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/statistical analyses/histograms-3.svg b/previews/PR593/gallery/gallery/statistical analyses/histograms-3.svg index cd4b95583..e69f62746 100644 --- a/previews/PR593/gallery/gallery/statistical analyses/histograms-3.svg +++ b/previews/PR593/gallery/gallery/statistical analyses/histograms-3.svg @@ -2,73 +2,70 @@ - + - + - + + + + - + - + - + - + - + - + - + - + - + - + - + - - - - + - - - - - + + - - + + - + - + - + - + @@ -76,110 +73,110 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + diff --git a/previews/PR593/gallery/gallery/statistical analyses/histograms-4.svg b/previews/PR593/gallery/gallery/statistical analyses/histograms-4.svg index 261da751e..ab261410c 100644 --- a/previews/PR593/gallery/gallery/statistical analyses/histograms-4.svg +++ b/previews/PR593/gallery/gallery/statistical analyses/histograms-4.svg @@ -2,79 +2,85 @@ - + - + - + - - - - + - + - + + + + - + - + - - + + - + - + - + - + - + - + - + + + + - + - - + + - + - + + + + - + - + - + - + @@ -82,132 +88,135 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - + - + - + diff --git a/previews/PR593/gallery/gallery/statistical analyses/histograms-5.svg b/previews/PR593/gallery/gallery/statistical analyses/histograms-5.svg index 43f020fd9..0c52a16c5 100644 --- a/previews/PR593/gallery/gallery/statistical analyses/histograms-5.svg +++ b/previews/PR593/gallery/gallery/statistical analyses/histograms-5.svg @@ -2,453 +2,509 @@ - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + + + + + + + - + + + + + + + - + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - - + + - - - + + + + + + + + - - + + diff --git a/previews/PR593/gallery/gallery/statistical analyses/histograms/index.html b/previews/PR593/gallery/gallery/statistical analyses/histograms/index.html index 9c02e8bbd..b0cd2d3d1 100644 --- a/previews/PR593/gallery/gallery/statistical analyses/histograms/index.html +++ b/previews/PR593/gallery/gallery/statistical analyses/histograms/index.html @@ -8,4 +8,4 @@ plt = data(df) * mapping(:x, color=:c, stack=:c) * histogram(bins=20) fg = draw(plt)

df = (x=rand(1000), y=randn(1000))
 plt = data(df) * mapping(:x, :y) * histogram(bins=20)
-draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

+draw(plt)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/gallery/statistical analyses/regression_plots-3.svg b/previews/PR593/gallery/gallery/statistical analyses/regression_plots-3.svg index f98174068..02cef8b07 100644 --- a/previews/PR593/gallery/gallery/statistical analyses/regression_plots-3.svg +++ b/previews/PR593/gallery/gallery/statistical analyses/regression_plots-3.svg @@ -2,225 +2,202 @@ - + - + - + - + - - - - + - + - + - + - - - - + - + + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR593/gallery/gallery/statistical analyses/regression_plots-4.svg b/previews/PR593/gallery/gallery/statistical analyses/regression_plots-4.svg index 969a0c938..28aaa3be1 100644 --- a/previews/PR593/gallery/gallery/statistical analyses/regression_plots-4.svg +++ b/previews/PR593/gallery/gallery/statistical analyses/regression_plots-4.svg @@ -2,52 +2,46 @@ - + - + - + - + - + - + - + - - - - - - - + - + + + + - + - + - - - - + - + @@ -55,165 +49,165 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/previews/PR593/gallery/gallery/statistical analyses/regression_plots/index.html b/previews/PR593/gallery/gallery/statistical analyses/regression_plots/index.html index b5c592224..6a3d0c102 100644 --- a/previews/PR593/gallery/gallery/statistical analyses/regression_plots/index.html +++ b/previews/PR593/gallery/gallery/statistical analyses/regression_plots/index.html @@ -11,4 +11,4 @@ df = (; x, y) xy = data(df) * mapping(:x, :y) layers = smooth() + visual(Scatter) -fg = draw(layers * xy)


This page was generated using DemoCards.jl and Literate.jl.

+fg = draw(layers * xy)


This page was generated using DemoCards.jl and Literate.jl.

diff --git a/previews/PR593/gallery/index.html b/previews/PR593/gallery/index.html index f2bea88cf..7bba03219 100644 --- a/previews/PR593/gallery/index.html +++ b/previews/PR593/gallery/index.html @@ -335,4 +335,4 @@

card image

- + diff --git a/previews/PR593/generated/analyses/7e6fa5e8.svg b/previews/PR593/generated/analyses/63cd6b70.svg similarity index 91% rename from previews/PR593/generated/analyses/7e6fa5e8.svg rename to previews/PR593/generated/analyses/63cd6b70.svg index cbbad3d36..35153c090 100644 --- a/previews/PR593/generated/analyses/7e6fa5e8.svg +++ b/previews/PR593/generated/analyses/63cd6b70.svg @@ -2,130 +2,130 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -134,19 +134,19 @@ - - + + - + - + - + - + diff --git a/previews/PR593/generated/analyses/20a0d47b.svg b/previews/PR593/generated/analyses/c9a36d84.svg similarity index 92% rename from previews/PR593/generated/analyses/20a0d47b.svg rename to previews/PR593/generated/analyses/c9a36d84.svg index 032dfe4da..d6db44b14 100644 --- a/previews/PR593/generated/analyses/20a0d47b.svg +++ b/previews/PR593/generated/analyses/c9a36d84.svg @@ -2,87 +2,87 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -94,22 +94,22 @@ - + - + - + - + - + - + @@ -121,13 +121,13 @@ - + - + - + @@ -139,51 +139,51 @@ - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/generated/analyses/a0c0082a.svg b/previews/PR593/generated/analyses/ecd630f4.svg similarity index 70% rename from previews/PR593/generated/analyses/a0c0082a.svg rename to previews/PR593/generated/analyses/ecd630f4.svg index cbc8c6101..5beaed4e0 100644 --- a/previews/PR593/generated/analyses/a0c0082a.svg +++ b/previews/PR593/generated/analyses/ecd630f4.svg @@ -1,1400 +1,1400 @@ - + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + @@ -1446,6645 +1446,6645 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - + diff --git a/previews/PR593/generated/analyses/8d57166f.svg b/previews/PR593/generated/analyses/fffe0656.svg similarity index 91% rename from previews/PR593/generated/analyses/8d57166f.svg rename to previews/PR593/generated/analyses/fffe0656.svg index a69db20a5..a2533fca2 100644 --- a/previews/PR593/generated/analyses/8d57166f.svg +++ b/previews/PR593/generated/analyses/fffe0656.svg @@ -2,295 +2,295 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -304,19 +304,19 @@ - - + + - + - + - + - + diff --git a/previews/PR593/generated/analyses/index.html b/previews/PR593/generated/analyses/index.html index 2fa97d4d5..e1445a318 100644 --- a/previews/PR593/generated/analyses/index.html +++ b/previews/PR593/generated/analyses/index.html @@ -1,5 +1,5 @@ -Analyses · Algebra of Graphics

Analyses

Histogram

AlgebraOfGraphics.histogramFunction
histogram(; bins=automatic, datalimits=automatic, closed=:left, normalization=:none)

Compute a histogram.

The attribute bins can be an Integer, an AbstractVector (in particular, a range), or a Tuple of either integers or abstract vectors (useful for 2- or 3-dimensional histograms). When bins is an Integer, it denotes the approximate number of equal-width intervals used to compute the histogram. In that case, the range covered by the intervals is defined by datalimits (it defaults to the extrema of the whole data). The keyword argument datalimits can be a tuple of two values, e.g. datalimits=(0, 10), or a function to be applied group by group, e.g. datalimits=extrema. When bins is an AbstractVector, it denotes the intervals directly.

closed determines whether the the intervals are closed to the left or to the right.

The histogram can be normalized by setting normalization. Possible values are:

  • :pdf: Normalize by sum of weights and bin sizes. Resulting histogram has norm 1 and represents a PDF.
  • :density: Normalize by bin sizes only. Resulting histogram represents count density of input and does not have norm 1.
  • :probability: Normalize by sum of weights only. Resulting histogram represents the fraction of probability mass for each bin and does not have norm 1.
  • :none: Do not normalize.

Weighted data is supported via the keyword weights (passed to mapping).

Note

Normalizations are computed withing groups. For example, in the case of normalization=:pdf, sum of weights within each group will be equal to 1.

source
using AlgebraOfGraphics, CairoMakie
+Analyses · Algebra of Graphics

Analyses

Histogram

AlgebraOfGraphics.histogramFunction
histogram(; bins=automatic, datalimits=automatic, closed=:left, normalization=:none)

Compute a histogram.

The attribute bins can be an Integer, an AbstractVector (in particular, a range), or a Tuple of either integers or abstract vectors (useful for 2- or 3-dimensional histograms). When bins is an Integer, it denotes the approximate number of equal-width intervals used to compute the histogram. In that case, the range covered by the intervals is defined by datalimits (it defaults to the extrema of the whole data). The keyword argument datalimits can be a tuple of two values, e.g. datalimits=(0, 10), or a function to be applied group by group, e.g. datalimits=extrema. When bins is an AbstractVector, it denotes the intervals directly.

closed determines whether the the intervals are closed to the left or to the right.

The histogram can be normalized by setting normalization. Possible values are:

  • :pdf: Normalize by sum of weights and bin sizes. Resulting histogram has norm 1 and represents a PDF.
  • :density: Normalize by bin sizes only. Resulting histogram represents count density of input and does not have norm 1.
  • :probability: Normalize by sum of weights only. Resulting histogram represents the fraction of probability mass for each bin and does not have norm 1.
  • :none: Do not normalize.

Weighted data is supported via the keyword weights (passed to mapping).

Note

Normalizations are computed withing groups. For example, in the case of normalization=:pdf, sum of weights within each group will be equal to 1.

source
using AlgebraOfGraphics, CairoMakie
 set_aog_theme!()
 
 df = (x=randn(5000), y=randn(5000), z=rand(["a", "b", "c"], 5000))
@@ -9,7 +9,7 @@
 draw(specs)
Example block output
specs = data(df) *
     mapping((:x, :z) => ((x, z) -> x + 5 * (z == "b")) => "new x", col=:z) *
     histogram(datalimits=extrema, bins=20)
-draw(specs, facet=(linkxaxes=:minimal,))
Example block output
data(df) * mapping(:x, :y, layout=:z) * histogram(bins=15) |> draw
Example block output

Density

AlgebraOfGraphics.densityFunction
density(; datalimits=automatic, kernel=automatic, bandwidth=automatic, npoints=200)

Fit a kernel density estimation of data.

Here, datalimits specifies the range for which the density should be calculated (it defaults to the extrema of the whole data). The keyword argument datalimits can be a tuple of two values, e.g. datalimits=(0, 10), or a function to be applied group by group, e.g. datalimits=extrema. The keyword arguments kernel and bandwidth are forwarded to KernelDensity.kde. npoints is the number of points used by Makie to draw the line

Weighted data is supported via the keyword weights (passed to mapping).

source
df = (x=randn(5000), y=randn(5000), z=rand(["a", "b", "c", "d"], 5000))
+draw(specs, facet=(linkxaxes=:minimal,))
Example block output
data(df) * mapping(:x, :y, layout=:z) * histogram(bins=15) |> draw
Example block output

Density

AlgebraOfGraphics.densityFunction
density(; datalimits=automatic, kernel=automatic, bandwidth=automatic, npoints=200)

Fit a kernel density estimation of data.

Here, datalimits specifies the range for which the density should be calculated (it defaults to the extrema of the whole data). The keyword argument datalimits can be a tuple of two values, e.g. datalimits=(0, 10), or a function to be applied group by group, e.g. datalimits=extrema. The keyword arguments kernel and bandwidth are forwarded to KernelDensity.kde. npoints is the number of points used by Makie to draw the line

Weighted data is supported via the keyword weights (passed to mapping).

source
df = (x=randn(5000), y=randn(5000), z=rand(["a", "b", "c", "d"], 5000))
 specs = data(df) * mapping(:x, layout=:z) * AlgebraOfGraphics.density(datalimits=((-2.5, 2.5),))
 
 draw(specs)
Example block output
specs = data(df) *
@@ -18,37 +18,37 @@
 draw(specs, facet=(linkxaxes=:minimal,))
Example block output
data(df) * mapping(:x, :y, layout=:z) * AlgebraOfGraphics.density(npoints=50) |> draw
Example block output
specs = data(df) * mapping(:x, :y, layout=:z) *
     AlgebraOfGraphics.density(npoints=50) * visual(Surface)
 
-draw(specs, axis=(type=Axis3, zticks=0:0.1:0.2, limits=(nothing, nothing, (0, 0.2))))
Example block output

Frequency

df = (x=rand(["a", "b", "c"], 100), y=rand(["a", "b", "c"], 100), z=rand(["a", "b", "c"], 100))
+draw(specs, axis=(type=Axis3, zticks=0:0.1:0.2, limits=(nothing, nothing, (0, 0.2))))
Example block output

Frequency

df = (x=rand(["a", "b", "c"], 100), y=rand(["a", "b", "c"], 100), z=rand(["a", "b", "c"], 100))
 specs = data(df) * mapping(:x, layout=:z) * frequency()
 draw(specs)
Example block output
specs = data(df) * mapping(:x, layout=:z, color=:y, stack=:y) * frequency()
 draw(specs)
Example block output
specs = data(df) * mapping(:x, :y, layout=:z) * frequency()
-draw(specs)
Example block output

Expectation

df = (x=rand(["a", "b", "c"], 100), y=rand(["a", "b", "c"], 100), z=rand(100), c=rand(["a", "b", "c"], 100))
+draw(specs)
Example block output

Expectation

df = (x=rand(["a", "b", "c"], 100), y=rand(["a", "b", "c"], 100), z=rand(100), c=rand(["a", "b", "c"], 100))
 specs = data(df) * mapping(:x, :z, layout=:c) * expectation()
 draw(specs)
Example block output
specs = data(df) * mapping(:x, :z, layout=:c, color=:y, dodge=:y) * expectation()
 draw(specs)
Example block output
specs = data(df) * mapping(:x, :y, :z, layout=:c) * expectation()
-draw(specs)
Example block output

Linear

AlgebraOfGraphics.linearFunction
linear(; interval=automatic, level=0.95, dropcollinear=false, npoints=200)

Compute a linear fit of y ~ 1 + x. An optional named mapping weights determines the weights. Use interval to specify what type of interval the shaded band should represent, for a given coverage level (the default 0.95 equates alpha = 0.05). Valid values of interval are :confidence, to delimit the uncertainty of the predicted relationship, and :prediction, to delimit estimated bounds for new data points. Use interval = nothing to only compute the line fit, without any uncertainty estimate. By default, this analysis errors on singular (collinear) data. To avoid that, it is possible to set dropcollinear=true. npoints is the number of points used by Makie to draw the shaded band.

Weighted data is supported via the keyword weights (passed to mapping).

source
x = 1:0.05:10
+draw(specs)
Example block output

Linear

AlgebraOfGraphics.linearFunction
linear(; interval=automatic, level=0.95, dropcollinear=false, npoints=200)

Compute a linear fit of y ~ 1 + x. An optional named mapping weights determines the weights. Use interval to specify what type of interval the shaded band should represent, for a given coverage level (the default 0.95 equates alpha = 0.05). Valid values of interval are :confidence, to delimit the uncertainty of the predicted relationship, and :prediction, to delimit estimated bounds for new data points. Use interval = nothing to only compute the line fit, without any uncertainty estimate. By default, this analysis errors on singular (collinear) data. To avoid that, it is possible to set dropcollinear=true. npoints is the number of points used by Makie to draw the shaded band.

Weighted data is supported via the keyword weights (passed to mapping).

source
x = 1:0.05:10
 a = rand(1:7, length(x))
 y = 1.2 .* x .+ a .+ 0.5 .* randn.()
 df = (; x, y, a)
 specs = data(df) * mapping(:x, :y, color=:a => nonnumeric) * (linear() + visual(Scatter))
-draw(specs)
Example block output

Smoothing

AlgebraOfGraphics.smoothFunction
smooth(; span=0.75, degree=2, npoints=200)

Fit a loess model. span is the degree of smoothing, typically in [0,1]. Smaller values result in smaller local context in fitting. degree is the polynomial degree used in the loess model. npoints is the number of points used by Makie to draw the line

source
x = 1:0.05:10
+draw(specs)
Example block output

Smoothing

AlgebraOfGraphics.smoothFunction
smooth(; span=0.75, degree=2, npoints=200)

Fit a loess model. span is the degree of smoothing, typically in [0,1]. Smaller values result in smaller local context in fitting. degree is the polynomial degree used in the loess model. npoints is the number of points used by Makie to draw the line

source
x = 1:0.05:10
 a = rand(1:7, length(x))
 y = sin.(x) .+ a .+ 0.1 .* randn.()
 df = (; x, y, a)
 specs = data(df) * mapping(:x, :y, color=:a => nonnumeric) * (smooth() + visual(Scatter))
-draw(specs)
Example block output

Contours

AlgebraOfGraphics.contoursFunction
contours(; levels=5, kwargs...)

Create contour lines over the grid spanned over x and y by args 1 and 2 in the mapping, with height values z passed via arg 3.

You can pass the number of levels as an integer or a vector of levels. The levels are calculated across the whole z data if they are specified as an integer.

Note that visual(Contour) only works in a limited way with AlgebraOfGraphics since version 0.7, because the internal calculations it does are not compatible with the scale system. With visual(Contour), you can only have categorically-colored contours (for example to visualize contours of multiple categories). Alternatively, if you set the colormap attribute, you can get continuously-colored contours but the levels will not be known to AlgebraOfGraphics, so they won't be synchronized across facets and there will not be a colorbar.

All other keyword arguments are forwarded as attributes to the underlying Contour plot.

source
x = repeat(1:10, 10)
+draw(specs)
Example block output

Contours

AlgebraOfGraphics.contoursFunction
contours(; levels=5, kwargs...)

Create contour lines over the grid spanned over x and y by args 1 and 2 in the mapping, with height values z passed via arg 3.

You can pass the number of levels as an integer or a vector of levels. The levels are calculated across the whole z data if they are specified as an integer.

Note that visual(Contour) only works in a limited way with AlgebraOfGraphics since version 0.7, because the internal calculations it does are not compatible with the scale system. With visual(Contour), you can only have categorically-colored contours (for example to visualize contours of multiple categories). Alternatively, if you set the colormap attribute, you can get continuously-colored contours but the levels will not be known to AlgebraOfGraphics, so they won't be synchronized across facets and there will not be a colorbar.

All other keyword arguments are forwarded as attributes to the underlying Contour plot.

source
x = repeat(1:10, 10)
 y = repeat(11:20, inner = 10)
 z = sqrt.(x .* y)
 df = (; x, y, z)
 specs = data(df) * mapping(:x, :y, :z) * contours(levels = 8)
-draw(specs)
Example block output
x = repeat(1:10, 10)
+draw(specs)
Example block output
x = repeat(1:10, 10)
 y = repeat(11:20, inner = 10)
 z = sqrt.(x .* y)
 df = (; x, y, z)
 specs = data(df) * mapping(:x, :y, :z) * contours(levels = 8, labels = true)
-draw(specs)
Example block output

Filled Contours

AlgebraOfGraphics.filled_contoursFunction
filled_contours(; bands=automatic, levels=automatic)

Create filled contours over the grid spanned over x and y by args 1 and 2 in the mapping, with height values z passed via arg 3.

You can pass either the number of bands to bands or pass a vector of levels (the boundaries of the bands) to levels, but not both. The number of bands when levels is passed is length(levels) - 1. The levels are calculated across the whole z data if the number of bands is specified. If neither levels nor bands are specified, the default is bands = 10.

Note that visual(Contourf) does not work with AlgebraOfGraphics since version 0.7, because the internal binning it does is not compatible with the scale system.

source
x = repeat(1:10, 10)
+draw(specs)
Example block output

Filled Contours

AlgebraOfGraphics.filled_contoursFunction
filled_contours(; bands=automatic, levels=automatic)

Create filled contours over the grid spanned over x and y by args 1 and 2 in the mapping, with height values z passed via arg 3.

You can pass either the number of bands to bands or pass a vector of levels (the boundaries of the bands) to levels, but not both. The number of bands when levels is passed is length(levels) - 1. The levels are calculated across the whole z data if the number of bands is specified. If neither levels nor bands are specified, the default is bands = 10.

Note that visual(Contourf) does not work with AlgebraOfGraphics since version 0.7, because the internal binning it does is not compatible with the scale system.

source
x = repeat(1:10, 10)
 y = repeat(11:20, inner = 10)
 z = sqrt.(x .* y)
 df = (; x, y, z)
 specs = data(df) * mapping(:x, :y, :z) * filled_contours(levels = 3:2:15)
-draw(specs)
Example block output

This page was generated using Literate.jl.

+draw(specs)
Example block output

This page was generated using Literate.jl.

diff --git a/previews/PR593/generated/penguins/e5579890.svg b/previews/PR593/generated/penguins/0baa5274.svg similarity index 99% rename from previews/PR593/generated/penguins/e5579890.svg rename to previews/PR593/generated/penguins/0baa5274.svg index c95eee2b2..08fe2411f 100644 --- a/previews/PR593/generated/penguins/e5579890.svg +++ b/previews/PR593/generated/penguins/0baa5274.svg @@ -2,410 +2,410 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2908,49 +2908,49 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -5453,49 +5453,49 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -7998,147 +7998,147 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/generated/penguins/245e3e20.svg b/previews/PR593/generated/penguins/936b695a.svg similarity index 96% rename from previews/PR593/generated/penguins/245e3e20.svg rename to previews/PR593/generated/penguins/936b695a.svg index 9a9723881..c32ce80c4 100644 --- a/previews/PR593/generated/penguins/245e3e20.svg +++ b/previews/PR593/generated/penguins/936b695a.svg @@ -2,409 +2,409 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -745,61 +745,61 @@ - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -815,88 +815,88 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/generated/penguins/0e57e53a.svg b/previews/PR593/generated/penguins/e99dc106.svg similarity index 99% rename from previews/PR593/generated/penguins/0e57e53a.svg rename to previews/PR593/generated/penguins/e99dc106.svg index abd938fbd..d5d51d30f 100644 --- a/previews/PR593/generated/penguins/0e57e53a.svg +++ b/previews/PR593/generated/penguins/e99dc106.svg @@ -2,401 +2,401 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2899,49 +2899,49 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -5444,49 +5444,49 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -7989,135 +7989,135 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + diff --git a/previews/PR593/generated/penguins/index.html b/previews/PR593/generated/penguins/index.html index e0501359d..83026d601 100644 --- a/previews/PR593/generated/penguins/index.html +++ b/previews/PR593/generated/penguins/index.html @@ -31,7 +31,7 @@ plt = penguin_bill * layers * mapping(color = :species, col = :sex) draw(plt; axis = axis)Example block output

Smooth density plots

An alternative approach to understanding how two variables interact is to consider their joint probability density distribution (pdf).

using AlgebraOfGraphics: density
 plt = penguin_bill * density(npoints=50) * mapping(col = :species)
-draw(plt; axis = axis)
Example block output

The default colormap is multi-hue, but it is possible to pass single-hue colormaps as well. The color range is inferred from the data by default, but it can also be passed manually. Both settings are passed via scales to draw, because multiple plots can share the same colormap, so visual is not the appropriate place for this setting.

draw(plt, scales(Color = (; colormap = :grayC, colorrange = (0, 6))); axis = axis)
Example block output

We could also use a Contour plot instead:

axis = (width = 225, height = 225)
+draw(plt; axis = axis)
Example block output

The default colormap is multi-hue, but it is possible to pass single-hue colormaps as well. The color range is inferred from the data by default, but it can also be passed manually. Both settings are passed via scales to draw, because multiple plots can share the same colormap, so visual is not the appropriate place for this setting.

draw(plt, scales(Color = (; colormap = :grayC, colorrange = (0, 6))); axis = axis)
Example block output

We could also use a Contour plot instead:

axis = (width = 225, height = 225)
 layer = density() * visual(Contour)
 plt = penguin_bill * layer * mapping(color = :species)
 draw(plt; axis = axis)
Example block output

The data and the linear fit can also be added back to the plot:

layers = density() * visual(Contour) + linear() + mapping()
@@ -41,7 +41,7 @@
 draw(plt; axis = axis)
Example block output

Correlating three variables

We are now mostly up to speed with bill size, but we have not considered how it relates to other penguin features, such as their weight. For that, a possible approach is to use a continuous color on a gradient to denote weight and different marker shapes to denote species. Here we use group to split the data for the linear regression without adding any additional style.

body_mass = :body_mass_g => (t -> t / 1000) => "body mass (kg)"
 layers = linear() * mapping(group = :species) + mapping(color = body_mass, marker = :species)
 plt = penguin_bill * layers
-draw(plt; axis = axis)
Example block output
plt = penguin_bill * mapping(body_mass, color = :species, layout = :sex)
+draw(plt; axis = axis)
Example block output
plt = penguin_bill * mapping(body_mass, color = :species, layout = :sex)
 draw(plt; axis = axis)
Example block output

Note that static 3D plot can be misleading, as they only show one projection of 3D data. They are mostly useful when shown interactively.

Machine Learning

Finally, let us use Machine Learning techniques to build an automated penguin classifier!

We would like to investigate whether it is possible to predict the species of a penguin based on its bill size. To do so, we will use a standard classifier technique called Support-Vector Machine.

The strategy is quite simple. We split the data into training and testing subdatasets. We then train our classifier on the training dataset and use it to make predictions on the whole data. We then add the new columns obtained this way to the dataset and visually inspect how well the classifier performed in both training and testing.

using LIBSVM, Random
 
 # use approximately 80% of penguins for training
@@ -79,4 +79,4 @@
 draw(plt; axis = axis)
Example block output

Um, some of the penguins are indeed being misclassified... Let us try to understand why by adding an extra layer, which describes the density of the distributions of the three species.

pdflayer = density() * visual(Contour, colormap=Reverse(:grays)) * mapping(group = :species)
 layers = pdflayer + datalayer
 plt = penguin_bill * layers
-draw(plt; axis = axis)
Example block output

We can conclude that the classifier is doing a reasonable job: it is mostly making mistakes on outlier penguins.


This page was generated using Literate.jl.

+draw(plt; axis = axis)Example block output

We can conclude that the classifier is doing a reasonable job: it is mostly making mistakes on outlier penguins.


This page was generated using Literate.jl.

diff --git a/previews/PR593/generated/visual/6b2b6c7c.svg b/previews/PR593/generated/visual/b0875935.svg similarity index 99% rename from previews/PR593/generated/visual/6b2b6c7c.svg rename to previews/PR593/generated/visual/b0875935.svg index 080a003cb..a8da1d788 100644 --- a/previews/PR593/generated/visual/6b2b6c7c.svg +++ b/previews/PR593/generated/visual/b0875935.svg @@ -2,106 +2,106 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2603,52 +2603,52 @@ - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/generated/visual/b6334d43.svg b/previews/PR593/generated/visual/bfd21982.svg similarity index 99% rename from previews/PR593/generated/visual/b6334d43.svg rename to previews/PR593/generated/visual/bfd21982.svg index 6175ddfc2..8d21f0d31 100644 --- a/previews/PR593/generated/visual/b6334d43.svg +++ b/previews/PR593/generated/visual/bfd21982.svg @@ -2,106 +2,106 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2603,52 +2603,52 @@ - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/generated/visual/index.html b/previews/PR593/generated/visual/index.html index 46d215bf2..68e2f13eb 100644 --- a/previews/PR593/generated/visual/index.html +++ b/previews/PR593/generated/visual/index.html @@ -1,10 +1,10 @@ -Visual · Algebra of Graphics

Visual

AlgebraOfGraphics.visualFunction
visual(plottype; attributes...)

Create a Layer that will cause a plot spec multiplied with it to be visualized with plot type plottype, together with optional attributes.

The available plotting functions are documented here. Refer to plotting functions using upper CamelCase for visual's first argument (e.g. visual(Scatter), visual(BarPlot)). See the documentation of each plotting function to discover the available attributes. These attributes can be passed as additional keyword arguments to visual, or as part of the mapping you define.

The visual function can in principle be used for any plotting function that is defined using the @recipe macro from Makie. AlgebraOfGraphics just needs method definitions for aesthetic_mapping, which define what arguments of the plotting function map to which visual aesthetics. And for legend support, legend_elements must be overloaded for custom recipes as well, as Makie's default legend mechanism relies on instantiated plot objects, while AlgebraOfGraphics must go by the type and attributes alone.

Depending on its aesthetic_mapping, a plot type and its attributes may change certain semantics of a given data(...) * mapping(...) spec. For example, visual(BarPlot) will show mapping 1 on the x axis and 2 on the y axis, while visual(BarPlot, direction = :x) shows mapping 1 on y and 2 on x.

source

Examples

using AlgebraOfGraphics, CairoMakie
+Visual · Algebra of Graphics

Visual

AlgebraOfGraphics.visualFunction
visual(plottype; attributes...)

Create a Layer that will cause a plot spec multiplied with it to be visualized with plot type plottype, together with optional attributes.

The available plotting functions are documented here. Refer to plotting functions using upper CamelCase for visual's first argument (e.g. visual(Scatter), visual(BarPlot)). See the documentation of each plotting function to discover the available attributes. These attributes can be passed as additional keyword arguments to visual, or as part of the mapping you define.

The visual function can in principle be used for any plotting function that is defined using the @recipe macro from Makie. AlgebraOfGraphics just needs method definitions for aesthetic_mapping, which define what arguments of the plotting function map to which visual aesthetics. And for legend support, legend_elements must be overloaded for custom recipes as well, as Makie's default legend mechanism relies on instantiated plot objects, while AlgebraOfGraphics must go by the type and attributes alone.

Depending on its aesthetic_mapping, a plot type and its attributes may change certain semantics of a given data(...) * mapping(...) spec. For example, visual(BarPlot) will show mapping 1 on the x axis and 2 on the y axis, while visual(BarPlot, direction = :x) shows mapping 1 on y and 2 on x.

source

Examples

using AlgebraOfGraphics, CairoMakie
 set_aog_theme!()
 
 df = (x=randn(1000), y=randn(1000))
 plt = data(df) * mapping(:x, :y) * AlgebraOfGraphics.density(npoints=50)
-draw(plt * visual(Heatmap)) # plot as heatmap (the default)
Example block output

From AlgebraOfGraphics version 0.7 on, some attributes of the underlying Makie functions will not have an effect if they are controlled by scales instead. For example, continuous colors are completely controlled by color scales, so setting colormap in visual does not have an effect.

Set the colormap in the Scale options instead.

draw(plt, scales(Color = (; colormap = :viridis))) # set a different colormap
Example block output
draw(plt * visual(Contour)) # plot as contour
Example block output
draw(plt * visual(Contour, linewidth=2)) # plot as contour with thicker lines
Example block output

Manual legend entries via label

The legend normally contains entries for all appropriate scales used in the plot. Sometimes, however, you just want to label certain plots such that they appear in the legend without using any scale. You can achieve this by adding the label keyword to all visuals that you want to label. Layers with the same label will be combined within a legend entry.

x = range(0, 4pi, length = 40)
+draw(plt * visual(Heatmap)) # plot as heatmap (the default)
Example block output

From AlgebraOfGraphics version 0.7 on, some attributes of the underlying Makie functions will not have an effect if they are controlled by scales instead. For example, continuous colors are completely controlled by color scales, so setting colormap in visual does not have an effect.

Set the colormap in the Scale options instead.

draw(plt, scales(Color = (; colormap = :viridis))) # set a different colormap
Example block output
draw(plt * visual(Contour)) # plot as contour
Example block output
draw(plt * visual(Contour, linewidth=2)) # plot as contour with thicker lines
Example block output

Manual legend entries via label

The legend normally contains entries for all appropriate scales used in the plot. Sometimes, however, you just want to label certain plots such that they appear in the legend without using any scale. You can achieve this by adding the label keyword to all visuals that you want to label. Layers with the same label will be combined within a legend entry.

x = range(0, 4pi, length = 40)
 layer1 = data((; x = x, y = cos.(x))) * mapping(:x, :y) * visual(Lines, linestyle = :dash, label = "A cosine line")
 layer2 = data((; x = x, y = sin.(x) .+ 2)) * mapping(:x, :y) *
     (visual(Lines, color = (:tomato, 0.4)) + visual(Scatter, color = :tomato)) * visual(label = "A sine line + scatter")
@@ -28,4 +28,4 @@
     mapping(:x, :y, color = :group) *
     visual(Scatter; markersize = 5, legend = (; markersize = 15))
 
-draw(spec)
Example block output

These are the attributes you can override (note that some of them have convenience aliases like color which applies to all elements while polycolor only applies to PolyElements):

  • MarkerElement
    • [marker]points, markersize, [marker]strokewidth, [marker]color, [marker]strokecolor, [marker]colorrange, [marker]colormap
  • LineElement
    • [line]points, linewidth, [line]color, linestyle, [line]colorrange, [line]colormap
  • PolyElement
    • [poly]points, [poly]strokewidth, [poly]color, [poly]strokecolor, [poly]colorrange, [poly]colormap

More information about legend overrides can be found in Makie's documentation.


This page was generated using Literate.jl.

+draw(spec)
Example block output

These are the attributes you can override (note that some of them have convenience aliases like color which applies to all elements while polycolor only applies to PolyElements):

  • MarkerElement
    • [marker]points, markersize, [marker]strokewidth, [marker]color, [marker]strokecolor, [marker]colorrange, [marker]colormap
  • LineElement
    • [line]points, linewidth, [line]color, linestyle, [line]colorrange, [line]colormap
  • PolyElement
    • [poly]points, [poly]strokewidth, [poly]color, [poly]strokecolor, [poly]colorrange, [poly]colormap

More information about legend overrides can be found in Makie's documentation.


This page was generated using Literate.jl.

diff --git a/previews/PR593/index.html b/previews/PR593/index.html index 731b84260..d03a9c8a9 100644 --- a/previews/PR593/index.html +++ b/previews/PR593/index.html @@ -1,2 +1,2 @@ -Home · Algebra of Graphics

Introduction

AlgebraOfGraphics defines a language for data visualization. It is based on a few simple building blocks that can be combined using + and *.

This package can be installed typing

julia> import Pkg; Pkg.add("AlgebraOfGraphics")

in the Julia REPL.

See the Tutorial to get started.

+Home · Algebra of Graphics

Introduction

AlgebraOfGraphics defines a language for data visualization. It is based on a few simple building blocks that can be combined using + and *.

This package can be installed typing

julia> import Pkg; Pkg.add("AlgebraOfGraphics")

in the Julia REPL.

See the Tutorial to get started.

diff --git a/previews/PR593/layers/data/index.html b/previews/PR593/layers/data/index.html index f046c5610..51edd3991 100644 --- a/previews/PR593/layers/data/index.html +++ b/previews/PR593/layers/data/index.html @@ -1,9 +1,9 @@ -Data · Algebra of Graphics

Data

AlgebraOfGraphics.dataFunction
data(table)

Create a Layer with its data field set to a table-like object.

There are no type restrictions on this object, as long as it respects the Tables interface. In particular, any one of these formats should work out of the box.

To create a fully specified layer, the layer created with data needs to be multiplied with the output of mapping.

spec = data(...) * mapping(...)
source
using AlgebraOfGraphics
+Data · Algebra of Graphics

Data

AlgebraOfGraphics.dataFunction
data(table)

Create a Layer with its data field set to a table-like object.

There are no type restrictions on this object, as long as it respects the Tables interface. In particular, any one of these formats should work out of the box.

To create a fully specified layer, the layer created with data needs to be multiplied with the output of mapping.

spec = data(...) * mapping(...)
source
using AlgebraOfGraphics
 df = (a = rand(10), b = rand(10))
 data(df)
Layer 
   transformation: identity
   data: AlgebraOfGraphics.Columns{@NamedTuple{a::Vector{Float64}, b::Vector{Float64}}}
   positional:
   named:
-
+
diff --git a/previews/PR593/layers/draw/9554028a.svg b/previews/PR593/layers/draw/738ac322.svg similarity index 92% rename from previews/PR593/layers/draw/9554028a.svg rename to previews/PR593/layers/draw/738ac322.svg index 1bd487202..4185671b8 100644 --- a/previews/PR593/layers/draw/9554028a.svg +++ b/previews/PR593/layers/draw/738ac322.svg @@ -2,121 +2,121 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -128,36 +128,36 @@ - - + + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/layers/draw/32ac7126.svg b/previews/PR593/layers/draw/c4173628.svg similarity index 90% rename from previews/PR593/layers/draw/32ac7126.svg rename to previews/PR593/layers/draw/c4173628.svg index 4eaa32213..6792abff6 100644 --- a/previews/PR593/layers/draw/32ac7126.svg +++ b/previews/PR593/layers/draw/c4173628.svg @@ -2,380 +2,380 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -385,34 +385,34 @@ - + - + - + - + - + - + - + - + - + - + @@ -440,49 +440,49 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -535,19 +535,19 @@ - + - + - + - + - + @@ -600,19 +600,19 @@ - + - + - + - + - + @@ -640,354 +640,354 @@ - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/previews/PR593/layers/draw/index.html b/previews/PR593/layers/draw/index.html index 07c81c860..89cd2c771 100644 --- a/previews/PR593/layers/draw/index.html +++ b/previews/PR593/layers/draw/index.html @@ -126,7 +126,7 @@ highclip = :red, colorrange = (2, 9) ) -))Example block output

MarkerSize

The range of marker sizes can be set with the sizerange attribute. Marker sizes are computed such that their area, and not markersize itself, grows linearly with the scale values.

using AlgebraOfGraphics
+))
Example block output

MarkerSize

The range of marker sizes can be set with the sizerange attribute. Marker sizes are computed such that their area, and not markersize itself, grows linearly with the scale values.

using AlgebraOfGraphics
 using CairoMakie
 
 spec = data((; x = 1:10, y = 1:10, z = 10:10:100)) *
@@ -195,4 +195,4 @@
         ],
     ),
     axis = (; width = 100, height = 100)
-)
Example block output +)Example block output diff --git a/previews/PR593/layers/introduction/index.html b/previews/PR593/layers/introduction/index.html index 9196ace88..6ab0f1f3e 100644 --- a/previews/PR593/layers/introduction/index.html +++ b/previews/PR593/layers/introduction/index.html @@ -1,2 +1,2 @@ -Introduction · Algebra of Graphics

Introduction

Layers are the key building blocks of AlgebraOfGraphics. Each layer is the product of the following elementary objects.

  • Data (encoding the dataset).
  • Mapping (associating variables to plot attributes).
  • Visual (encoding data-independent plot information).
  • Analyses (encoding transformations that are applied to the data before plotting).

Data, mappings, visuals and analyses can be combined together using Algebraic Operations to form one or more layers.

The output of these algebraic operations can be visualized, as shown in the section Drawing Layers.

+Introduction · Algebra of Graphics

Introduction

Layers are the key building blocks of AlgebraOfGraphics. Each layer is the product of the following elementary objects.

  • Data (encoding the dataset).
  • Mapping (associating variables to plot attributes).
  • Visual (encoding data-independent plot information).
  • Analyses (encoding transformations that are applied to the data before plotting).

Data, mappings, visuals and analyses can be combined together using Algebraic Operations to form one or more layers.

The output of these algebraic operations can be visualized, as shown in the section Drawing Layers.

diff --git a/previews/PR593/layers/mapping/index.html b/previews/PR593/layers/mapping/index.html index 6ebac5536..ce02d8b67 100644 --- a/previews/PR593/layers/mapping/index.html +++ b/previews/PR593/layers/mapping/index.html @@ -12,7 +12,7 @@ )

Pregrouped

With data(Pregrouped()) * mapping(...) or the shortcut pregrouped(...), each element in mapping specifies input data directly, like with nothing. However, in this mode, data should be passed in pregrouped. Categorical variables should come as a vector of categories, while numerical variables should come as a vector of vectors of values, with as many inner vectors as there are groups in the categorical variables.

pregrouped(
     [[1, 2, 3], [4, 5]], # two grouped vectors, of length 3 and 2
     color = ["A", "B"]   # a vector with two categorical group values
-)
source

Aesthetics

The structure of a mapping is always directly tied to the signature of the plotting function (or analysis) that it is being connected with. What visual aspects of the plot the positional or keyword arguments affect depends on the plotting function in use.

To be used with AlgebraOfGraphics, a plotting function has to add a declaration which aesthetics (like X, Y, Color, MarkerSize, LineStyle) its arguments map to. This mechanism allows AlgebraOfGraphics to correctly convert the raw input data into visual attributes for each plotting function and to correctly create and label axes, colorbars and legends.

Aesthetics can also change depending on attributes passed to visual.

For example, for a BarPlot, args 1 and 2 correspond to the X and Y aesthetics by default. But if you change the direction in the visual, then axis labels shift accordingly because the aesthetic mapping has changed to 1 = Y, 2 = X:

using AlgebraOfGraphics
+)
source

Aesthetics

The structure of a mapping is always directly tied to the signature of the plotting function (or analysis) that it is being connected with. What visual aspects of the plot the positional or keyword arguments affect depends on the plotting function in use.

To be used with AlgebraOfGraphics, a plotting function has to add a declaration which aesthetics (like X, Y, Color, MarkerSize, LineStyle) its arguments map to. This mechanism allows AlgebraOfGraphics to correctly convert the raw input data into visual attributes for each plotting function and to correctly create and label axes, colorbars and legends.

Aesthetics can also change depending on attributes passed to visual.

For example, for a BarPlot, args 1 and 2 correspond to the X and Y aesthetics by default. But if you change the direction in the visual, then axis labels shift accordingly because the aesthetic mapping has changed to 1 = Y, 2 = X:

using AlgebraOfGraphics
 using CairoMakie
 
 df = (; name = ["Anna", "Beatrix", "Claire"], height_meters = [1.55, 1.76, 1.63])
@@ -101,4 +101,4 @@
       Color = (; palette = [:red, :green, :blue]),
       color2 = (; palette = [:gray30, :gray80]),
    )
-)
Example block output +)Example block output diff --git a/previews/PR593/layers/operations/index.html b/previews/PR593/layers/operations/index.html index 18384592b..d1ef95a04 100644 --- a/previews/PR593/layers/operations/index.html +++ b/previews/PR593/layers/operations/index.html @@ -1,2 +1,2 @@ -Algebraic Operations · Algebra of Graphics

Algebraic Operations

There are two algebraic types that can be added or multiplied with each other: AlgebraOfGraphics.Layer and AlgebraOfGraphics.Layers.

Multiplication on individual layers

Each layer is composed of data, mappings, and transformations. Datasets can be replaced, mappings can be merged, and transformations can be concatenated. These operations, taken together, define an associative operation on layers, which we call multiplication *.

Multiplication is primarily useful to combine partially defined layers.

Addition

The operation + is used to superimpose separate layers. a + b has as many layers as la + lb, where la and lb are the number of layers in a and b respectively.

Multiplication on lists of layers

Multiplication naturally extends to lists of layers. Given two Layers objects a and b, containing la and lb layers respectively, the product a * b contains la * lb layers—all possible pair-wise products.

+Algebraic Operations · Algebra of Graphics

Algebraic Operations

There are two algebraic types that can be added or multiplied with each other: AlgebraOfGraphics.Layer and AlgebraOfGraphics.Layers.

Multiplication on individual layers

Each layer is composed of data, mappings, and transformations. Datasets can be replaced, mappings can be merged, and transformations can be concatenated. These operations, taken together, define an associative operation on layers, which we call multiplication *.

Multiplication is primarily useful to combine partially defined layers.

Addition

The operation + is used to superimpose separate layers. a + b has as many layers as la + lb, where la and lb are the number of layers in a and b respectively.

Multiplication on lists of layers

Multiplication naturally extends to lists of layers. Given two Layers objects a and b, containing la and lb layers respectively, the product a * b contains la * lb layers—all possible pair-wise products.

diff --git a/previews/PR593/philosophy/index.html b/previews/PR593/philosophy/index.html index a522a4f4c..c1559a232 100644 --- a/previews/PR593/philosophy/index.html +++ b/previews/PR593/philosophy/index.html @@ -12,4 +12,4 @@ draw(plt)Example block output

In this case, thanks to the distributive property, it is clear that the dataset and the positional arguments :y, :z are shared across layers, the transparency and the grouping are specific to the data layer, whereas the density analysis, the Contour visualization, and the choice of color map are specific to the analysis layer.

User-defined building blocks

It is common in data analysis tasks to "pipe" a sequence of operations. This became very popular in the data science field with the %>% operator in the R language, and it can allow users to seamlessly compose a sequence of tasks:

df %>%
     filter(Weight < 3) %>%
     group_by(Species) %>%
-    summarise(avg_height = mean(Height))

Naturally, the alternative would be to create a statement per operation and to assign each intermediate result to its own variable.

AlgebraOfGraphics is markedly in favor of the latter approach. It is recommended that commonly used building blocks are stored in variables with meaningful names. If we often make a scatter plot with some transparency, we can create a variable transparent_scatter = visual(Scatter, alpha = 0.5) and use it consistently. If some columns of our dataset are always analyzed together, with a similar set of transformations, we can store that information as variables = mapping(variable1 => f1 => label1, variable2 => f2 => label2).

Working over one or more datasets, the user would then create a library of building blocks to be combined with each other with * and +. These two operators allow for a much larger number of possible combinations than just sequential composition, thus fully justifying the extra characters used to name intermediate entities.

Opinionated defaults

While users should be able to customize every aspect of their plots, it is important to note that this customization can be very time-consuming, and many subtleties can escape the attention of the casual user:

To remedy this, AlgebraOfGraphics aims to provide solid, opinionated default settings. In particular, it uses a conservative, colorblind-friendly palette and a perceptually uniform, universally readable color map. It follows IBM guidelines to differentiate titles and labels from tick labels via font weight, while using the same typeface at a readable size.

Wide format support

Finally, AlgebraOfGraphics aims to support many different data formats. Different problems require organizing the data in different formats, and AlgebraOfGraphics should support a wide range of options.

This is achieved in three different ways. First, the Tables interface ensures integration with a large variety of data sources. Second, using the Wide data syntax, users can compare many different columns in the same visualization, without having to first reshape the dataset to a long format. Finally, tabular datasets are not a requirement: users may also work directly with Pre-grouped data, which are not organized as a table, but rather as a collection of (possibly multi-dimensional) arrays.

+ summarise(avg_height = mean(Height))

Naturally, the alternative would be to create a statement per operation and to assign each intermediate result to its own variable.

AlgebraOfGraphics is markedly in favor of the latter approach. It is recommended that commonly used building blocks are stored in variables with meaningful names. If we often make a scatter plot with some transparency, we can create a variable transparent_scatter = visual(Scatter, alpha = 0.5) and use it consistently. If some columns of our dataset are always analyzed together, with a similar set of transformations, we can store that information as variables = mapping(variable1 => f1 => label1, variable2 => f2 => label2).

Working over one or more datasets, the user would then create a library of building blocks to be combined with each other with * and +. These two operators allow for a much larger number of possible combinations than just sequential composition, thus fully justifying the extra characters used to name intermediate entities.

Opinionated defaults

While users should be able to customize every aspect of their plots, it is important to note that this customization can be very time-consuming, and many subtleties can escape the attention of the casual user:

To remedy this, AlgebraOfGraphics aims to provide solid, opinionated default settings. In particular, it uses a conservative, colorblind-friendly palette and a perceptually uniform, universally readable color map. It follows IBM guidelines to differentiate titles and labels from tick labels via font weight, while using the same typeface at a readable size.

Wide format support

Finally, AlgebraOfGraphics aims to support many different data formats. Different problems require organizing the data in different formats, and AlgebraOfGraphics should support a wide range of options.

This is achieved in three different ways. First, the Tables interface ensures integration with a large variety of data sources. Second, using the Wide data syntax, users can compare many different columns in the same visualization, without having to first reshape the dataset to a long format. Finally, tabular datasets are not a requirement: users may also work directly with Pre-grouped data, which are not organized as a table, but rather as a collection of (possibly multi-dimensional) arrays.

diff --git a/previews/PR593/search_index.js b/previews/PR593/search_index.js index 5c51d7424..f74059b4a 100644 --- a/previews/PR593/search_index.js +++ b/previews/PR593/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/basic visualizations/statistical_visualizations.jl\"","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/#Statistical-visualizations","page":"Statistical visualizations","title":"Statistical visualizations","text":"","category":"section"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"using AlgebraOfGraphics, CairoMakie, PalmerPenguins, DataFrames\n\npenguins = dropmissing(DataFrame(PalmerPenguins.load()))\n\ndata(penguins) * visual(Violin) *\n mapping(:species, :bill_depth_mm, color=:sex, dodge=:sex) |> draw","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"plt = data(penguins) * visual(Violin, datalimits=extrema)\nplt *= mapping(:species, :bill_depth_mm, color=:sex, side=:sex, dodge=:island)\nfg = draw(plt, axis=(limits=((0.5, 3.5), nothing),))","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"data(penguins) * visual(BoxPlot, show_notch=true) *\n mapping(:species, :bill_depth_mm, color=:sex, dodge=:sex) |> draw","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"data(penguins) *\n mapping(:bill_length_mm, :bill_depth_mm, col=:sex) *\n visual(QQPlot, qqline=:fit) |> draw","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"FAQs/#Frequently-Asked-Questions","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"section"},{"location":"FAQs/#What-is-the-algebraic-structure-of-AlgebraOfGraphics?","page":"Frequently Asked Questions","title":"What is the algebraic structure of AlgebraOfGraphics?","text":"","category":"section"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"AlgebraOfGraphics is based on two operators, + and *. These two operators induce a semiring structure, with a small caveat. Addition is commutative only up to the drawing order. For example, visual(Lines) + visual(Scatter) is slightly different from visual(Scatter) + visual(Lines), in that the former draws the scatter on top of the lines, and the latter draws the lines on top of the scatter. As a consequence, only right distributivity holds with full generality, whereas left distributivity only holds up to the drawing order.","category":"page"},{"location":"FAQs/#Why-is-the-mapping-pair-syntax-different-from-DataFrames?","page":"Frequently Asked Questions","title":"Why is the mapping pair syntax different from DataFrames?","text":"","category":"section"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The transformations passed within a mapping, e.g. mapping(:x => log => \"log(x)\"), are applied element-wise. Operations that require the whole column are not supported on purpose. An important reason to prefer element-wise operations (other than performance) is that whole-column operations can be error prone in this setting, especially when","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"the data is grouped or\ndifferent datasets are used.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If you do need column-wise transformations, consider implementing a custom analysis, such as density, which takes the whole data as input, or apply the transformation directly in your data before passing it to AlgebraOfGraphics.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"See also Pair syntax for a detailed description of the pair syntax within a mapping.","category":"page"},{"location":"FAQs/#What-is-the-difference-between-axis-scales-and-data-transformations?","page":"Frequently Asked Questions","title":"What is the difference between axis scales and data transformations?","text":"","category":"section"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"There are two overlapping but distinct ways to rescale data.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Keep the data as is and use a nonlinear scale, e.g. axis=(xscale=log,).\nTransform the data directly, e.g. mapping(:x => log => \"log(x)\").","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Note that the resulting plots may \"look different\" in some cases. Consider for instance the following example.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"using AlgebraOfGraphics\nusing AlgebraOfGraphics: density\ndf = (x = exp.(randn(1000)),)\nkde1 = data(df) * mapping(:x) * density()\ndraw(kde1, axis=(width=225, height=225, xscale=log,))","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"df = (x = exp.(randn(1000)),)\nkde2 = data(df) * mapping(:x => log => \"log(x)\") * density()\ndraw(kde2, axis=(width=225, height=225))","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The two plots look different. The first represents the pdf of x in a log scale, while the second represents the pdf of log(x) in a linear scale. The two curves differ by a factor 1 / x, the derivative of log(x). See e.g. this post for some mathematical background on the topic.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In general, the second approach (plotting the density of log(x)) could be considered more principled, as it preserves the proportionality between area and probability mass. On the contrary, the first approach (plotting the density of x in a log scale) breaks this proportionality relationship.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"A similar reasoning applies to histograms:","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"using AlgebraOfGraphics\ndf = (x = exp.(rand(1000)),)\nhist1 = data(df) * mapping(:x) * histogram()\ndraw(hist1, axis=(width=225, height=225, xscale=log))","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"df = (x = exp.(rand(1000)),)\nhist2 = data(df) * mapping(:x => log => \"log(x)\") * histogram()\ndraw(hist2, axis=(width=225, height=225))","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The data transformation approach is preferable as it produces uniform bins, which are easier to interpret.","category":"page"},{"location":"FAQs/#How-to-combine-AlgebraOfGraphics-with-plain-Makie-plots?","page":"Frequently Asked Questions","title":"How to combine AlgebraOfGraphics with plain Makie plots?","text":"","category":"section"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Since AlgebraOfGraphics is built upon the Makie ecosystem we can easily combine plots from both packages. Two approaches can be taken. Firstly, by using draw! you can pass a Figure or FigurePosition created by Makie to be used by AlgebraOfGraphics, e.g.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"using AlgebraOfGraphics, CairoMakie #hide\n\nf, a, p = lines(0..2pi, sin; figure = (size = (600, 400),))\n\ndf = (x = exp.(rand(1000)),)\nhist1 = data(df) * mapping(:x => log => \"log(x)\") * histogram()\ndraw!(f[1, 2], hist1)\n\nf #hide","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Alternatively, we can create the AlgebraOfGraphics figure first and then add in additional plain Makie axes alongside the result by accessing the .figure field of fg, e.g.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"using AlgebraOfGraphics, CairoMakie #hide\n\ndf = (x = exp.(rand(1000)),)\nhist2 = data(df) * mapping(:x => log => \"log(x)\") * histogram()\nfg = draw(hist2; figure = (size = (600, 400),))\n\nlines(fg.figure[1, 2], 0..2pi, cos)\n\nfg #hide","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"note: Note\nWhen setting the width and height dimensions of each axis manually you will need to call resize_to_layout!(fg) before displaying the figure such that each axis is sized correctly.","category":"page"},{"location":"philosophy/#Philosophy","page":"Philosophy","title":"Philosophy","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"AlgebraOfGraphics aims to be a declarative, question-driven language for data visualizations. This section describes its main guiding principles.","category":"page"},{"location":"philosophy/#From-question-to-plot","page":"Philosophy","title":"From question to plot","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"When analyzing a dataset, we often think in abstract, declarative terms. We have questions concerning our data, which can be answered by appropriate visualizations. For instance, we could ask whether a discrete variable :x affects the distribution of a continuous variable :y. We would then like to generate a visualization that answers this question.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"In imperative programming, this would be implemented via the following steps.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Pick the dataset.\nDivide the dataset into subgroups according to the values of :x.\nCompute the density of :y on each subgroup.\nChoose a plot attribute to distinguish subgroups, for instance color.\nSelect as many distinguishable colors as there are unique values of :x.\nPlot all the density curves on top of each other.\nCreate a legend, describing how unique values of :x are associated to colors.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"While the above procedure is certainly feasible, it can introduce a cognitive overhead, especially when more variables and attributes are involved.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"In a declarative framework, the user needs to express the question, and the library will take care of creating the visualization. Let us solve the above problem in a toy dataset.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"using AlgebraOfGraphics, CairoMakie\nusing AlgebraOfGraphics: density\nset_aog_theme!()\nN = 1000\nx = rand([\"Class 1\", \"Class 2\", \"Class 3\", \"Class 4\"], N)\ny = @. (x == \"Class 1\") * randn() + (x == \"Class 2\") - (x == \"Class 3\") + randn()\nz = @. (x == \"Class 2\") * randn() + (x == \"Class 2\") + (x == \"Class 3\") + y + randn()\ndf = (; x, y, z)","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"plt = data(df) # declare the dataset\nplt *= density() # declare the analysis\nplt *= mapping(:y) # declare the arguments of the analysis\nplt *= mapping(color = :x) # declare the grouping and the respective visual attribute\ndraw(plt) # draw the visualization and its legend","category":"page"},{"location":"philosophy/#No-mind-reading","page":"Philosophy","title":"No mind reading","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Plotting packages requires the user to specify a large amount of settings. The temptation is then to engineer a plotting library in such a way that it would guess what the user actually wanted. AlgebraOfGraphics follows a different approach, based on algebraic manipulations of plot descriptors.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"The key intuition is that a large fraction of the \"clutter\" in a plot specification comes from repeating the same information over and over. Different layers of the same plot will share some but not all information, and the user should be able to distinguish settings that are private to a layer from those that are shared across layers.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"We achieve this goal using the distributive properties of addition and multiplication. This is best explained by example. Let us assume that we wish to visually inspect whether a discrete variable :x affects the joint distribution of two continuous variables, :y and :z.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"We would like to have two layers, one with the raw data, the other with an analysis (kernel density estimation).","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Naturally, the axes should represent the same variables (:y and :z) for both layers. Only the density layer should be a contour plot, whereas only the scatter layer should have some transparency and be grouped (according to :x) in different subplots.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"plt = data(df) *\n (\n visual(Scatter, alpha = 0.3) * mapping(layout = :x) +\n density() * visual(Contour, colormap = Reverse(:grays))\n ) *\n mapping(:y, :z)\ndraw(plt)","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"In this case, thanks to the distributive property, it is clear that the dataset and the positional arguments :y, :z are shared across layers, the transparency and the grouping are specific to the data layer, whereas the density analysis, the Contour visualization, and the choice of color map are specific to the analysis layer.","category":"page"},{"location":"philosophy/#User-defined-building-blocks","page":"Philosophy","title":"User-defined building blocks","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"It is common in data analysis tasks to \"pipe\" a sequence of operations. This became very popular in the data science field with the %>% operator in the R language, and it can allow users to seamlessly compose a sequence of tasks:","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"df %>%\n filter(Weight < 3) %>%\n group_by(Species) %>%\n summarise(avg_height = mean(Height))","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Naturally, the alternative would be to create a statement per operation and to assign each intermediate result to its own variable.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"AlgebraOfGraphics is markedly in favor of the latter approach. It is recommended that commonly used building blocks are stored in variables with meaningful names. If we often make a scatter plot with some transparency, we can create a variable transparent_scatter = visual(Scatter, alpha = 0.5) and use it consistently. If some columns of our dataset are always analyzed together, with a similar set of transformations, we can store that information as variables = mapping(variable1 => f1 => label1, variable2 => f2 => label2).","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Working over one or more datasets, the user would then create a library of building blocks to be combined with each other with * and +. These two operators allow for a much larger number of possible combinations than just sequential composition, thus fully justifying the extra characters used to name intermediate entities.","category":"page"},{"location":"philosophy/#Opinionated-defaults","page":"Philosophy","title":"Opinionated defaults","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"While users should be able to customize every aspect of their plots, it is important to note that this customization can be very time-consuming, and many subtleties can escape the attention of the casual user:","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Is the color palette colorblind-friendly?\nWould the colors be distinguishable in black and white (when printed)?\nIs the color gradient perceptually uniform?\nAre the labels and the ticks legible for readers with low vision?\nAre the spacing and typographic hierarchies respected?","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"To remedy this, AlgebraOfGraphics aims to provide solid, opinionated default settings. In particular, it uses a conservative, colorblind-friendly palette and a perceptually uniform, universally readable color map. It follows IBM guidelines to differentiate titles and labels from tick labels via font weight, while using the same typeface at a readable size.","category":"page"},{"location":"philosophy/#Wide-format-support","page":"Philosophy","title":"Wide format support","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Finally, AlgebraOfGraphics aims to support many different data formats. Different problems require organizing the data in different formats, and AlgebraOfGraphics should support a wide range of options.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"This is achieved in three different ways. First, the Tables interface ensures integration with a large variety of data sources. Second, using the Wide data syntax, users can compare many different columns in the same visualization, without having to first reshape the dataset to a long format. Finally, tabular datasets are not a requirement: users may also work directly with Pre-grouped data, which are not organized as a table, but rather as a collection of (possibly multi-dimensional) arrays.","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/multiple_color_scales.jl\"","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/#Multiple-color-scales","page":"Multiple color scales","title":"Multiple color scales","text":"","category":"section"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"Continuous and discrete color scales can coexist in the same plot. This should be used sparingly, as it can make the plot harder to interpret.","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"x = range(-π, π, length=100)\ny = sin.(x)\nŷ = y .+ randn.() .* 0.1\nz = cos.(x)\nc = rand([\"a\", \"b\"], 100)\ndf = (; x, y, ŷ, z, c)\nlayers = mapping(:y, color=:z) * visual(Lines) + mapping(:ŷ => \"y\", color=:c)\nplt = data(df) * mapping(:x) * layers\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"EditURL = \"analyses.jl\"","category":"page"},{"location":"generated/analyses/#Analyses","page":"Analyses","title":"Analyses","text":"","category":"section"},{"location":"generated/analyses/#Histogram","page":"Analyses","title":"Histogram","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"histogram","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.histogram","page":"Analyses","title":"AlgebraOfGraphics.histogram","text":"histogram(; bins=automatic, datalimits=automatic, closed=:left, normalization=:none)\n\nCompute a histogram.\n\nThe attribute bins can be an Integer, an AbstractVector (in particular, a range), or a Tuple of either integers or abstract vectors (useful for 2- or 3-dimensional histograms). When bins is an Integer, it denotes the approximate number of equal-width intervals used to compute the histogram. In that case, the range covered by the intervals is defined by datalimits (it defaults to the extrema of the whole data). The keyword argument datalimits can be a tuple of two values, e.g. datalimits=(0, 10), or a function to be applied group by group, e.g. datalimits=extrema. When bins is an AbstractVector, it denotes the intervals directly.\n\nclosed determines whether the the intervals are closed to the left or to the right.\n\nThe histogram can be normalized by setting normalization. Possible values are:\n\n:pdf: Normalize by sum of weights and bin sizes. Resulting histogram has norm 1 and represents a PDF.\n:density: Normalize by bin sizes only. Resulting histogram represents count density of input and does not have norm 1.\n:probability: Normalize by sum of weights only. Resulting histogram represents the fraction of probability mass for each bin and does not have norm 1.\n:none: Do not normalize.\n\nWeighted data is supported via the keyword weights (passed to mapping).\n\nnote: Note\nNormalizations are computed withing groups. For example, in the case of normalization=:pdf, sum of weights within each group will be equal to 1.\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"using AlgebraOfGraphics, CairoMakie\nset_aog_theme!()\n\ndf = (x=randn(5000), y=randn(5000), z=rand([\"a\", \"b\", \"c\"], 5000))\nspecs = data(df) * mapping(:x, layout=:z) * histogram(bins=range(-2, 2, length=15))\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, dodge=:z, color=:z) * histogram(bins=range(-2, 2, length=15))\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, stack=:z, color=:z) * histogram(bins=range(-2, 2, length=15))\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) *\n mapping((:x, :z) => ((x, z) -> x + 5 * (z == \"b\")) => \"new x\", col=:z) *\n histogram(datalimits=extrema, bins=20)\ndraw(specs, facet=(linkxaxes=:minimal,))","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"data(df) * mapping(:x, :y, layout=:z) * histogram(bins=15) |> draw","category":"page"},{"location":"generated/analyses/#Density","page":"Analyses","title":"Density","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"AlgebraOfGraphics.density","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.density","page":"Analyses","title":"AlgebraOfGraphics.density","text":"density(; datalimits=automatic, kernel=automatic, bandwidth=automatic, npoints=200)\n\nFit a kernel density estimation of data.\n\nHere, datalimits specifies the range for which the density should be calculated (it defaults to the extrema of the whole data). The keyword argument datalimits can be a tuple of two values, e.g. datalimits=(0, 10), or a function to be applied group by group, e.g. datalimits=extrema. The keyword arguments kernel and bandwidth are forwarded to KernelDensity.kde. npoints is the number of points used by Makie to draw the line\n\nWeighted data is supported via the keyword weights (passed to mapping).\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"df = (x=randn(5000), y=randn(5000), z=rand([\"a\", \"b\", \"c\", \"d\"], 5000))\nspecs = data(df) * mapping(:x, layout=:z) * AlgebraOfGraphics.density(datalimits=((-2.5, 2.5),))\n\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) *\n mapping((:x, :z) => ((x, z) -> x + 5 * (z ∈ [\"b\", \"d\"])) => \"new x\", layout=:z) *\n AlgebraOfGraphics.density(datalimits=extrema)\ndraw(specs, facet=(linkxaxes=:minimal,))","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"data(df) * mapping(:x, :y, layout=:z) * AlgebraOfGraphics.density(npoints=50) |> draw","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, :y, layout=:z) *\n AlgebraOfGraphics.density(npoints=50) * visual(Surface)\n\ndraw(specs, axis=(type=Axis3, zticks=0:0.1:0.2, limits=(nothing, nothing, (0, 0.2))))","category":"page"},{"location":"generated/analyses/#Frequency","page":"Analyses","title":"Frequency","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"frequency","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.frequency","page":"Analyses","title":"AlgebraOfGraphics.frequency","text":"frequency()\n\nCompute a frequency table of the arguments.\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"df = (x=rand([\"a\", \"b\", \"c\"], 100), y=rand([\"a\", \"b\", \"c\"], 100), z=rand([\"a\", \"b\", \"c\"], 100))\nspecs = data(df) * mapping(:x, layout=:z) * frequency()\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, layout=:z, color=:y, stack=:y) * frequency()\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, :y, layout=:z) * frequency()\ndraw(specs)","category":"page"},{"location":"generated/analyses/#Expectation","page":"Analyses","title":"Expectation","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"expectation","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.expectation","page":"Analyses","title":"AlgebraOfGraphics.expectation","text":"expectation()\n\nCompute the expected value of the last argument conditioned on the preceding ones.\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"df = (x=rand([\"a\", \"b\", \"c\"], 100), y=rand([\"a\", \"b\", \"c\"], 100), z=rand(100), c=rand([\"a\", \"b\", \"c\"], 100))\nspecs = data(df) * mapping(:x, :z, layout=:c) * expectation()\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, :z, layout=:c, color=:y, dodge=:y) * expectation()\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, :y, :z, layout=:c) * expectation()\ndraw(specs)","category":"page"},{"location":"generated/analyses/#Linear","page":"Analyses","title":"Linear","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"linear","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.linear","page":"Analyses","title":"AlgebraOfGraphics.linear","text":"linear(; interval=automatic, level=0.95, dropcollinear=false, npoints=200)\n\nCompute a linear fit of y ~ 1 + x. An optional named mapping weights determines the weights. Use interval to specify what type of interval the shaded band should represent, for a given coverage level (the default 0.95 equates alpha = 0.05). Valid values of interval are :confidence, to delimit the uncertainty of the predicted relationship, and :prediction, to delimit estimated bounds for new data points. Use interval = nothing to only compute the line fit, without any uncertainty estimate. By default, this analysis errors on singular (collinear) data. To avoid that, it is possible to set dropcollinear=true. npoints is the number of points used by Makie to draw the shaded band.\n\nWeighted data is supported via the keyword weights (passed to mapping).\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"x = 1:0.05:10\na = rand(1:7, length(x))\ny = 1.2 .* x .+ a .+ 0.5 .* randn.()\ndf = (; x, y, a)\nspecs = data(df) * mapping(:x, :y, color=:a => nonnumeric) * (linear() + visual(Scatter))\ndraw(specs)","category":"page"},{"location":"generated/analyses/#Smoothing","page":"Analyses","title":"Smoothing","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"smooth","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.smooth","page":"Analyses","title":"AlgebraOfGraphics.smooth","text":"smooth(; span=0.75, degree=2, npoints=200)\n\nFit a loess model. span is the degree of smoothing, typically in [0,1]. Smaller values result in smaller local context in fitting. degree is the polynomial degree used in the loess model. npoints is the number of points used by Makie to draw the line\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"x = 1:0.05:10\na = rand(1:7, length(x))\ny = sin.(x) .+ a .+ 0.1 .* randn.()\ndf = (; x, y, a)\nspecs = data(df) * mapping(:x, :y, color=:a => nonnumeric) * (smooth() + visual(Scatter))\ndraw(specs)","category":"page"},{"location":"generated/analyses/#Contours","page":"Analyses","title":"Contours","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"contours","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.contours","page":"Analyses","title":"AlgebraOfGraphics.contours","text":"contours(; levels=5, kwargs...)\n\nCreate contour lines over the grid spanned over x and y by args 1 and 2 in the mapping, with height values z passed via arg 3. \n\nYou can pass the number of levels as an integer or a vector of levels. The levels are calculated across the whole z data if they are specified as an integer.\n\nNote that visual(Contour) only works in a limited way with AlgebraOfGraphics since version 0.7, because the internal calculations it does are not compatible with the scale system. With visual(Contour), you can only have categorically-colored contours (for example to visualize contours of multiple categories). Alternatively, if you set the colormap attribute, you can get continuously-colored contours but the levels will not be known to AlgebraOfGraphics, so they won't be synchronized across facets and there will not be a colorbar.\n\nAll other keyword arguments are forwarded as attributes to the underlying Contour plot.\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"x = repeat(1:10, 10)\ny = repeat(11:20, inner = 10)\nz = sqrt.(x .* y)\ndf = (; x, y, z)\nspecs = data(df) * mapping(:x, :y, :z) * contours(levels = 8)\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"x = repeat(1:10, 10)\ny = repeat(11:20, inner = 10)\nz = sqrt.(x .* y)\ndf = (; x, y, z)\nspecs = data(df) * mapping(:x, :y, :z) * contours(levels = 8, labels = true)\ndraw(specs)","category":"page"},{"location":"generated/analyses/#Filled-Contours","page":"Analyses","title":"Filled Contours","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"filled_contours","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.filled_contours","page":"Analyses","title":"AlgebraOfGraphics.filled_contours","text":"filled_contours(; bands=automatic, levels=automatic)\n\nCreate filled contours over the grid spanned over x and y by args 1 and 2 in the mapping, with height values z passed via arg 3. \n\nYou can pass either the number of bands to bands or pass a vector of levels (the boundaries of the bands) to levels, but not both. The number of bands when levels is passed is length(levels) - 1. The levels are calculated across the whole z data if the number of bands is specified. If neither levels nor bands are specified, the default is bands = 10.\n\nNote that visual(Contourf) does not work with AlgebraOfGraphics since version 0.7, because the internal binning it does is not compatible with the scale system.\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"x = repeat(1:10, 10)\ny = repeat(11:20, inner = 10)\nz = sqrt.(x .* y)\ndf = (; x, y, z)\nspecs = data(df) * mapping(:x, :y, :z) * filled_contours(levels = 3:2:15)\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"This page was generated using Literate.jl.","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/data manipulations/pre_grouped_data.jl\"","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/#Pre-grouped-data","page":"Pre-grouped data","title":"Pre-grouped data","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"using AlgebraOfGraphics, CairoMakie\n\n\nx = [rand(10) .+ i for i in 1:3]\ny = [rand(10) .+ i for i in 1:3]\nz = [rand(10) .+ i for i in 1:3]\nc = [\"a\", \"b\", \"c\"]\n\nm = pregrouped(x, y, color=c => (t -> \"Type \" * t ) => \"Category\")\ndraw(m)","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"m = pregrouped(x, (y, z) => (+) => \"sum\", color=c => (t -> \"Type \" * t ) => \"Category\")\ndraw(m)","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"m = pregrouped(x, [y z], color=dims(1) => renamer([\"a\", \"b\", \"c\"])) * visual(Scatter)\ndraw(m)","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"m = pregrouped(x, [y z], color=[\"1\" \"2\"])\nlayers = visual(Scatter) + linear()\nfg = draw(m * layers)","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/customization/legend.jl\"","category":"page"},{"location":"gallery/gallery/customization/legend/#Legend-tweaking","page":"Legend tweaking","title":"Legend tweaking","text":"","category":"section"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: Source code)","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"To tweak the position and appearance of the legend, simply use the legend keyword when plotting. For example","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"labels = [\"a looooooong label\", \"an even loooooonger label\", \"and one more long label\"]\ndf = (x=rand(100), y=rand(100), group=rand(labels, 100))\nlayers = linear() + mapping(color=:group)\nplt = data(df) * layers * mapping(:x, :y)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"fg = draw(plt, legend=(position=:top, titleposition=:left, framevisible=true, padding=5))","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"To adjust the title and order of labels in a legend you can use the pair syntax.","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"layers = linear() + mapping(color=:group => sorter(labels) => \"Labels\")\nplt = data(df) * layers * mapping(:x, :y)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"Adding a plot to a pre-existing figure with draw! will not draw the legend automatically. In this case, one must use legend! and specify the axis to which it should be added.","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"The tellheight = false, tellwidth = false arguments are useful to avoid changing the dimensions of the axis.","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"makie_fig = Figure()\nax_scatter = Axis(makie_fig[1, 1])\n\ngrid = draw!(ax_scatter, plt)\n\nlegend!(makie_fig[1, 1], grid; tellheight=false, tellwidth=false, halign=:right, valign=:top)\n\nmakie_fig","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"If the automatic legend elements are not legible enough, you can change their properties by passing overrides to the legend attribute of a visual.","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"df = (;\n x = repeat(1:100, 5),\n y = reduce(vcat, [[cos(x) for x in range(0, 8pi, length = 100)] .+ 0.3 .* randn.() for _ in 1:5]),\n group = repeat(1:5, inner = 100),\n)\n\nlin = data(df) *\n mapping(:x, :y, group = :group => nonnumeric) *\n visual(Lines, linewidth = 0.3, label = \"Lines\", legend = (; linewidth = 1.5))\nsca = data(df) *\n mapping(:x, :y => y -> y + 5, group = :group => nonnumeric) *\n visual(Scatter, markersize = 3, label = \"Scatter\", legend = (; markersize = 12))\n\ndraw(lin + sca)","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"EditURL = \"visual.jl\"","category":"page"},{"location":"generated/visual/#Visual","page":"Visual","title":"Visual","text":"","category":"section"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"visual","category":"page"},{"location":"generated/visual/#AlgebraOfGraphics.visual","page":"Visual","title":"AlgebraOfGraphics.visual","text":"visual(plottype; attributes...)\n\nCreate a Layer that will cause a plot spec multiplied with it to be visualized with plot type plottype, together with optional attributes.\n\nThe available plotting functions are documented here. Refer to plotting functions using upper CamelCase for visual's first argument (e.g. visual(Scatter), visual(BarPlot)). See the documentation of each plotting function to discover the available attributes. These attributes can be passed as additional keyword arguments to visual, or as part of the mapping you define.\n\nThe visual function can in principle be used for any plotting function that is defined using the @recipe macro from Makie. AlgebraOfGraphics just needs method definitions for aesthetic_mapping, which define what arguments of the plotting function map to which visual aesthetics. And for legend support, legend_elements must be overloaded for custom recipes as well, as Makie's default legend mechanism relies on instantiated plot objects, while AlgebraOfGraphics must go by the type and attributes alone.\n\nDepending on its aesthetic_mapping, a plot type and its attributes may change certain semantics of a given data(...) * mapping(...) spec. For example, visual(BarPlot) will show mapping 1 on the x axis and 2 on the y axis, while visual(BarPlot, direction = :x) shows mapping 1 on y and 2 on x.\n\n\n\n\n\n","category":"function"},{"location":"generated/visual/#Examples","page":"Visual","title":"Examples","text":"","category":"section"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"using AlgebraOfGraphics, CairoMakie\nset_aog_theme!()\n\ndf = (x=randn(1000), y=randn(1000))\nplt = data(df) * mapping(:x, :y) * AlgebraOfGraphics.density(npoints=50)\ndraw(plt * visual(Heatmap)) # plot as heatmap (the default)","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"From AlgebraOfGraphics version 0.7 on, some attributes of the underlying Makie functions will not have an effect if they are controlled by scales instead. For example, continuous colors are completely controlled by color scales, so setting colormap in visual does not have an effect.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"Set the colormap in the Scale options instead.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"draw(plt, scales(Color = (; colormap = :viridis))) # set a different colormap","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"draw(plt * visual(Contour)) # plot as contour","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"draw(plt * visual(Contour, linewidth=2)) # plot as contour with thicker lines","category":"page"},{"location":"generated/visual/#Manual-legend-entries-via-label","page":"Visual","title":"Manual legend entries via label","text":"","category":"section"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"The legend normally contains entries for all appropriate scales used in the plot. Sometimes, however, you just want to label certain plots such that they appear in the legend without using any scale. You can achieve this by adding the label keyword to all visuals that you want to label. Layers with the same label will be combined within a legend entry.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"x = range(0, 4pi, length = 40)\nlayer1 = data((; x = x, y = cos.(x))) * mapping(:x, :y) * visual(Lines, linestyle = :dash, label = \"A cosine line\")\nlayer2 = data((; x = x, y = sin.(x) .+ 2)) * mapping(:x, :y) *\n (visual(Lines, color = (:tomato, 0.4)) + visual(Scatter, color = :tomato)) * visual(label = \"A sine line + scatter\")\ndraw(layer1 + layer2)","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"If the figure contains other scales, the legend will list the labelled group last by default. If you want to reorder, use the symbol :Label to specify the labelled group.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"df = (; x = repeat(1:10, 3), y = cos.(1:30), group = repeat([\"A\", \"B\", \"C\"], inner = 10))\nspec1 = data(df) * mapping(:x, :y, color = :group) * visual(Lines)\n\nspec2 = data((; x = 1:10, y = cos.(1:10) .+ 2)) * mapping(:x, :y) * visual(Scatter, color = :purple, label = \"Scatter\")\n\nf = Figure()\nfg = draw!(f[1, 1], spec1 + spec2)\nlegend!(f[1, 2], fg)\nlegend!(f[1, 3], fg, order = [:Label, :Color])\n\nf","category":"page"},{"location":"generated/visual/#Legend-element-overrides","page":"Visual","title":"Legend element overrides","text":"","category":"section"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"Sometimes it might be necessary to override legend element properties that are otherwise copied from the visual settings. For example, a scatter plot with many small markers might have a legend that is hard to read. We can use AlgebraOfGraphics's legend keyword in visual to specify override attributes via key-value pairs. Here we increase the markersize for the MarkerElements that are created for a Scatter plot:","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"df = (;\n x = randn(200) .+ repeat([0, 3], 100),\n y = randn(200) .+ repeat([0, 3], 100),\n group = repeat([\"A\", \"B\"], 100)\n)\n\nspec = data(df) *\n mapping(:x, :y, color = :group) *\n visual(Scatter; markersize = 5, legend = (; markersize = 15))\n\ndraw(spec)","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"These are the attributes you can override (note that some of them have convenience aliases like color which applies to all elements while polycolor only applies to PolyElements):","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"MarkerElement\n[marker]points, markersize, [marker]strokewidth, [marker]color, [marker]strokecolor, [marker]colorrange, [marker]colormap\nLineElement\n[line]points, linewidth, [line]color, linestyle, [line]colorrange, [line]colormap\nPolyElement\n[poly]points, [poly]strokewidth, [poly]color, [poly]strokecolor, [poly]colorrange, [poly]colormap","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"More information about legend overrides can be found in Makie's documentation.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"This page was generated using Literate.jl.","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/customization/axis.jl\"","category":"page"},{"location":"gallery/gallery/customization/axis/#Axis-tweaking","page":"Axis tweaking","title":"Axis tweaking","text":"","category":"section"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"To tweak one or more axes, simply use the axis keyword when plotting. For example","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"df = (x=rand(100), y=rand(100), z=rand(100))\nlayers = linear() + mapping(color=:z)\nplt = data(df) * layers * mapping(:x, :y)\ndraw(plt, axis=(aspect=1,))","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"fg = draw(plt, axis=(aspect=1, xticks=0:0.1:1, yticks=0:0.1:1, ylabel=\"custom label\"))","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/secondary_scales.jl\"","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/#Secondary-scales","page":"Secondary scales","title":"Secondary scales","text":"","category":"section"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"By default, scales with the same aesthetic type have their categories merged. This can be undesirable if there are disjoint sets of categories, for example three different time series with two different event markers:","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"nevents = 500\nngroups = 3\ntime = repeat(1:nevents, ngroups)\ny = reduce(vcat, [cumsum(randn(length(time))) for _ in 1:ngroups])\ngroup = repeat([\"A\", \"B\", \"C\"], inner = nevents)\ndf1 = (; time, y, group)\ndf2 = (; time = [30, 79, 250, 400], event = [\"X\", \"Y\", \"Y\", \"X\"])\n\nspec_a = data(df1) * mapping(:time, :y, color = :group) * visual(Lines)\nspec_b = data(df2) * mapping(:time, color = :event) * visual(VLines)\n\ndraw(spec_a + spec_b)","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"By assigning an arbitrary scale identifier to one of the color mappings, we can split the two scales apart and receive a separate legend for both:","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"split_spec = spec_a + spec_b * mapping(color = :event => scale(:secondary))\ndraw(split_spec)","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"Each scale can then be modified separately in the scales configuration. For example, it is not desired that both scales use the same color palette:","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"fg = draw(split_spec, scales(secondary = (;\n palette = [:gray70, :gray30]\n)))","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"If you don't want to have separate legend groups, you can merge them using the order keyword in the legend config.","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"draw(\n split_spec,\n scales(\n secondary = (; palette = [:gray70, :gray30])\n );\n legend = (; order = [[:Color, :secondary] => \"Legend\"])\n)","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/customization/figure.jl\"","category":"page"},{"location":"gallery/gallery/customization/figure/#Figure-tweaking","page":"Figure tweaking","title":"Figure tweaking","text":"","category":"section"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"You can pass attributes to the underlying Makie.Figure using the figure keyword of draw.","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"df = (x=rand(100), y=rand(100), z=rand(100), c=rand([\"a\", \"b\"], 100))\nxyc = data(df) * mapping(:x, :y, layout=:c)\nlayers = linear() + mapping(color=:z)\nplt = xyc * layers\ndraw(\n plt,\n figure = (;\n figure_padding = 10,\n backgroundcolor = :gray80,\n size = (800, 400)\n )\n)","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"You can also add a figure title, subtitle and footnotes.","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"fg = draw(\n plt,\n figure = (;\n figure_padding = 10,\n backgroundcolor = :gray80,\n size = (800, 400),\n title = \"Figure title\",\n subtitle = \"Some subtitle below the figure title\",\n footnotes = [\n rich(superscript(\"1\"), \"First footnote\"),\n rich(superscript(\"2\"), \"Second footnote\"),\n ]\n )\n)","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"The appearance of these elements can be modified further, for all options check the draw function.","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"draw(\n plt,\n figure = (;\n figure_padding = 10,\n backgroundcolor = :gray80,\n size = (800, 400),\n title = \"Figure title\",\n subtitle = \"Some subtitle below the figure title\",\n footnotes = [\n rich(superscript(\"1\"), \"First footnote\"),\n rich(superscript(\"2\"), \"Second footnote\"),\n ],\n titlecolor = :firebrick,\n titlealign = :right,\n footnotefont = :bold,\n )\n)","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"layers/mapping/#Mapping","page":"Mapping","title":"Mapping","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Mappings determine how the data is translated into a plot. For example, this mapping maps columns weight and height to positional arguments 1 and 2, and age to the markersize attribute of the Scatter plotting function:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"mapping(:weight, :height, markersize = :age)","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"mapping","category":"page"},{"location":"layers/mapping/#AlgebraOfGraphics.mapping","page":"Mapping","title":"AlgebraOfGraphics.mapping","text":"mapping(positional...; named...)\n\nCreate a Layer with positional and named selectors. These selectors will be translated into input data for the Makie plotting function or AlgebraOfGraphics analysis that is chosen to visualize the Layer.\n\nA Layer created with mapping does not have a data source by default, you can add one by multiplying with the output of the data function.\n\nThe positional and named selectors of mapping are converted to actual input data for the plotting function that will be selected via visual. The translation from selector to data differs according to the data source.\n\nTabular data\n\nWhen a mapping is combined with a data(tabular) where tabular is some Tables.jl-compatible object, each argument will be interpreted as a column selector. Additionally, it's allowed to specify columns outside of the dataset directly by wrapping the values in direct. The values can either be vectors that have to match the number of rows from the tabular data, or scalars that will be expanded as if they were a column filled with the same value.\n\nmapping(\n :x, # column named \"x\"\n \"a column\"; # column named \"a column\"\n color = 1, # first column\n marker = direct(\"abc\"), # a new column filled with the string \"abc\"\n linestyle = direct(1:3), # a new column, length must match the table\n)\n\nnothing\n\nIf no data is set, each entry of mapping should be an AbstractVector that specifies a column of data directly. Scalars like strings for example will be expanded as if they were a column filled with the same value. This is useful when a legend should be shown, but there's only one group.\n\nmapping(\n 1:3, # a column with values 1 to 3\n [4, 5, 6], # a column with values 4 to 6 \n color = \"group 1\", # a column with repeated value \"group 1\" \n)\n\nPregrouped\n\nWith data(Pregrouped()) * mapping(...) or the shortcut pregrouped(...), each element in mapping specifies input data directly, like with nothing. However, in this mode, data should be passed in pregrouped. Categorical variables should come as a vector of categories, while numerical variables should come as a vector of vectors of values, with as many inner vectors as there are groups in the categorical variables.\n\npregrouped(\n [[1, 2, 3], [4, 5]], # two grouped vectors, of length 3 and 2\n color = [\"A\", \"B\"] # a vector with two categorical group values\n)\n\n\n\n\n\n","category":"function"},{"location":"layers/mapping/#Aesthetics","page":"Mapping","title":"Aesthetics","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"The structure of a mapping is always directly tied to the signature of the plotting function (or analysis) that it is being connected with. What visual aspects of the plot the positional or keyword arguments affect depends on the plotting function in use.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"To be used with AlgebraOfGraphics, a plotting function has to add a declaration which aesthetics (like X, Y, Color, MarkerSize, LineStyle) its arguments map to. This mechanism allows AlgebraOfGraphics to correctly convert the raw input data into visual attributes for each plotting function and to correctly create and label axes, colorbars and legends.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Aesthetics can also change depending on attributes passed to visual.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"For example, for a BarPlot, args 1 and 2 correspond to the X and Y aesthetics by default. But if you change the direction in the visual, then axis labels shift accordingly because the aesthetic mapping has changed to 1 = Y, 2 = X:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (; name = [\"Anna\", \"Beatrix\", \"Claire\"], height_meters = [1.55, 1.76, 1.63])\nm = mapping(:name, :height_meters)\nspec1 = data(df) * m * visual(BarPlot)\nspec2 = data(df) * m * visual(BarPlot, direction = :x)\n\nf = Figure()\ndraw!(f[1, 1], spec1)\ndraw!(f[1, 2], spec2)\nf","category":"page"},{"location":"layers/mapping/#Hardcoded-aesthetics","page":"Mapping","title":"Hardcoded aesthetics","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Most aesthetics are tied to specific attributes of plot types, for example like AesColor to strokecolor of Scatter. There are a few aesthetics, however, which are hardcoded to belong to certain mapping keywords independent of the plot type in use.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"These are layout, row and col for facetting, group for creating a separate plot for each group (like separate lines instead of one long line) and dodge_x and dodge_y for dodging.","category":"page"},{"location":"layers/mapping/#Dodging","page":"Mapping","title":"Dodging","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Dodging refers to the shifting of plots on a (usually categorical) scale depending on the group they belong to. It is used to avoid overlaps. Some plot types, like BarPlot, have their own dodge keyword because their dodging logic additionally needs to transform the visual elements (for example, dodging a bar plot makes thinner bars). For all other plot types, you can use the generic dodge_x and dodge_y keywords.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"They work by shifting each categorical group by some value that depends on the chosen \"dodge width\". The dodge width refers to the width that all dodged elements in a group add up to at a given point. Some plot types have an inherent width, like barplots. Others have no width, like scatters or errorbars. For those plot types that have no width to use for dodging, you have to specify one manually in scales.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Here's an example of a manual width selection:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (\n x = repeat(1:10, inner = 2),\n y = cos.(range(0, 2pi, length = 20)),\n ylow = cos.(range(0, 2pi, length = 20)) .- 0.2,\n yhigh = cos.(range(0, 2pi, length = 20)) .+ 0.3,\n dodge = repeat([\"A\", \"B\"], 10)\n)\n\nf = Figure()\nplt = data(df) * (\n mapping(:x, :y, dodge_x = :dodge, color = :dodge) * visual(Scatter) +\n mapping(:x, :ylow, :yhigh, dodge_x = :dodge, color = :dodge) * visual(Rangebars)\n)\ndraw!(f[1, 1], plt, scales(DodgeX = (; width = 1)), axis = (; title = \"width = 1\"))\ndraw!(f[1, 2], plt, scales(DodgeX = (; width = 0.75)), axis = (; title = \"width = 0.75\"))\ndraw!(f[2, 1], plt, scales(DodgeX = (; width = 0.5)), axis = (; title = \"width = 0.5\"))\ndraw!(f[2, 2], plt, scales(DodgeX = (; width = 0.25)), axis = (; title = \"width = 0.25\"))\nf","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"A common scenario is plotting errorbars on top of barplots. In this case, AlgebraOfGraphics can detect the inherent dodging width of the barplots and adjust accordingly for the errorbars. Note in this example how choosing a manual dodging width only applies to the errorbars (because the barplot plot type handles this internally) and potentially leads to a misalignment between the different plot elements:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (\n x = repeat(1:10, inner = 2),\n y = cos.(range(0, 2pi, length = 20)),\n ylow = cos.(range(0, 2pi, length = 20)) .- 0.2,\n yhigh = cos.(range(0, 2pi, length = 20)) .+ 0.3,\n dodge = repeat([\"A\", \"B\"], 10)\n)\n\nf = Figure()\nplt = data(df) * (\n mapping(:x, :y, dodge = :dodge, color = :dodge) * visual(BarPlot) +\n mapping(:x, :ylow, :yhigh, dodge_x = :dodge) * visual(Rangebars)\n)\ndraw!(f[1, 1], plt, axis = (; title = \"No width specified, auto-determined by AlgebraOfGraphics\"))\ndraw!(f[2, 1], plt, scales(DodgeX = (; width = 0.25)), axis = (; title = \"Manually specifying width = 0.25 leads to a mismatch\"))\nf","category":"page"},{"location":"layers/mapping/#Pair-syntax","page":"Mapping","title":"Pair syntax","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"The Pair operator => can be used for three different purposes within mapping:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"renaming columns\ntransforming columns by row\nmapping data to a custom scale","category":"page"},{"location":"layers/mapping/#Renaming-columns","page":"Mapping","title":"Renaming columns","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndata((; name = [\"Anna\", \"Beatrix\", \"Claire\"], height_meters = [1.55, 1.76, 1.63])) *\n mapping(:name => \"Name\", :height_meters => \"Height (m)\") *\n visual(BarPlot) |> draw ","category":"page"},{"location":"layers/mapping/#Transforming-columns","page":"Mapping","title":"Transforming columns","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"If a Function is paired to the column selector, it is applied by row to the data. Often, you will want to also assign a new name that fits the transformed data, in which case you can use the three-element column => transformation => name syntax:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndata((; name = [\"Anna\", \"Beatrix\", \"Claire\"], height_meters = [1.55, 1.76, 1.63])) *\n mapping(:name => (n -> n[1] * \".\"), :height_meters => (x -> x * 100) => \"Height (cm)\") *\n visual(BarPlot) |> draw","category":"page"},{"location":"layers/mapping/#Row-by-row-versus-whole-column-operations","page":"Mapping","title":"Row-by-row versus whole-column operations","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"The pair syntax acts row by row, unlike, e.g., DataFrames.transform. This has several advantages.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Simpler for the user in most cases.\nLess error prone especially\nwith grouped data (should a column operation apply to each group or the whole dataset?)\nwhen several datasets are used","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Naturally, this also incurs some downsides, as whole-column operations, such as z-score standardization, are not supported: they should be done by adding a new column to the underlying dataset beforehand.","category":"page"},{"location":"layers/mapping/#Functions-of-several-arguments","page":"Mapping","title":"Functions of several arguments","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"In the case of functions of several arguments, such as isequal, the input variables must be passed as a Tuple.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"accuracy = (:species, :predicted_species) => isequal => \"accuracy\"","category":"page"},{"location":"layers/mapping/#Helper-functions","page":"Mapping","title":"Helper functions","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Some helper functions are provided, which can be used within the pair syntax to either rename and reorder unique values of a categorical column on the fly or to signal whether a numerical column should be treated as categorical.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"The complete API of helper functions is available at Mapping helpers, but here are a few examples:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"# column `train` has two unique values, `true` and `false`\n:train => renamer([true => \"training\", false => \"testing\"]) => \"Dataset\"\n# column `price` has three unique values, `\"low\"`, `\"medium\"`, and `\"high\"`\n:price => sorter([\"low\", \"medium\", \"high\"])\n# column `age` is expressed in integers and we want to treat it as categorical\n:age => nonnumeric\n# column `labels` is expressed in strings and we do not want to treat it as categorical\n:labels => verbatim\n# wrap categorical values to signal that the order from the data source should be respected\n:weight => presorted","category":"page"},{"location":"layers/mapping/#Custom-scales","page":"Mapping","title":"Custom scales","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"All columns mapped to the same aesthetic type are represented using the same scale by default. This is evident if you plot two different datasets with two different plot types.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"In the following example, both Scatter and HLines use the Color aesthetic, Scatter for the strokecolor keyword and HLines for color. A single merged legend is rendered for both, which does not have a title because it derives from two differently named columns.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf_a = (; x = 1:9, y = [1, 2, 3, 5, 6, 7, 9, 10, 11], group = repeat([\"A\", \"B\", \"C\"], inner = 3))\n\nspec1 = data(df_a) * mapping(:x, :y, strokecolor = :group) * visual(Scatter, color = :transparent, strokewidth = 3, markersize = 15)\n\ndf_b = (; y = [4, 8], threshold = [\"first\", \"second\"])\n\nspec2 = data(df_b) * mapping(:y, color = :threshold) * visual(HLines)\n\ndraw(spec1 + spec2)","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"If we want to have separate legends for both, we can assign a custom scale identifier to either the strokecolor or the color mapping. The name can be chosen freely, it serves only to disambiguate.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"spec2_custom_scale = data(df_b) * mapping(:y, color = :threshold => scale(:color2)) * visual(HLines)\n\ndraw(spec1 + spec2_custom_scale)","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Each scale can be customized further by passing configuration options via scales as the second argument of the draw function. More information on scale options can be found under Scale options.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"As an example, we can pass separate colormaps using the palette keyword:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"spec2_custom_scale = data(df_b) * mapping(:y, color = :threshold => scale(:color2)) * visual(HLines)\n\ndraw(\n spec1 + spec2_custom_scale,\n scales(\n Color = (; palette = [:red, :green, :blue]),\n color2 = (; palette = [:gray30, :gray80]),\n )\n)","category":"page"},{"location":"changelog/#Changelog","page":"Changelog","title":"Changelog","text":"","category":"section"},{"location":"changelog/#Unreleased","page":"Changelog","title":"Unreleased","text":"","category":"section"},{"location":"changelog/#v0.8.14-2025-01-16","page":"Changelog","title":"v0.8.14 - 2025-01-16","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added automatic alpha forwarding to all legend elements which will have an effect from Makie 0.22.1 on #588.\nAdded the ability to use multiple different X and Y scales within one facet layout. The requirement is that not more than one X and Y scale is used per facet. Row, Col and Layout scales got the ability to set show_labels = false in scales. Also added the zerolayer function which can be used as a basis to build up the required mappings iteratively #586.\nIncreased compat to Makie 0.22 and GeometryBasics 0.5 #587.\nIncreased compat to Colors 0.13 #589.","category":"page"},{"location":"changelog/#v0.8.13-2024-10-21","page":"Changelog","title":"v0.8.13 - 2024-10-21","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added aesthetics for Stairs #573.","category":"page"},{"location":"changelog/#v0.8.12-2024-10-07","page":"Changelog","title":"v0.8.12 - 2024-10-07","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added legend keyword in visual to allow overriding legend element attributes #570.","category":"page"},{"location":"changelog/#v0.8.11-2024-09-25","page":"Changelog","title":"v0.8.11 - 2024-09-25","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixed lexicographic natural sorting of tuples (this would fall back to default sort order before) #568.","category":"page"},{"location":"changelog/#v0.8.10-2024-09-24","page":"Changelog","title":"v0.8.10 - 2024-09-24","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixed markercolor in ScatterLines legends when it did not match color #567.","category":"page"},{"location":"changelog/#v0.8.9-2024-09-24","page":"Changelog","title":"v0.8.9 - 2024-09-24","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added ability to include layers in the legend without using scales by adding visual(label = \"some label\") #565.","category":"page"},{"location":"changelog/#v0.8.8-2024-09-17","page":"Changelog","title":"v0.8.8 - 2024-09-17","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixed aesthetics of errorbar so that x and y stay labelled correctly when using direction = :x #560.\nAdded ability to specify title, subtitle and footnotes plus settings in the draw function #556.\nAdded dodge_x and dodge_y keywords to mapping that allow to dodge any plot types that have AesX or AesY data #558.","category":"page"},{"location":"changelog/#v0.8.7-2024-09-06","page":"Changelog","title":"v0.8.7 - 2024-09-06","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added ability to return ProcessedLayers from transformations, thereby enabling multi-layer transformations, such as scatter plus errorbars #549.\nFixed bug where mergesorted applied on string vectors used isless instead of natural sort #553.","category":"page"},{"location":"changelog/#v0.8.6-2024-09-02","page":"Changelog","title":"v0.8.6 - 2024-09-02","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added bar_labels to BarPlot's aesthetic mapping #544.\nAdded ability to hide legend or colorbar by passing, e.g., legend = (; show = false) to draw #547.","category":"page"},{"location":"changelog/#v0.8.5-2024-08-27","page":"Changelog","title":"v0.8.5 - 2024-08-27","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added presorted helper function to keep categorical data in the order encountered in the source table, instead of sorting it alphabetically #529.\nAdded from_continuous helper function which allows to sample continuous colormaps evenly to use them as categorical palettes without having to specify how many categories there are #541.","category":"page"},{"location":"changelog/#v0.8.4-2024-08-26","page":"Changelog","title":"v0.8.4 - 2024-08-26","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added fillto to BarPlot aesthetics #535.\nFixed bug when giving datalimits of density as a (low, high) tuple #536.\nFixed bug where facet-local continuous scale limits were used instead of the globally merged ones, possibly leading to mismatches between data and legend #539.","category":"page"},{"location":"changelog/#v0.8.3-2024-08-23","page":"Changelog","title":"v0.8.3 - 2024-08-23","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixed incorrect x/y axis assignment for the violin plot type #528.","category":"page"},{"location":"changelog/#v0.8.2-2024-08-21","page":"Changelog","title":"v0.8.2 - 2024-08-21","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Enable use of LaTeXStrings and rich text in renamer #525.\nFixed widths of boxplots with color groupings #524.","category":"page"},{"location":"changelog/#v0.8.1-2024-08-20","page":"Changelog","title":"v0.8.1 - 2024-08-20","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added back support for Hist, CrossBar, ECDFPlot and Density #522.","category":"page"},{"location":"changelog/#v0.8.0-2024-07-26","page":"Changelog","title":"v0.8.0 - 2024-07-26","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: Columns with element types of Union{Missing,T} are not treated as categorical by default anymore, instead T decides if data is seen as categorical, continuous or geometrical. If you relied on numerical vectors with missings being treated as categorical, you can use :columnname => nonnumeric in the mapping instead.\nBreaking: AbstractString categories are now sorted with natural sort order by default. This means that where you got [\"1\", \"10\", \"2\"] before, you now get [\"1\", \"2\", \"10\"]. You can use sorter, the categories keyword or categorical arrays to sort your data differently if needed.","category":"page"},{"location":"changelog/#v0.7.0-2024-07-16","page":"Changelog","title":"v0.7.0 - 2024-07-16","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: The palette keyword of draw linking palettes to keyword arguments was removed. Instead, palettes need to be passed to specific scales like draw(..., scales(Color = (; palette = :Set1_3)))\nBreaking: All recipes need to have the new function aesthetic_mapping defined for all sets of positional arguments that should be supported, as can be seen in src/aesthetics.jl. This breaks usage of all custom recipes. Additionally, not all Makie plots have been ported to the new system yet. If you encounter missing plots, or missing attributes of already ported plots, please open an issue.\nBreaking: All custom recipes that should be displayed in a legend, need to have legend_elements(P, attributes, scale_args) defined as can be seen in src/guides/legend.jl. AlgebraOfGraphics cannot use the same default mechanism as Makie, which can create a legend from an existing plot, because AlgebraOfGraphics needs to create the legend before the plot is instantiated.\nBreaking: Pregrouped data cannot be passed anymore to the plain mapping(...) without any data(tabular). Instead, you should use pregrouped(...) which is a shortcut for data(Pregrouped()) * mapping(...).\nBreaking: Contour and Contourf generally do not work anymore with visual(). Instead, the contours() and filled_contours() analyses should be used. Contour can still be used with categorical colors, but not with continuous ones.\nBreaking: All colormap properties for continuous color scales need to be passed via scales now, and not through visual. This is to have central control over the scale as it can be used by multiple visuals simultaneously.\nHorizontal barplots, violins, errorbars, rangebars and other plot types that have two different orientations work correctly now. Axis labels switch accordingly when the orientation is changed.\nPlotting functions whose positional arguments don't correspond to X, Y, Z work correctly now. For example, HLines (1 => Y) or rangebars (1 => X, 2 => Y, 3 => Y).\nIt is possible to add categories beyond those present in the data with the categories keyword within a scale's settings. It is also possible to reorder or otherwise transform the existing categories by passing a function to categories.\nThe supported attributes are not limited anymore to a specific set of names, for example, strokecolor can work the same as color did before, and the two can share a scale via their shared aesthetic type.\nThere can be multiple scales of the same aesthetic now. This allows to have separate legends for different plot types using the same aesthetics. Scale separation works by pairing a variable in mapping with a scale(id_symbol).\nLegend entries can be reordered using the legend = (; order = ...) option in draw. Specific scales can opt out of the legend by passing legend = false in scales.\nLabels can now be anything that Makie supports, primarily Strings, LaTeXStrings or rich text.\nLegend elements now usually reflect all attributes set in their corresponding visual.\nSimple column vectors of data can now be passed directly to mapping without using data first. Additionally, scalar values are accepted as a shortcut for columns with the same repeated value.\nColumns from outside a table source in data can now be passed to mapping by wrapping them in the direct function. Scalar values are accepted as a shortcut for columns with the same repeated value. For example, to create a label for columns x and y from a dataframe passed to data, one could now do mapping(:x, :y, color = direct(\"label\")) without having to create a column full of \"label\" strings first.\nThe numbers at which categorical values are plotted on x and y axis can now be changed via scales(X = (; palette = [1, 2, 4])) or similar.\nContinuous marker size scales can now be shown in the legend. Numerical values are proportional to area and not diameter now, which makes more sense with respect to human perception. The min and max marker size can be set using the sizerange property for the respective scale in scales.","category":"page"},{"location":"changelog/#v0.6.11-2022-08-08","page":"Changelog","title":"v0.6.11 - 2022-08-08","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added paginate for pagination of large facet plots. ","category":"page"},{"location":"changelog/#v0.6.8-2022-06-14","page":"Changelog","title":"v0.6.8 - 2022-06-14","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added choropleth recipe to supersede geodata for geographical data.","category":"page"},{"location":"changelog/#v0.6.1-2022-01-28","page":"Changelog","title":"v0.6.1 - 2022-01-28","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Support level in linear analysis for confidence interval.\nReplaced tuples and named tuples in Layer and Entry with dictionaries from Dictionaries.jl.\nSplit internal Entry type into ProcessedLayer (to be used for analyses) and Entry (to be used for plotting).","category":"page"},{"location":"changelog/#v0.6.0-2021-10-24","page":"Changelog","title":"v0.6.0 - 2021-10-24","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: Default axis linking behavior has changed: now only axes corresponding to the same variable are linked. For consistency with row/col, layout will hide decorations of linked axes and span axis labels if appropriate.\nCustomizable legend and colorbar position and look.\nCustomizable axis linking behavior.","category":"page"},{"location":"changelog/#v0.5-2021-08-05","page":"Changelog","title":"v0.5 - 2021-08-05","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: Axis(ae) has been replaced by ae.axis.\nBreaking: Legend(fg) has been replaced by legend!(fg) and colorbar!(fg).\nlegend! and colorbar! API allows for custom legend placement.","category":"page"},{"location":"changelog/#v0.4-2021-05-21","page":"Changelog","title":"v0.4 - 2021-05-21","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: Removed deprecations for style and spec (now only mapping and visual are allowed).\nBreaking: Analyses now require parentheses (i.e. linear() instead of linear).\nBreaking: Rename layout_x and layout_y to col and row.\nBreaking: Rename wts keyword argument to weights.\nBreaking: categorical has been replaced by nonnumeric.","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/statistical analyses/density_plots.jl\"","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/#Density-plots","page":"Density plots","title":"Density plots","text":"","category":"section"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"using AlgebraOfGraphics, CairoMakie\nusing AlgebraOfGraphics: density\n\ndf = (x=randn(1000), c=rand([\"a\", \"b\"], 1000))\nplt = data(df) * mapping(:x, color=:c) * density(bandwidth=0.5)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"df = (x=randn(1000), c=rand([\"a\", \"b\"], 1000))\nplt = data(df) * mapping(:x, color=:c) * density(bandwidth=0.5) * visual(orientation=:vertical)\n\"Not yet supported\" # hide","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"\"Not yet supported\"","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"API/types/#Types","page":"Types","title":"Types","text":"","category":"section"},{"location":"API/types/","page":"Types","title":"Types","text":"AlgebraOfGraphics.AbstractDrawable\nAlgebraOfGraphics.AbstractAlgebraic\nAlgebraOfGraphics.Layer\nAlgebraOfGraphics.Layers\nAlgebraOfGraphics.zerolayer\nAlgebraOfGraphics.ProcessedLayer\nAlgebraOfGraphics.ProcessedLayers\nAlgebraOfGraphics.Entry\nAlgebraOfGraphics.AxisEntries","category":"page"},{"location":"API/types/#AlgebraOfGraphics.AbstractDrawable","page":"Types","title":"AlgebraOfGraphics.AbstractDrawable","text":"AbstractDrawable\n\nAbstract type encoding objects that can be drawn via AlgebraOfGraphics.draw.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.AbstractAlgebraic","page":"Types","title":"AlgebraOfGraphics.AbstractAlgebraic","text":"AbstractAlgebraic <: AbstractDrawable\n\nAbstract type encoding objects that can be combined together using + and *.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.Layer","page":"Types","title":"AlgebraOfGraphics.Layer","text":"Layer(transformation, data, positional::AbstractVector, named::AbstractDictionary)\n\nAlgebraic object encoding a single layer of a visualization. It is composed of a dataset, positional and named arguments, as well as a transformation to be applied to those. Layer objects can be multiplied, yielding a novel Layer object, or added, yielding a AlgebraOfGraphics.Layers object.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.Layers","page":"Types","title":"AlgebraOfGraphics.Layers","text":"Layers(layers::Vector{Layer})\n\nAlgebraic object encoding a list of AlgebraOfGraphics.Layer objects. Layers objects can be added or multiplied, yielding a novel Layers object.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.zerolayer","page":"Types","title":"AlgebraOfGraphics.zerolayer","text":"zerolayer()\n\nReturns a Layers with an empty layer list which can act as a zero in the layer algebra.\n\nlayer * zerolayer() ~ zerolayer()\nlayer + zerolayer() ~ layer\n\n\n\n\n\n","category":"function"},{"location":"API/types/#AlgebraOfGraphics.ProcessedLayer","page":"Types","title":"AlgebraOfGraphics.ProcessedLayer","text":"ProcessedLayer(l::Layer)\n\nProcess a Layer and return the resulting ProcessedLayer.\n\nNote that this method should not be used anymore as processing a Layer can now potentially return multiple ProcessedLayer objects. Therefore, you should use the plural form ProcessedLayers(layer).\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.ProcessedLayers","page":"Types","title":"AlgebraOfGraphics.ProcessedLayers","text":"ProcessedLayers(layers::Vector{ProcessedLayer})\n\nObject encoding a list of AlgebraOfGraphics.ProcessedLayer objects. ProcessedLayers objects are the output of the processing pipeline and can be drawn without further processing.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.Entry","page":"Types","title":"AlgebraOfGraphics.Entry","text":"Entry(plottype::PlotType, positional::Arguments, named::NamedArguments)\n\nDefine plottype as well as positional and named arguments for a single plot.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.AxisEntries","page":"Types","title":"AlgebraOfGraphics.AxisEntries","text":"AxisEntries(axis::Union{Axis, Nothing}, entries::Vector{Entry}, categoricalscales, continuousscales)\n\nDefine all ingredients to make plots on an axis. Each categorical scale should be a CategoricalScale, and each continuous scale should be a ContinuousScale.\n\n\n\n\n\n","category":"type"},{"location":"API/recipes/#Recipes","page":"Recipes","title":"Recipes","text":"","category":"section"},{"location":"API/recipes/","page":"Recipes","title":"Recipes","text":"choropleth\nlinesfill","category":"page"},{"location":"API/recipes/#AlgebraOfGraphics.choropleth","page":"Recipes","title":"AlgebraOfGraphics.choropleth","text":"choropleth(geometries; transformation, attributes...)\n\nChoropleth map, where regions are defined by geometries. Use transformation to transform coordinates (see Proj.jl for more information).\n\nwarning: Warning\nThe transformation keyword argument is experimental and could be deprecated (even in a non-breaking release) in favor of a different syntax.\n\nAttributes\n\nAvailable attributes and their defaults for Plot{AlgebraOfGraphics.choropleth} are: \n\n alpha 1.0\n clip_planes MakieCore.Automatic()\n color :gray25\n colormap :batlow\n colorrange MakieCore.Automatic()\n colorscale identity\n cycle [:color => :patchcolor]\n depth_shift 0.0f0\n highclip MakieCore.Automatic()\n inspectable true\n inspector_clear MakieCore.Automatic()\n inspector_hover MakieCore.Automatic()\n inspector_label MakieCore.Automatic()\n joinstyle :miter\n linecap :butt\n linestyle \"nothing\"\n lowclip MakieCore.Automatic()\n miter_limit 1.0471975511965976\n nan_color :transparent\n overdraw false\n shading NoShading\n space :data\n ssao false\n stroke_depth_shift -1.0f-5\n strokecolor :black\n strokecolormap :batlow\n strokewidth 0\n transparency false\n visible true\n\n\n\n\n\n","category":"function"},{"location":"API/recipes/#AlgebraOfGraphics.linesfill","page":"Recipes","title":"AlgebraOfGraphics.linesfill","text":"linesfill(xs, ys; lower, upper, attributes...)\n\nLine plot with a shaded area between lower and upper. If lower and upper are not given, shaded area is between 0 and ys.\n\nAttributes\n\nAvailable attributes and their defaults for Plot{AlgebraOfGraphics.linesfill} are: \n\n color :gray25\n colormap :batlow\n colorrange MakieCore.Automatic()\n fillalpha 0.15\n linestyle \"nothing\"\n linewidth 1.5\n lower MakieCore.Automatic()\n upper MakieCore.Automatic()\n\n\n\n\n\n","category":"function"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/data manipulations/no_data.jl\"","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/#Using-mapping-without-tabular-data","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"Sometimes it's easier to specify columnar data directly within mapping rather than first storing it in some tabular data source and accessing it by column name. Note that you can also use scalar values which will be treated like columns with repeated elements. In the example below, we specify color = \"marker\" instead of the more verbose color = fill(\"marker\", 3).","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"using AlgebraOfGraphics, CairoMakie\n\nx = 1:100\ny = sin.(range(0, 2pi, length = 100))\n\nplt = mapping(x, y, color = repeat([\"high\", \"low\"], inner = 50)) *\n visual(Lines) +\n mapping([20, 28, 51], color = \"marker\" => scale(:secondary)) *\n visual(VLines, linestyle = :dash)\n\nfg = draw(plt, scales(secondary = (; palette = [:gray80])))","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"layers/data/#Data","page":"Data","title":"Data","text":"","category":"section"},{"location":"layers/data/","page":"Data","title":"Data","text":"data","category":"page"},{"location":"layers/data/#AlgebraOfGraphics.data","page":"Data","title":"AlgebraOfGraphics.data","text":"data(table)\n\nCreate a Layer with its data field set to a table-like object.\n\nThere are no type restrictions on this object, as long as it respects the Tables interface. In particular, any one of these formats should work out of the box.\n\nTo create a fully specified layer, the layer created with data needs to be multiplied with the output of mapping.\n\nspec = data(...) * mapping(...)\n\n\n\n\n\n","category":"function"},{"location":"layers/data/","page":"Data","title":"Data","text":"using AlgebraOfGraphics\ndf = (a = rand(10), b = rand(10))\ndata(df)","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/applications/time_series.jl\"","category":"page"},{"location":"gallery/gallery/applications/time_series/#Time-series","page":"Time series","title":"Time series","text":"","category":"section"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"using AlgebraOfGraphics, CairoMakie\nusing Dates\n\nx = today() - Year(1) : Day(1) : today()\ny = cumsum(randn(length(x)))\nz = cumsum(randn(length(x)))\ndf = (; x, y, z)\nlabels = [\"series 1\", \"series 2\", \"series 3\", \"series 4\", \"series 5\"]\nplt = data(df) *\n mapping(:x, [:y, :z] .=> \"value\", color=dims(1) => renamer(labels) => \"series \") *\n visual(Lines)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"(Image: )","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"x = now() - Hour(6) : Minute(1) : now()\ny = cumsum(randn(length(x)))\nz = cumsum(randn(length(x)))\ndf = (; x, y, z)\nplt = data(df) *\n mapping(:x, [:y, :z] .=> \"value\", color=dims(1) => renamer(labels) =>\"series \") *\n visual(Lines)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"(Image: )","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"dates = Date(2022, 1, 1):Day(1):Date(2022, 1, 31)\ntrend = cumsum(randn(31))\ndf = map(1:2000) do _\n idx = rand(1:31)\n date = dates[idx]\n observation = trend[idx] + 2 * rand()\n return (; date, observation)\nend\nplt = data(df) * mapping(:date, :observation) * visual(BoxPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"(Image: )","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"layers/draw/#Drawing-Layers","page":"Drawing Layers","title":"Drawing Layers","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"A AlgebraOfGraphics.Layer or AlgebraOfGraphics.Layers object can be plotted using the functions draw or draw!.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Whereas draw automatically adds colorbar and legend, draw! does not, as it would be hard to infer a good default placement that works in all scenarios.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Colorbar and legend, should they be necessary, can be added separately with the colorbar! and legend! helper functions. See also Nested layouts for a complex example.","category":"page"},{"location":"layers/draw/#Scale-options","page":"Drawing Layers","title":"Scale options","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"All properties that decide how scales are visualized can be modified by passing scale options (using the scales function) as the second argument of draw . The properties that are accepted differ depending on the scale aesthetic type (for example Color, Marker, LineStyle) and whether the scale is categorical or continuous.","category":"page"},{"location":"layers/draw/#Shared-categorical-scale-options","page":"Drawing Layers","title":"Shared categorical scale options","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The palette and categories options are implemented across all categorical scale types.","category":"page"},{"location":"layers/draw/#palette","page":"Drawing Layers","title":"palette","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The palette decides which attribute values are passed to Makie's plotting functions for each categorical value in the scale.","category":"page"},{"location":"layers/draw/#Color","page":"Drawing Layers","title":"Color","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"A Symbol is converted to a colormap with Makie.to_colormap. ","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = 'A':'J')) *\n mapping(:x, :y, color = :z) *\n visual(BarPlot)\ndraw(spec, scales(Color = (; palette = :tab10)))","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"It's also possible to directly specify a vector of colors, each of which Makie.to_color can handle:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\nusing CairoMakie.Colors: RGB, RGBA, Gray, HSV\n\nspec = data((; x = 1:10, y = 1:10, z = 'A':'J')) *\n mapping(:x, :y, color = :z) *\n visual(BarPlot)\ndraw(spec, scales(Color = (; palette = [:red, :green, :blue, RGB(1, 0, 1), RGB(1, 1, 0), \"#abcff0\", \"#c88cbccc\", HSV(0.9, 0.3, 0.7), RGBA(0.7, 0.9, 0.6, 0.5), Gray(0.5)])))","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"If you want to use a continuous colormap for categorical data, you can use the from_continuous helper function. It automatically takes care that the continuous colormap is sampled evenly from start to end depending on the number of categories. Any colormap that Makie understands can be passed, including named colormaps such as :viridis.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"This example shows the difference in behavior when the two-element colormap [:red, :blue] is used with or without from_continuous:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = 'A':'J')) *\n mapping(:x, :y, color = :z) *\n visual(BarPlot)\n\nf = Figure()\nfg1 = draw!(f[1, 1], spec, scales(Color = (; palette = [:red, :blue])))\nlegend!(f[1, 2], fg1)\nfg2 = draw!(f[1, 3], spec, scales(Color = (; palette = from_continuous([:red, :blue]))))\nlegend!(f[1, 4], fg2)\nf","category":"page"},{"location":"layers/draw/#Marker","page":"Drawing Layers","title":"Marker","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"A vector of values that Makie.to_spritemarker can handle.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = 'A':'J')) *\n mapping(:x, :y, marker = :z) *\n visual(Scatter, markersize = 20)\n\ndraw(\n spec,\n scales(\n Marker = (; palette = [:rect, :circle, :utriangle, :dtriangle, :diamond, :hline, :vline, :star5, :star6, :hexagon])\n )\n)","category":"page"},{"location":"layers/draw/#LineStyle","page":"Drawing Layers","title":"LineStyle","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"A vector of values that Makie.to_linestyle can handle.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = repeat('A':'E', inner = 2))) *\n mapping(:x, :y, linestyle = :z) *\n visual(Lines, linewidth = 2)\n\ndraw(spec, scales(\n LineStyle = (; palette = [:solid, :dash, :dot, (:dot, :loose), Linestyle([0, 1, 2, 3, 4, 8])])\n))","category":"page"},{"location":"layers/draw/#X-and-Y","page":"Drawing Layers","title":"X & Y","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The \"palette\" values for X and Y axes are by default simply the numbers from 1 to N, the number of categories. In some circumstances, it might be useful to change these values, for example to visualize that one category is different than others. The palette values are normally assigned category-by-category in the sorted order, or in the order provided manually through the categories keyword. However, if you pass a vector of values, you can always use the category => value pair option to assign a specific category directly to a value, while the others cycle. Here, we do this with \"Unknown\" as it would otherwise be sorted before \"X\".","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (; group = [\"A\", \"B\", \"C\", \"X\", \"Y\", \"Unknown\"], count = [45, 10, 20, 32, 54, 72])\n\nspec = data(df) * mapping(:group, :count) * visual(BarPlot)\n\ndraw(spec, scales(X = (; palette = [1, 2, 3, 5, 6, \"Unknown\" => 8])))","category":"page"},{"location":"layers/draw/#Layout","page":"Drawing Layers","title":"Layout","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Normally, with the Layout aesthetic, rows wrap automatically such that an approximately square distribution of facets is attained. You can overwrite these values, however, to place axes at manually chosen positions:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (;\n group = repeat([\"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\"], inner = 20),\n x = randn(160),\n y = randn(160)\n)\n\nspec = data(df) * mapping(:x, :y, layout = :group) * visual(Scatter)\n\nclockwise = [(1, 1), (1, 2), (1, 3), (2, 3), (3, 3), (3, 2), (3, 1), (2, 1)]\n\ndraw(spec, scales(Layout = (; palette = clockwise)))","category":"page"},{"location":"layers/draw/#categories","page":"Drawing Layers","title":"categories","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The categories keyword can be used to reorder, label and even add categorical values.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Some reordering and renaming can be done using the sorter and renamer helper functions applied directly to columns in mapping. However, this works less well when several data sources are combined where not all categories appear in each column. Also, no categories can be added this way, which is something that can be useful if the existence of categories should be shown even though there is no data for them.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"New labels can be assigned using the value => label pair syntax.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; group = [\"A\", \"C\", \"D\"], value = [1, 3, 4])) *\n mapping(:group, :value) * visual(BarPlot)\n\nf = Figure()\n\ndraw!(f[1, 1], spec, scales(\n X = (; categories = [\"A\", \"B\", \"C\", \"D\"])\n))\ndraw!(f[1, 2], spec, scales(\n X = (; categories = [\"D\", \"A\", \"C\"])\n))\ndraw!(f[1, 3], spec, scales(\n X = (; categories = [\"A\" => \"a\", \"C\" => \"c\", \"D\" => \"d\"])\n))\n\nf","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"You can also pass a Function to categories which should take the vector of category values and return a new vector of categories or category/label pairs.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"For example, you could add summary statistics to the facet layout titles this way, by grabbing them from a dictionary computed separately.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nsummary_stats = Dict(\"A\" => 1.32, \"B\" => 4.19, \"C\" => 0.04)\n\ndf = (;\n x = randn(90),\n y = randn(90) .+ repeat([0, 5, 10], inner = 30),\n group = repeat([\"A\", \"B\", \"C\"], inner = 30)\n)\n\nspec = data(df) * mapping(:x, :y, col = :group) * visual(Scatter)\n\ndraw(spec, scales(Col = (;\n categories = cats -> [\n cat => rich(\"$cat\\n\", rich(\"λ = $(summary_stats[cat])\", font = :italic))\n for cat in reverse(cats)\n ]\n)))","category":"page"},{"location":"layers/draw/#Special-categorical-scale-options","page":"Drawing Layers","title":"Special categorical scale options","text":"","category":"section"},{"location":"layers/draw/#Row,-Col-and-Layout","page":"Drawing Layers","title":"Row, Col & Layout","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"All three facetting scales have the option show_labels which is true by default and can be set to false to hide the facet labels.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"This example shows the behavior for Col only:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((;\n x = 1:16,\n y = 17:32,\n group1 = repeat([\"A\", \"B\"], inner = 8),\n group2 = repeat([\"C\", \"D\"], 8))\n) * mapping(:x, :y, row = :group1, col = :group2) * visual(Scatter)\n\ndraw(spec, scales(Col = (; show_labels = false)))","category":"page"},{"location":"layers/draw/#Continuous-scale-options","page":"Drawing Layers","title":"Continuous scale options","text":"","category":"section"},{"location":"layers/draw/#Color-2","page":"Drawing Layers","title":"Color","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Continuous color scales can be modified using the familiar Makie attributes colormap, colorrange, highclip, lowclip and nan_color. By default, colorrange is set to the extrema of the encountered values, so no clipping occurs.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = [1:4; NaN; 6:10])) *\n mapping(:x, :y, color = :z) *\n visual(Scatter, markersize = 20)\n\ndraw(spec, scales(\n Color = (;\n colormap = :plasma,\n nan_color = :cyan,\n lowclip = :lime,\n highclip = :red,\n colorrange = (2, 9)\n )\n))","category":"page"},{"location":"layers/draw/#MarkerSize","page":"Drawing Layers","title":"MarkerSize","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The range of marker sizes can be set with the sizerange attribute. Marker sizes are computed such that their area, and not markersize itself, grows linearly with the scale values. ","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = 10:10:100)) *\n mapping(:x, :y, markersize = :z) *\n visual(Scatter)\n\nf = Figure()\n\ngrid = draw!(f[1, 1], spec, scales(\n MarkerSize = (;\n sizerange = (5, 15)\n )\n))\nlegend!(f[1, 2], grid)\n\ngrid2 = draw!(f[2, 1], spec, scales(\n MarkerSize = (;\n sizerange = (5, 30)\n )\n))\nlegend!(f[2, 2], grid2)\n\nf","category":"page"},{"location":"layers/draw/#Legend-options","page":"Drawing Layers","title":"Legend options","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The legend keyword forwards most attributes to Makie's Legend function. The exceptions are listed here.","category":"page"},{"location":"layers/draw/#order","page":"Drawing Layers","title":"order","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"By default, the legend order depends on the order in which layers and mappings have been defined, as well as whether scales are categorical or continuous.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (;\n x = 1:12,\n y = 1:12,\n z = 1:12,\n group1 = repeat([\"A\", \"B\", \"C\"], inner = 4),\n group2 = repeat([\"X\", \"Y\"], 6),\n)\n\nspec = data(df) *\n mapping(:x, :y, markersize = :z, color = :group1, marker = :group2) *\n visual(Scatter)\n\ndraw(spec)","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"You can reorder the legend with the order keyword. This expects a vector with either Symbols or Vector{Symbol}s as elements, where each Symbol is the identifier for a scale that's represented in the legend.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Plain Symbols can be used for simple reordering:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"draw(spec; legend = (; order = [:MarkerSize, :Color, :Marker]))","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Symbols that are grouped into Vectors indicate that their groups should be merged together. For example, consider this plot that features two color scales, but one for a scatter plot and one for a line plot.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf_a = (; x = 1:9, y = [1, 2, 3, 5, 6, 7, 9, 10, 11], group = repeat([\"A\", \"B\", \"C\"], inner = 3))\n\nspec1 = data(df_a) * mapping(:x, :y, strokecolor = :group) * visual(Scatter, color = :transparent, strokewidth = 3, markersize = 15)\n\ndf_b = (; y = [4, 8], threshold = [\"first\", \"second\"])\n\nspec2_custom_scale = data(df_b) * mapping(:y, color = :threshold => scale(:color2)) * visual(HLines)\n\ndraw(spec1 + spec2_custom_scale)","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"You can group the two scales together using order. The titles are dropped.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"draw(spec1 + spec2_custom_scale; legend = (; order = [[:Color, :color2]]))","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"If you want to add a title to a merged group, you can add it with the group => title pair syntax:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"draw(spec1 + spec2_custom_scale; legend = (; order = [[:Color, :color2] => \"Title\"]))","category":"page"},{"location":"layers/draw/#Figure-options","page":"Drawing Layers","title":"Figure options","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"AlgebraOfGraphics can add a title, subtitle and footnotes to a figure automatically. Settings for these must be passed to the figure keyword. Check the draw function for a complete list.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = pregrouped(\n fill(1:5, 6),\n fill(11:15, 6),\n [reshape(sin.(1:25), 5, 5) .+ i for i in 1:6],\n layout = 1:6 => nonnumeric) * visual(Heatmap)\n\ndraw(\n spec;\n figure = (;\n title = \"Numbers in square configuration\",\n subtitle = \"Arbitrary data exhibits sinusoidal properties\",\n footnotes = [\n rich(superscript(\"1\"), \"First footnote\"),\n rich(superscript(\"2\"), \"Second \", rich(\"footnote\", color = :red)),\n ],\n ),\n axis = (; width = 100, height = 100)\n)","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = AlgebraOfGraphics","category":"page"},{"location":"#Introduction","page":"Home","title":"Introduction","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"AlgebraOfGraphics defines a language for data visualization. It is based on a few simple building blocks that can be combined using + and *.","category":"page"},{"location":"","page":"Home","title":"Home","text":"This package can be installed typing","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> import Pkg; Pkg.add(\"AlgebraOfGraphics\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"in the Julia REPL.","category":"page"},{"location":"","page":"Home","title":"Home","text":"See the Tutorial to get started.","category":"page"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/legend_merging.jl\"","category":"page"},{"location":"gallery/gallery/scales/legend_merging/#Legend-merging","page":"Legend merging","title":"Legend merging","text":"","category":"section"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"using AlgebraOfGraphics, CairoMakie\n\nN = 40\n\nx = [1:N; 1:N]\ny = [cumsum(randn(N)); cumsum(randn(N))]\ngrp = [fill(\"a\", N); fill(\"b\", N)]\n\ndf = (; x, y, grp)\n\nlayers = visual(Lines) + visual(Scatter) * mapping(marker = :grp)\nplt = data(df) * layers * mapping(:x, :y, color = :grp)\n\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"","category":"page"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/statistical analyses/regression_plots.jl\"","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/#Regression-plots","page":"Regression plots","title":"Regression plots","text":"","category":"section"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"using AlgebraOfGraphics, CairoMakie\n\nx = rand(100)\ny = @. randn() + x\ndf = (; x, y)\nxy = data(df) * mapping(:x, :y)\nlayers = linear() + visual(Scatter)\ndraw(layers * xy)","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"x = rand(100)\ny = @. randn() + 5 * x ^ 2\ndf = (; x, y)\nxy = data(df) * mapping(:x, :y)\nlayers = smooth() + visual(Scatter)\nfg = draw(layers * xy)","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/continuous_scales.jl\"","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/#Continuous-scales","page":"Continuous scales","title":"Continuous scales","text":"","category":"section"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"using AlgebraOfGraphics, CairoMakie\n\nx = 1:100\ny = @. sqrt(x) + 20x + 100\ndf = (; x, y)\nplt = data(df) *\n mapping(\n :x,\n :y => log => \"√x + 20x + 100 (log scale)\",\n ) * visual(Lines)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"x = 1:100\ny = @. sqrt(x) + 20x + 100\ndf = (; x, y)\nplt = data(df) *\n mapping(\n :x,\n :y => \"√x + 20x + 100 (log scale)\",\n ) * visual(Lines)\ndraw(plt, axis=(yscale=log,))","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"x = 0:100\ny = @. 0.01 + x/1000\ndf = (; x, y)\nplt = data(df) *\n mapping(\n :x,\n :y => \"y\",\n ) * visual(Lines)\nfg = draw(plt, axis=(yscale=log,))","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"API/functions/#Functions","page":"Functions","title":"Functions","text":"","category":"section"},{"location":"API/functions/#Drawing-functions","page":"Functions","title":"Drawing functions","text":"","category":"section"},{"location":"API/functions/","page":"Functions","title":"Functions","text":"draw\ndraw!\ncolorbar!\nlegend!\npaginate\nscales","category":"page"},{"location":"API/functions/#AlgebraOfGraphics.draw","page":"Functions","title":"AlgebraOfGraphics.draw","text":"draw(d, scales::Scales = scales(); [axis, figure, facet, legend, colorbar])\n\nDraw a AlgebraOfGraphics.AbstractDrawable object d. In practice, d will often be a AlgebraOfGraphics.Layer or AlgebraOfGraphics.Layers. Scale options can be passed as an optional second argument. The output can be customized by passing named tuples or dictionaries with settings via the axis, figure, facet, legend or colorbar keywords. Legend and colorbar are drawn automatically unless show = false is passed to the keyword arguments of either legend or colorbar.\n\nFor finer control, use draw!, legend!, and colorbar! independently.\n\nFigure options\n\nAlgebraOfGraphics accepts the following special keywords under the figure keyword, the remaining attributes are forwarded to Makie's Figure constructor. The title, subtitle and footnotes arguments accept objects of any kind that Makie's Label or text function can handle, such as rich text.\n\n- `title`\n- `subtitle`\n- `titlesize::Union{Nothing,Float64}`\n- `subtitlesize::Union{Nothing,Float64}`\n- `titlealign::Union{Nothing,Symbol}`\n- `titlecolor`\n- `subtitlecolor`\n- `titlefont`\n- `subtitlefont`\n- `titlelineheight`\n- `subtitlelineheight`\n- `footnotes::Union{Nothing,Vector{Any}}`\n- `footnotesize::Union{Nothing,Float64}`\n- `footnotefont`\n- `footnotecolor`\n- `footnotealign`\n- `footnotelineheight`\n\n\n\n\n\ndraw(p::PaginatedLayers; kws...)\n\nDraw each element of PaginatedLayers p and return a Vector{FigureGrid}. Keywords kws are passed to the underlying draw calls.\n\n\n\n\n\ndraw(p::PaginatedLayers, i::Int; kws...)\n\nDraw the ith element of PaginatedLayers p and return a FigureGrid. Keywords kws are passed to the underlying draw call.\n\nYou can retrieve the number of elements using length(p).\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.draw!","page":"Functions","title":"AlgebraOfGraphics.draw!","text":"draw!(fig, d::AbstractDrawable, scales::Scales = scales(); [axis, facet])\n\nDraw a AlgebraOfGraphics.AbstractDrawable object d on fig. In practice, d will often be a AlgebraOfGraphics.Layer or AlgebraOfGraphics.Layers. fig can be a figure, a position in a layout, or an axis if d has no facet specification. The output can be customized by passing named tuples or dictionaries with settings via the axis or facet keywords.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.colorbar!","page":"Functions","title":"AlgebraOfGraphics.colorbar!","text":"colorbar!(figpos, grid; kwargs...)\n\nCompute colorbar for grid (which should be the output of draw!) and draw it in position figpos. Attributes allowed in kwargs are the same as MakieLayout.Colorbar.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.legend!","page":"Functions","title":"AlgebraOfGraphics.legend!","text":"legend!(figpos, grid; order = nothing, kwargs...)\n\nCompute legend for grid (which should be the output of draw!) and draw it in position figpos. All kwargs are forwarded to Makie's Legend constructor.\n\nThe order of scales represented in the legend can be changed with the order keyword. By default, legend sections are ordered the same as they appear in the plot specification. Assuming three scales Color, MarkerSize and custom exist in a spec, you can pass a vector to reorder them like [:MarkerSize, :custom, :Color], or merge multiple entries together with a nested vector like [[:MarkerSize, :custom], :Color], or give merged sections a title with the pair syntax [[:MarkerSize, :custom] => \"Merged group\", :Color].\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.paginate","page":"Functions","title":"AlgebraOfGraphics.paginate","text":"paginate(l; layout=nothing, row=nothing, col=nothing)\n\nPaginate l, the Layer or Layers object created by an AlgebraOfGraphics spec, to create a PaginatedLayers object. This contains a vector of layers where each layer operates on a subset of the input data.\n\nThe PaginatedLayers object can be passed to draw which will return a Vector{FigureGrid} rather than a single figure.\n\nThe keywords that limit the number of subplots on each page are the same that are used to specify facets in mapping:\n\nlayout: Maximum number of subplots in a wrapped linear layout.\nrow: Maximum number of rows in a 2D layout.\ncol: Maximum number of columns in a 2D layout.\n\nExample\n\nd = data((\n x = rand(1000),\n y = rand(1000),\n group1 = rand(string.('a':'i'), 1000),\n group2 = rand(string.('j':'r'), 1000),\n))\n\nlayer_1 = d * mapping(:x, :y, layout = :group1) * visual(Scatter)\npaginated_1 = paginate(layer_1, layout = 9)\nfiguregrids = draw(paginated_1)\n\nlayer_2 = d * mapping(:x, :y, row = :group1, col = :group2) * visual(Scatter)\npaginated_2 = paginate(layer_2, row = 4, col = 3)\nfiguregrid = draw(paginated_2, 1) # draw only the first grid\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.scales","page":"Functions","title":"AlgebraOfGraphics.scales","text":"scales(; kwargs...)\n\nCreate a Scales object containing properties for aesthetic scales that can be passed to draw and draw!. Each keyword should be the name of a scale in the spec that is being drawn. That can either be a default one like Color, Marker or LineStyle, or a custom scale name defined in a mapping using the scale function.\n\nThe values attached to the keywords must be dict-like, with Symbols as keys (such as NamedTuples).\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#Mapping-helpers","page":"Functions","title":"Mapping helpers","text":"","category":"section"},{"location":"API/functions/","page":"Functions","title":"Functions","text":"pregrouped\ndirect\nrenamer\nsorter\nnonnumeric\nverbatim\nscale\npresorted","category":"page"},{"location":"API/functions/#AlgebraOfGraphics.pregrouped","page":"Functions","title":"AlgebraOfGraphics.pregrouped","text":"pregrouped(positional...; named...)\n\nEquivalent to data(Pregrouped()) * mapping(positional...; named...). Refer to mapping for more information.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.direct","page":"Functions","title":"AlgebraOfGraphics.direct","text":"direct(x)\n\nReturn DirectData(x) which marks x for direct use in a mapping that's used with a table-like data source. As a result, x will be used directly as data, without lookup in the table. If x is not an AbstractArray, it will be expanded like fill(x, n) where n is the number of rows in the data source.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.renamer","page":"Functions","title":"AlgebraOfGraphics.renamer","text":"renamer(arr::Union{AbstractArray, Tuple})\n\nUtility to rename a categorical variable, as in renamer([value1 => label1, value2 => label2]). The keys of all pairs should be all the unique values of the categorical variable and the values should be the corresponding labels. The order of arr is respected in the legend.\n\nExamples\n\njulia> r = renamer([\"class 1\" => \"Class One\", \"class 2\" => \"Class Two\"])\nAlgebraOfGraphics.Renamer{Vector{String}, Vector{String}}([\"class 1\", \"class 2\"], [\"Class One\", \"Class Two\"])\n\njulia> println(r(\"class 1\"))\nClass One\n\nAlternatively, a sequence of pair arguments may be passed.\n\njulia> r = renamer(\"class 1\" => \"Class One\", \"class 2\" => \"Class Two\")\nAlgebraOfGraphics.Renamer{Tuple{String, String}, Tuple{String, String}}((\"class 1\", \"class 2\"), (\"Class One\", \"Class Two\"))\n\njulia> println(r(\"class 1\"))\nClass One\n\nIf arr does not contain Pairs, elements of arr are assumed to be labels, and the unique values of the categorical variable are taken to be the indices of the array. This is particularly useful for dims mappings.\n\nExamples\n\njulia> r = renamer([\"Class One\", \"Class Two\"])\nAlgebraOfGraphics.Renamer{Nothing, Vector{String}}(nothing, [\"Class One\", \"Class Two\"])\n\njulia> println(r(2))\nClass Two\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.sorter","page":"Functions","title":"AlgebraOfGraphics.sorter","text":"sorter(ks)\n\nUtility to reorder a categorical variable, as in sorter([\"low\", \"medium\", \"high\"]). A vararg method sorter(\"low\", \"medium\", \"high\") is also supported. ks should include all the unique values of the categorical variable. The order of ks is respected in the legend.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.nonnumeric","page":"Functions","title":"AlgebraOfGraphics.nonnumeric","text":"nonnumeric(x)\n\nTransform x into a non numeric type that is printed and sorted in the same way.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.verbatim","page":"Functions","title":"AlgebraOfGraphics.verbatim","text":"verbatim(x)\n\nSignal that x should not be rescaled, but used in the plot as is.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.scale","page":"Functions","title":"AlgebraOfGraphics.scale","text":"scale(id::Symbol)\n\nCreate a ScaleID object that can be used in a mapping to assign a custom id to the mapped variable. This variable will then not be merged into the default scale for its aesthetic type, but instead be handled separately, leading to a separate legend entry.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.presorted","page":"Functions","title":"AlgebraOfGraphics.presorted","text":"presorted(x)\n\nUse within a pair expression in mapping to signal that a categorical column from the data source should be used in the original order and not automatically sorted.\n\nExample:\n\n# normally, categories would be sorted a, b, c but with `presorted`\n# they stay in the order b, c, a\n\ndata((; some_column = [\"b\", \"c\", \"a\"])) * mapping(:some_column => presorted)\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#Theming","page":"Functions","title":"Theming","text":"","category":"section"},{"location":"API/functions/","page":"Functions","title":"Functions","text":"set_aog_theme!\nAlgebraOfGraphics.aog_theme\nfrom_continuous","category":"page"},{"location":"API/functions/#AlgebraOfGraphics.set_aog_theme!","page":"Functions","title":"AlgebraOfGraphics.set_aog_theme!","text":"set_aog_theme!(; kwargs...)\n\nSet the current theme to a predefined and opinionated theme, as defined by the unexported internal function AlgebraOfGraphics.aog_theme.\n\nTo tweak the predefined theme, use the function Makie.update_theme!. See the example below on how to change, e.g., default fontsize, title, and markersize.\n\nFor more information about setting themes, see the Theming section of the Makie.jl docs.\n\nExamples\n\njulia> using CairoMakie, AlgebraOfGraphics\n\njulia> set_aog_theme!() # Sets a prefedined theme\n\njulia> update_theme!( # Tweaks the current theme\n fontsize=30,\n markersize=40,\n Axis=(title=\"MyDefaultTitle\",)\n )\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.aog_theme","page":"Functions","title":"AlgebraOfGraphics.aog_theme","text":"aog_theme(; fonts=[firasans(\"Medium\"), firasans(\"Light\")])\n\nReturn a NamedTuple of theme settings. Intended for internal use. The provided functionality is exposed to the user by the function set_aog_theme!.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.from_continuous","page":"Functions","title":"AlgebraOfGraphics.from_continuous","text":"from_continuous(x)\n\nMark a colormap as continuous such that AlgebraOfGraphics will sample a categorical palette from start to end in n steps, and not by using the first n colors.\n\nYou could also use cgrad(colormap, n; categorical = true), however, this requires you to specify how many levels there are, which from_continuous detects automatically.\n\nExample:\n\ndraw(scales(Color = (; palette = from_continuous(:viridis))))\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#Ticks-helpers","page":"Functions","title":"Ticks helpers","text":"","category":"section"},{"location":"API/functions/","page":"Functions","title":"Functions","text":"datetimeticks","category":"page"},{"location":"API/functions/#AlgebraOfGraphics.datetimeticks","page":"Functions","title":"AlgebraOfGraphics.datetimeticks","text":"datetimeticks(datetimes::AbstractVector{<:TimeType}, labels::AbstractVector{<:AbstractString})\n\nGenerate ticks matching datetimes to the corresponding labels. The result can be passed to xticks, yticks, or zticks.\n\n\n\n\n\ndatetimeticks(f, datetimes::AbstractVector{<:TimeType})\n\nCompute ticks for the given datetimes using a formatting function f. The result can be passed to xticks, yticks, or zticks.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#Internal-functions","page":"Functions","title":"Internal functions","text":"","category":"section"},{"location":"API/functions/","page":"Functions","title":"Functions","text":"AlgebraOfGraphics.scientific_eltype\nAlgebraOfGraphics.scientific_type\nAlgebraOfGraphics.plottypes_attributes\nAlgebraOfGraphics.compute_attributes","category":"page"},{"location":"API/functions/#AlgebraOfGraphics.scientific_eltype","page":"Functions","title":"AlgebraOfGraphics.scientific_eltype","text":"scientific_eltype(v)\n\nDetermine whether v should be treated as a continuous, geometrical, or categorical array.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.scientific_type","page":"Functions","title":"AlgebraOfGraphics.scientific_type","text":"scientific_type(T::Type)\n\nDetermine whether T represents a continuous, geometrical, or categorical variable.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.plottypes_attributes","page":"Functions","title":"AlgebraOfGraphics.plottypes_attributes","text":"plottypes_attributes(entries)\n\nReturn plottypes and relative attributes, as two vectors of the same length, for the given entries.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.compute_attributes","page":"Functions","title":"AlgebraOfGraphics.compute_attributes","text":"compute_attributes(pl::ProcessedLayer, categoricalscales, continuousscales_grid, continuousscales)\n\nProcess attributes of a ProcessedLayer. In particular,\n\nremove AlgebraOfGraphics-specific layout attributes,\nopt out of Makie cycling mechanism,\ncustomize behavior of color (implementing alpha transparency),\ncustomize behavior of bar width (default to one unit when not specified),\nset correct colorrange.\n\nReturn computed attributes.\n\n\n\n\n\n","category":"function"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/data manipulations/presorted_data.jl\"","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/#Pre-sorted-data","page":"Pre-sorted data","title":"Pre-sorted data","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"using AlgebraOfGraphics, CairoMakie, DataFrames","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"Sometimes we have datasets that have an inherent order we want to preserve. For example, this dataframe has countries sorted by some_value.","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"countries = [\"Algeria\", \"Bolivia\", \"China\", \"Denmark\", \"Ecuador\", \"France\"]\ngroup = [\"2\", \"3\", \"1\", \"1\", \"3\", \"2\"]\nsome_value = exp.(sin.(1:6))\n\ndf = DataFrame(; countries, group, some_value)\nsort!(df, :some_value)\n\ndf","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"
6×3 DataFrame
Rowcountriesgroupsome_value
StringStringFloat64
1Ecuador30.383305
2Denmark10.469164
3France20.756226
4China11.15156
5Algeria22.31978
6Bolivia32.48258
","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"When we plot this, the categorical variable countries is sorted alphabetically by default:","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"spec = data(df) *\n mapping(:countries, :some_value, color = :group) *\n visual(BarPlot, direction = :x)\ndraw(spec)","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"We don't want this, because we have purposefully sorted the dataframe to visualize which countries have the highest value. To retain the order, we can use the presorted helper.","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"spec = data(df) *\n mapping(:countries => presorted, :some_value, color = :group) *\n visual(BarPlot, direction = :x)\nfg = draw(spec)","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"We can also mark multiple variables as presorted, note how the order in the color legend shifts when we do the same for group:","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"spec = data(df) *\n mapping(:countries => presorted, :some_value, color = :group => presorted) *\n visual(BarPlot, direction = :x)\ndraw(spec)","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/basic visualizations/lines_and_markers.jl\"","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/#Lines-and-markers","page":"Lines and markers","title":"Lines and markers","text":"","category":"section"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/#A-simple-scatter-plot","page":"Lines and markers","title":"A simple scatter plot","text":"","category":"section"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"using AlgebraOfGraphics, CairoMakie\n\ndf = (x=rand(100), y=rand(100))\nxy = data(df) * mapping(:x, :y)\ndraw(xy)","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/#A-simple-lines-plot","page":"Lines and markers","title":"A simple lines plot","text":"","category":"section"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"x = range(-π, π, length=100)\ny = sin.(x)\ndf = (; x, y)\nxy = data(df) * mapping(:x, :y)\nlayer = visual(Lines)\ndraw(layer * xy)","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/#Lines-and-scatter-combined-plot","page":"Lines and markers","title":"Lines and scatter combined plot","text":"","category":"section"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"x = range(-π, π, length=100)\ny = sin.(x)\ndf = (; x, y)\nxy = data(df) * mapping(:x, :y)\nlayers = visual(Scatter) + visual(Lines)\ndraw(layers * xy)","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"x = range(-π, π, length=100)\ny = sin.(x)\ndf1 = (; x, y)\ndf2 = (x=rand(10), y=rand(10))\nlayers = data(df1) * visual(Lines) + data(df2) * visual(Scatter)\nfg = draw(layers * mapping(:x, :y))","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/statistical analyses/histograms.jl\"","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/#Histograms","page":"Histograms","title":"Histograms","text":"","category":"section"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"using AlgebraOfGraphics, CairoMakie\nusing AlgebraOfGraphics: density\n\ndf = (x=rand(0:99, 1000),)\nplt = data(df) * mapping(:x) * histogram(bins=20)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"df = (x=randn(1000), c=rand([\"a\", \"b\"], 1000))\nplt = data(df) * mapping(:x, color=:c, stack=:c) * histogram(bins=20)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"df = (x=rand(1000), y=randn(1000))\nplt = data(df) * mapping(:x, :y) * histogram(bins=20)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/split_scales_facet.jl\"","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/#Split-scales-across-facets","page":"Split scales across facets","title":"Split scales across facets","text":"","category":"section"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"Usually, facet layout plots use the same scale for all x and y axes, respectively, of every facet. Sometimes you might want to break with this convention, for example, to show how different categorical and continuous variables interact with each other.","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"AlgebraOfGraphics allows you to use multiple different scale ids for the X and Y aesthetics in a plot, as long as only one scale id for x and y axis, respectively, appears in a given facet.","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"Currently, this scenario requires building the plot in multiple separate layers rather than using wide input data with the dims selector for layout, row or col mappings. You need one layer for each set of scale ids. Multiple facets are allowed to share scale ids, but a single facet may not have multiple scale ids for x or y, respectively.","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"using AlgebraOfGraphics, CairoMakie\n\ndat = data((;\n fruit = rand([\"Apple\", \"Orange\", \"Pear\"], 150),\n taste = randn(150) .* repeat(1:3, inner = 50),\n weight = repeat([\"Heavy\", \"Light\", \"Medium\"], inner = 50),\n cost = randn(150) .+ repeat([10, 20, 30], inner = 50),\n))\n\nfruit = :fruit => \"Fruit\" => scale(:X1)\nweights = :weight => \"Weight\" => scale(:Y1)\ntaste = :taste => \"Taste Score\" => scale(:X2)\ncost = :cost => \"Cost\" => scale(:Y2)\n\nlayer1 = mapping(\n fruit,\n weights,\n col = direct(\"col1\"), # this controls what facet this mapping belongs to\n row = direct(\"row1\")\n) * frequency()\n\nlayer2 = mapping(\n fruit,\n cost,\n col = direct(\"col1\"),\n row = direct(\"row2\")\n) * visual(Violin)\n\nlayer3 = mapping(\n weights, # note X and Y are flipped here for a horizontal violin\n taste,\n col = direct(\"col2\"),\n row = direct(\"row1\")\n) * visual(Violin, orientation = :horizontal)\n\nlayer4 = mapping(\n taste,\n cost,\n col = direct(\"col2\"),\n row = direct(\"row2\")\n) * visual(Scatter)\n\nspec = dat * (layer1 + layer2 + layer3 + layer4)\n\nfg = draw(spec, scales(Row = (; show_labels = false), Col = (; show_labels = false)))","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/data manipulations/wide_data.jl\"","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/#Wide-data","page":"Wide data","title":"Wide data","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"using AlgebraOfGraphics, CairoMakie\nusing AlgebraOfGraphics: density\n\ndf = (a=randn(100), b=randn(100), c=randn(100))\nlabels = [\"Trace 1\", \"Trace 2\", \"Trace 3\"]\nplt = data(df) *\n density() *\n mapping([:a, :b, :c] .=> \"some label\") *\n mapping(color=dims(1) => renamer(labels))\ndraw(plt)","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"df = (a=rand(100), b=rand(100), c=rand(100), d=rand(100))\nlabels = [\"Trace One\", \"Trace Two\", \"Trace Three\"]\nlayers = linear() + visual(Scatter)\nplt = data(df) * layers * mapping(1, 2:4 .=> \"value\", color=dims(1) => renamer(labels))\ndraw(plt)","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"The wide format is combined with broadcast semantics.","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/#Axes-are-linked-when-they-correspond-to-the-same-variable","page":"Wide data","title":"Axes are linked when they correspond to the same variable","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"df = (\n sepal_length = 1 .+ rand(100),\n sepal_width = 2 .+ rand(100),\n petal_length = 3 .+ rand(100),\n petal_width = 4 .+ rand(100)\n)\nxvars = [\"sepal_length\", \"sepal_width\"]\nyvars = [\"petal_length\" \"petal_width\"]\nlayers = linear() + visual(Scatter)\nplt = data(df) * layers * mapping(xvars, yvars, col=dims(1), row=dims(2))\ndraw(plt)","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/#Axes-can-be-fully-linked-or-fully-unlinked","page":"Wide data","title":"Axes can be fully linked or fully unlinked","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"draw(plt, facet = (; linkxaxes = :all, linkyaxes = :all))","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"fg = draw(plt, facet = (; linkxaxes = :none, linkyaxes = :none))","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"layers/operations/#Algebraic-Operations","page":"Algebraic Operations","title":"Algebraic Operations","text":"","category":"section"},{"location":"layers/operations/","page":"Algebraic Operations","title":"Algebraic Operations","text":"There are two algebraic types that can be added or multiplied with each other: AlgebraOfGraphics.Layer and AlgebraOfGraphics.Layers.","category":"page"},{"location":"layers/operations/#Multiplication-on-individual-layers","page":"Algebraic Operations","title":"Multiplication on individual layers","text":"","category":"section"},{"location":"layers/operations/","page":"Algebraic Operations","title":"Algebraic Operations","text":"Each layer is composed of data, mappings, and transformations. Datasets can be replaced, mappings can be merged, and transformations can be concatenated. These operations, taken together, define an associative operation on layers, which we call multiplication *.","category":"page"},{"location":"layers/operations/","page":"Algebraic Operations","title":"Algebraic Operations","text":"Multiplication is primarily useful to combine partially defined layers.","category":"page"},{"location":"layers/operations/#Addition","page":"Algebraic Operations","title":"Addition","text":"","category":"section"},{"location":"layers/operations/","page":"Algebraic Operations","title":"Algebraic Operations","text":"The operation + is used to superimpose separate layers. a + b has as many layers as la + lb, where la and lb are the number of layers in a and b respectively.","category":"page"},{"location":"layers/operations/#Multiplication-on-lists-of-layers","page":"Algebraic Operations","title":"Multiplication on lists of layers","text":"","category":"section"},{"location":"layers/operations/","page":"Algebraic Operations","title":"Algebraic Operations","text":"Multiplication naturally extends to lists of layers. Given two Layers objects a and b, containing la and lb layers respectively, the product a * b contains la * lb layers—all possible pair-wise products.","category":"page"},{"location":"layers/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"layers/introduction/","page":"Introduction","title":"Introduction","text":"Layers are the key building blocks of AlgebraOfGraphics. Each layer is the product of the following elementary objects.","category":"page"},{"location":"layers/introduction/","page":"Introduction","title":"Introduction","text":"Data (encoding the dataset).\nMapping (associating variables to plot attributes).\nVisual (encoding data-independent plot information).\nAnalyses (encoding transformations that are applied to the data before plotting).","category":"page"},{"location":"layers/introduction/","page":"Introduction","title":"Introduction","text":"Data, mappings, visuals and analyses can be combined together using Algebraic Operations to form one or more layers.","category":"page"},{"location":"layers/introduction/","page":"Introduction","title":"Introduction","text":"The output of these algebraic operations can be visualized, as shown in the section Drawing Layers.","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/discrete_scales.jl\"","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/#Discrete-scales","page":"Discrete scales","title":"Discrete scales","text":"","category":"section"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"By default categorical ticks, as well as names from legend entries, are taken from the value of the variable converted to a string. Scales can be equipped with labels to overwrite that. You can either use the renamer function to apply relabeling or reordering to some column on the fly, or you use the categories keyword for the respective scale in the draw call.","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"note: Note\nThe categories keyword (added in v0.7) also allows adding categories not present in the data.","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"df = (x=rand([\"a\", \"b\", \"c\"], 100), y=rand(100))\nplt = data(df) * mapping(:x, :y) * visual(BoxPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"plt = data(df) * mapping(:x, :y) * visual(BoxPlot)\ndraw(plt, scales(X = (;\n categories = [\"a\" => \"label1\", \"b\" => \"label2\", \"c\" => \"label3\"]\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"The same operation can be done with renamer as well which modifies the input data","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"plt = data(df) *\n mapping(\n :x => renamer(\"a\" => \"label1\", \"b\" => \"label2\", \"c\" => \"label3\"),\n :y\n ) * visual(BoxPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"With categories, you can add further categories that might be missing from your data","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"plt = data(df) * mapping(:x, :y) * visual(BoxPlot)\ndraw(plt, scales(X = (;\n categories = [\"a\", \"missing\", \"b\", \"c\"]\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"The order can also be changed:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"plt = data(df) * mapping(:x, :y) * visual(BoxPlot)\ndraw(plt, scales(X = (;\n categories = [\"b\" => \"label b\", \"a\" => \"label a\", \"c\" => \"label c\"]\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"Or with renamer:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"plt = data(df) *\n mapping(\n :x => renamer(\"b\" => \"label b\", \"a\" => \"label a\", \"c\" => \"label c\"),\n :y\n ) * visual(BoxPlot)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"When categories come from different datasets, you can either apply the same renamer to multiple mappings, or set the ordering at one place in categories:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"df1 = (; x = rand([\"one\", \"two\"], 100), y = randn(100))\ndf2 = (; x = rand([\"three\", \"four\"], 50), y = randn(50))\nplt = (data(df1) + data(df2)) * mapping(:x, :y) * visual(BoxPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"draw(plt, scales(X = (;\n categories = [\"one\", \"two\", \"three\", \"four\"]\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"You can also pass a function to categories, which has to return a vector with (optionally labelled) categories in the desired order. For example, strings are by default ordered alphabetically:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"df = (; name = [\"Anna Coolidge\", \"Berta Bauer\", \"Charlie Archer\"], age = [34, 79, 58])\nplt = data(df) * mapping(:name, :age) * visual(BarPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"Instead of specifying the order manually, we could use a function to order by last name:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"draw(plt, scales(X = (;\n categories = cats -> sort(cats; by = name -> split(name)[2])\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"Or even combine this with a relabeling function that shortens the first name to the initial:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"function initialed(name)\n a, b = split(name)\n return name => \"$(first(a)). $b\"\nend\n\ndraw(plt, scales(X = (;\n categories = cats -> initialed.(sort(cats; by = name -> split(name)[2]))\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/layout/faceting.jl\"","category":"page"},{"location":"gallery/gallery/layout/faceting/#Faceting","page":"Faceting","title":"Faceting","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-grid","page":"Faceting","title":"Facet grid","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"df = let\n N = 100\n x0 = rand(1:10, N)\n i = rand([\"α\", \"β\"], N)\n j = rand([\"a\", \"b\", \"c\"], N)\n\n x = map(zip(x0, j)) do (xx, jj)\n shift = jj == \"a\" ? -2.9 : jj == \"c\" ? 2.9 : 0.0\n xx + shift\n end\n\n y = map(zip(x0, i)) do (xx, ii)\n shift = ii == \"α\" ? -3.9 : 3.9\n xx + 2 + shift + rand()\n end\n\n (; x, y, i, j)\nend\n\nplt = data(df) * mapping(:x, :y, row=:i, col=:j)\n\ndraw(plt)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-grid-with-minimal-axes-linking-needed-to-remove-ticks","page":"Faceting","title":"Facet grid with minimal axes linking needed to remove ticks","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"draw(plt, facet=(; linkxaxes=:minimal, linkyaxes=:minimal))","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-grid-with-unlinked-x-axes","page":"Faceting","title":"Facet grid with unlinked x-axes","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"draw(plt, facet=(; linkxaxes=:none))","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-wrap","page":"Faceting","title":"Facet wrap","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"df = (x=rand(100), y=rand(100), l=rand([\"a\", \"b\", \"c\", \"d\", \"e\"], 100))\nplt = data(df) * mapping(:x, :y, layout=:l)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-wrap-with-unlinked-axes","page":"Faceting","title":"Facet wrap with unlinked axes","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"draw(plt, facet=(; linkxaxes=:none, linkyaxes=:none))","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-wrap-with-specified-layout-for-rows-and-cols","page":"Faceting","title":"Facet wrap with specified layout for rows and cols","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"draw(plt, scales(Layout = (; palette = [(1, 1), (2, 1), (3, 1), (1, 2), (2, 2)])))","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Adding-traces-to-only-some-subplots","page":"Faceting","title":"Adding traces to only some subplots","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"df1 = (x=rand(100), y=rand(100), i=rand([\"a\", \"b\", \"c\"], 100), j=rand([\"d\", \"e\", \"f\"], 100))\ndf2 = (x=[0, 1], y=[0.5, 0.5], i=fill(\"a\", 2), j=fill(\"e\", 2))\nlayers = data(df1) * visual(Scatter) + data(df2) * visual(Lines)\nfg = draw(layers * mapping(:x, :y, col=:i, row=:j))","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Caveats","page":"Faceting","title":"Caveats","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"The faceting variable must be non-numeric. If the source is numeric, you can convert it with nonnumeric.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"df = (x=rand(100), y=rand(100), l=rand([1, 2, 3, 4, 5], 100))\nplt = data(df) * mapping(:x, :y, layout=:l => nonnumeric)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Pagination","page":"Faceting","title":"Pagination","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"If you have too many facets for one figure, you can use paginate to split the data into several subsets given a maximum number of plots per layout, row or column.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"Note that pagination is considered an experimental feature. In the current implementation, scales and layouts are not synchronized across pages. This means that, e.g., linked limits on one page are not influenced by limits of other pages. The exact synchronization behavior can be subject to change in non-breaking versions.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"df = (x=rand(500), y=rand(500), l=rand([\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"], 500))\nplt = data(df) * mapping(:x, :y, layout=:l)\npag = paginate(plt, layout = 4)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"PaginatedLayers with 2 entries (layout = 4)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"The object returned from draw will be a Vector{FigureGrid}.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"figuregrids = draw(pag)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"2-element Vector{AlgebraOfGraphics.FigureGrid}:\n FigureGrid()\n FigureGrid()","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"You can either extract single figures from this vector...","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"figuregrids[1]","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"or use draw with an optional second argument specifying the index of the page to draw.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"draw(pag, 2)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"EditURL = \"penguins.jl\"","category":"page"},{"location":"generated/penguins/#Tutorial","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"This is a gentle and lighthearted tutorial on how to use tools from AlgebraOfGraphics, using as example dataset a collection of measurements on penguins[1]. See the Palmer penguins website for more information.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"[1]: Gorman KB, Williams TD, Fraser WR (2014) Ecological Sexual Dimorphism and Environmental Variability within a Community of Antarctic Penguins (Genus Pygoscelis). PLoS ONE 9(3): e90081. DOI","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"To follow along this tutorial, you will need to install a few packages. All the required packages can be installed with the following command.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"julia> import Pkg; Pkg.add([\"AlgebraOfGraphics\", \"CairoMakie\", \"DataFrames\", \"LIBSVM\", \"PalmerPenguins\"])","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"After the above command completes, we are ready to go.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"using PalmerPenguins, DataFrames\n\npenguins = dropmissing(DataFrame(PalmerPenguins.load()))\nfirst(penguins, 6)","category":"page"},{"location":"generated/penguins/#Frequency-plots","page":"Tutorial 🐧","title":"Frequency plots","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Let us start by getting a rough idea of how the data is distributed.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"note: Note\nDue to julia's compilation model, the first plot may take a while to appear.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"using AlgebraOfGraphics, CairoMakie\nset_aog_theme!()\n\naxis = (width = 225, height = 225)\npenguin_frequency = data(penguins) * frequency() * mapping(:species)\n\ndraw(penguin_frequency; axis = axis)","category":"page"},{"location":"generated/penguins/#Small-intermezzo:-saving-the-plot","page":"Tutorial 🐧","title":"Small intermezzo: saving the plot","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"If you are working in an interactive enviroment with inline plotting support, such VSCode or Pluto.jl, the above should have displayed a bar plot. If you are working directly in the console, you can simply save the plot and inspect it in the file explorer.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"fg = draw(penguin_frequency; axis = axis)\nsave(\"figure.png\", fg, px_per_unit = 3) # save high-resolution png","category":"page"},{"location":"generated/penguins/#Styling-by-categorical-variables","page":"Tutorial 🐧","title":"Styling by categorical variables","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Next, let us see whether the distribution is the same across islands.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_frequency * mapping(color = :island)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Oops! The bars are in the same spot and are hiding each other. We need to specify how we want to fix this. Bars can either dodge each other, or be stacked on top of each other.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_frequency * mapping(color = :island, dodge = :island)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"This is our first finding. Adelie is the only species of penguins that can be found on all three islands. To be able to see both which species is more numerous and how different species are distributed across islands in a unique plot, we could have used stack.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_frequency * mapping(color = :island, stack = :island)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/#Correlating-two-variables","page":"Tutorial 🐧","title":"Correlating two variables","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Now that we have understood the distribution of these three penguin species, we can start analyzing their features.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"penguin_bill = data(penguins) * mapping(:bill_length_mm, :bill_depth_mm)\ndraw(penguin_bill; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We would actually prefer to visualize these measures in centimeters, and to have cleaner axes labels. As we want this setting to be preserved in all of our bill visualizations, let us save it in the variable penguin_bill, to be reused in subsequent plots.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"penguin_bill = data(penguins) * mapping(\n :bill_length_mm => (t -> t / 10) => \"bill length (cm)\",\n :bill_depth_mm => (t -> t / 10) => \"bill depth (cm)\",\n)\ndraw(penguin_bill; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Much better! Note the parentheses around the function t -> t / 10. They are necessary to specify that the function maps t to t / 10, and not to t / 10 => \"bill length (cm)\".","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"There does not seem to be a strong correlation between the two dimensions, which is odd. Maybe dividing the data by species will help.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_bill * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Ha! Within each species, penguins with a longer bill also have a deeper bill. We can confirm that with a linear regression","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_bill * linear() * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"This unfortunately no longer shows our data! We can use + to plot both things on top of each other:","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_bill * linear() * mapping(color = :species) + penguin_bill * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Note that the above expression seems a bit redundant, as we wrote the same thing twice. We can \"factor it out\" as follows","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_bill * (linear() + mapping()) * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"where mapping() is a neutral multiplicative element. Of course, the above could be refactored as","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = linear() + mapping()\nplt = penguin_bill * layers * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We could actually take advantage of the spare mapping() and use it to pass some extra info to the scatter, while still using all the species members to compute the linear fit.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = linear() + mapping(marker = :sex)\nplt = penguin_bill * layers * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"This plot is getting a little bit crowded. We could instead show female and male penguins in separate subplots.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = linear() + mapping(col = :sex)\nplt = penguin_bill * layers * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"See how both plots show the same fit, because the sex mapping is not applied to linear(). The following on the other hand produces a separate fit for males and females:","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = linear() + mapping()\nplt = penguin_bill * layers * mapping(color = :species, col = :sex)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/#Smooth-density-plots","page":"Tutorial 🐧","title":"Smooth density plots","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"An alternative approach to understanding how two variables interact is to consider their joint probability density distribution (pdf).","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"using AlgebraOfGraphics: density\nplt = penguin_bill * density(npoints=50) * mapping(col = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"The default colormap is multi-hue, but it is possible to pass single-hue colormaps as well. The color range is inferred from the data by default, but it can also be passed manually. Both settings are passed via scales to draw, because multiple plots can share the same colormap, so visual is not the appropriate place for this setting.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"draw(plt, scales(Color = (; colormap = :grayC, colorrange = (0, 6))); axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We could also use a Contour plot instead:","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"axis = (width = 225, height = 225)\nlayer = density() * visual(Contour)\nplt = penguin_bill * layer * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"The data and the linear fit can also be added back to the plot:","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = density() * visual(Contour) + linear() + mapping()\nplt = penguin_bill * layers * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"In the case of many layers (contour, density and scatter) it is important to think about balance. In the above plot, the markers are quite heavy and can obscure the linear fit and the contour lines. We can lighten the markers using alpha transparency.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = density() * visual(Contour) + linear() + visual(alpha = 0.5)\nplt = penguin_bill * layers * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/#Correlating-three-variables","page":"Tutorial 🐧","title":"Correlating three variables","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We are now mostly up to speed with bill size, but we have not considered how it relates to other penguin features, such as their weight. For that, a possible approach is to use a continuous color on a gradient to denote weight and different marker shapes to denote species. Here we use group to split the data for the linear regression without adding any additional style.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"body_mass = :body_mass_g => (t -> t / 1000) => \"body mass (kg)\"\nlayers = linear() * mapping(group = :species) + mapping(color = body_mass, marker = :species)\nplt = penguin_bill * layers\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_bill * mapping(body_mass, color = :species, layout = :sex)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Note that static 3D plot can be misleading, as they only show one projection of 3D data. They are mostly useful when shown interactively.","category":"page"},{"location":"generated/penguins/#Machine-Learning","page":"Tutorial 🐧","title":"Machine Learning","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Finally, let us use Machine Learning techniques to build an automated penguin classifier!","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We would like to investigate whether it is possible to predict the species of a penguin based on its bill size. To do so, we will use a standard classifier technique called Support-Vector Machine.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"The strategy is quite simple. We split the data into training and testing subdatasets. We then train our classifier on the training dataset and use it to make predictions on the whole data. We then add the new columns obtained this way to the dataset and visually inspect how well the classifier performed in both training and testing.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"using LIBSVM, Random\n\n# use approximately 80% of penguins for training\nRandom.seed!(1234) # for reproducibility\nN = nrow(penguins)\ntrain = fill(false, N)\nperm = randperm(N)\ntrain_idxs = perm[1:floor(Int, 0.8N)]\ntrain[train_idxs] .= true\nnothing # hide\n\n# fit model on training data and make predictions on the whole dataset\nX = hcat(penguins.bill_length_mm, penguins.bill_depth_mm)\ny = penguins.species\nmodel = SVC() # Support-Vector Machine Classifier\nfit!(model, X[train, :], y[train])\nŷ = predict(model, X)\n\n# incorporate relevant information in the dataset\npenguins.train = train\npenguins.predicted_species = ŷ\nnothing #hide","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Now, we have all the columns we need to evaluate how well our classifier performed.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"axis = (width = 225, height = 225)\ndataset =:train => renamer(true => \"training\", false => \"testing\") => \"Dataset\"\naccuracy = (:species, :predicted_species) => isequal => \"accuracy\"\nplt = data(penguins) *\n expectation() *\n mapping(:species, accuracy) *\n mapping(col = dataset)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"That is a bit hard to read, as all values are very close to 1. Let us visualize the error rate instead.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"error_rate = (:species, :predicted_species) => !isequal => \"error rate\"\nplt = data(penguins) *\n expectation() *\n mapping(:species, error_rate) *\n mapping(col = dataset)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"So, mostly our classifier is doing quite well, but there are some mistakes, especially among Chinstrap penguins. Using at the same time the species and predicted_species mappings on different attributes, we can see which penguins are problematic.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"prediction = :predicted_species => \"predicted species\"\ndatalayer = mapping(color = prediction, row = :species, col = dataset)\nplt = penguin_bill * datalayer\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Um, some of the penguins are indeed being misclassified... Let us try to understand why by adding an extra layer, which describes the density of the distributions of the three species.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"pdflayer = density() * visual(Contour, colormap=Reverse(:grays)) * mapping(group = :species)\nlayers = pdflayer + datalayer\nplt = penguin_bill * layers\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We can conclude that the classifier is doing a reasonable job: it is mostly making mistakes on outlier penguins.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"This page was generated using Literate.jl.","category":"page"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/applications/geometries.jl\"","category":"page"},{"location":"gallery/gallery/applications/geometries/#Geometries","page":"Geometries","title":"Geometries","text":"","category":"section"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"using AlgebraOfGraphics, CairoMakie\nusing GeometryBasics\n\ngeometry = [Rect(Vec(i, j), Vec(1, 1)) for i in 0:7 for j in 0:7]\ngroup = [isodd(i + j) ? \"light square\" : \"dark square\" for i in 0:7 for j in 0:7]\ndf = (; geometry, group)\n\nplt = data(df) * visual(Poly) * mapping(:geometry, color = :group)\nfg = draw(plt; axis=(aspect=1,))","category":"page"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"(Image: )","category":"page"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"","category":"page"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/index.md\"","category":"page"},{"location":"gallery/#Gallery","page":"Gallery","title":"Gallery","text":"","category":"section"},{"location":"gallery/#Basic-visualizations","page":"Gallery","title":"Basic visualizations","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Lines and markers\n

\n

\n Basic linear and scatter plots.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Statistical visualizations\n

\n

\n Violin plot, boxplot, qqplot.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Statistical-analyses","page":"Gallery","title":"Statistical analyses","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Density plots\n

\n

\n Visualizing kernel density estimation of data.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Histograms\n

\n

\n Computing 1- and 2-dimensional histograms.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Regression plots\n

\n

\n Linear and nonlinear regressions.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Data-manipulations","page":"Gallery","title":"Data manipulations","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Renaming and transforming variables\n

\n

\n Transforming data before generating the plot.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Using mapping without tabular data\n

\n

\n Passing columnar data directly to `mapping`.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Pre-grouped data\n

\n

\n Working with arrays of arrays.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Pre-sorted data\n

\n

\n Preserving the original order of categorical data.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Wide data\n

\n

\n Working with data in the wide format.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Scales","page":"Gallery","title":"Scales","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"Some advanced keywords to tweak the plot","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Discrete scales\n

\n

\n Sorting and renaming categorical variables.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Continuous scales\n

\n

\n Applying nonlinear transformations.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Custom scales\n

\n

\n Custom palettes and custom attributes.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Split scales across facets\n

\n

\n Using different categorical and continuous scales across a facet layout.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Secondary scales\n

\n

\n Categorical and continuous scales in the same plot.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Multiple color scales\n

\n

\n Categorical and continuous scales in the same plot.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Pre-scaled data\n

\n

\n Pass data to the plot as is.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Legend merging\n

\n

\n Multiple scales for the same variable.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Dodging\n

\n

\n Dodging groups to avoid overlaps.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Customization","page":"Gallery","title":"Customization","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"Some advanced keywords to tweak the plot","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Axis tweaking\n

\n

\n Setting axis attributes.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Figure tweaking\n

\n

\n Setting figure attributes.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Legend tweaking\n

\n

\n Setting legend attributes.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Colorbar tweaking\n

\n

\n Setting colorbar attributes.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Layout","page":"Gallery","title":"Layout","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Faceting\n

\n

\n Generating a grid of plots.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Nested layouts\n

\n

\n AlgebraOfGraphics plots within a Makie figure.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Applications","page":"Gallery","title":"Applications","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"Example applications with different types of data","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Geographic data\n

\n

\n Antarctic coastline.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Geometries\n

\n

\n Visualizing geometries.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Time series\n

\n

\n Visualizing time series data.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/data manipulations/new_columns_on_the_fly.jl\"","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/#Renaming-and-transforming-variables","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"using AlgebraOfGraphics, CairoMakie\n\ndf = (x=rand(100), y=rand(100), z=rand(100), c=rand([\"a\", \"b\"], 100))\nlayers = linear() + mapping(color=:z)\n\nplt = data(df) * layers * mapping(:x => (x -> x^2) => L\"x^2\", :y => L\"This variable is called $y$\")\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"Use a Tuple to pass combine several columns into a unique operation.","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"plt = data(df) * layers * mapping(:x, (:x, :y, :z) => (+) => L\"the new variable $x + y + z$\", layout=:c)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/customization/colorbar.jl\"","category":"page"},{"location":"gallery/gallery/customization/colorbar/#Colorbar-tweaking","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"","category":"section"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"(Image: Source code)","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"To tweak the position and appearance of the colorbar, simply use the colorbar keyword when plotting. For example","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"df = (x=rand(100), y=rand(100), z=rand(100))\nplt = data(df) * mapping(:x, :y, color=:z)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"fg = draw(plt, colorbar=(position=:top, size=25))","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"To change the colormap, you have to modify the corresponding scale. Usually, this will be the Color scale.","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"note: Note\nBefore AlgebraOfGraphics v0.7, you would change the colormap by passing it via visual. This was changed so that each color scale, which can be used by multiple plot layers, has a single source of truth for these settings.","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"draw(plt, scales(Color = (; colormap = :thermal)))","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"Other continuous color parameters are highclip, lowclip, nan_color and colorrange.","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"draw(plt, scales(Color = (;\n colormap = :thermal,\n colorrange = (0.25, 0.75),\n highclip = :cyan,\n lowclip = :lime,\n)))","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/custom_scales.jl\"","category":"page"},{"location":"gallery/gallery/scales/custom_scales/#custom_scales","page":"Custom scales","title":"Custom scales","text":"","category":"section"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"using AlgebraOfGraphics, CairoMakie\nusing Colors","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"A palette maps categorical values to particular attribute specifications (e.g. the first value maps to green, the second maps to red, and so on).","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"x=repeat(1:20, inner=20)\ny=repeat(1:20, outer=20)\nu=cos.(x)\nv=sin.(y)\nc=rand(Bool, length(x))\nd=rand(Bool, length(x))\ndf = (; x, y, u, v, c, d)\ncolors = [colorant\"#E24A33\", colorant\"#348ABD\"]\nheads = ['◮', '◭']\nplt = data(df) *\n mapping(:x, :y, :u, :v) *\n mapping(arrowhead = :c => nonnumeric) *\n mapping(color = :d => nonnumeric) *\n visual(Arrows, arrowsize=10, lengthscale=0.4, linewidth = 1)\nfg = draw(plt, scales(Marker = (; palette = heads), Color = (; palette = colors)))","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"To associate specific attribute values to specific data values, use pairs. Missing keys will cycle over values that are not pairs.","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"x = rand(100)\ny = rand(100)\nz = rand([\"a\", \"b\", \"c\", \"d\"], 100)\ndf = (; x, y, z)\nplt = data(df) * mapping(:x, :y, color=:z)\ncolors = [\"a\" => :tomato, \"c\" => :lime, colorant\"#988ED5\", colorant\"#777777\"]\ndraw(plt, scales(Color = (; palette = colors)))","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"Categorical color gradients can also be passed to palettes. You can use the from_continuous helper function to wrap continuous colormaps which you want to sample from start to end in n steps, where n is the number of categories you are visualizing.","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"x = rand(200)\ny = rand(200)\nz = rand([\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"], 200)\ndf = (; x, y, z)\nplt = data(df) * mapping(:x, :y, color=:z)\ndraw(plt, scales(Color = (; palette = from_continuous(:cividis))))","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/dodging.jl\"","category":"page"},{"location":"gallery/gallery/scales/dodging/#dodging","page":"Dodging","title":"Dodging","text":"","category":"section"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"using AlgebraOfGraphics, CairoMakie\nusing Colors","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"Some plot types like barplots natively support a dodge attribute which avoids overlap between groups that share the same coordinates.","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"df = (; x = [\"One\", \"One\", \"Two\", \"Two\"], y = 1:4, err = [0.2, 0.3, 0.4, 0.5], group = [\"A\", \"B\", \"A\", \"B\"])\nplt = data(df) * mapping(:x, :y, dodge = :group, color = :group) * visual(BarPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"Other plot types like errorbars do not have a dodge keyword, however you can dodge them using AlgebraOfGraphic's hardcoded dodge_x or dodge_y mappings. These will only shift the data away from the category centers but will not change other plot attributes (like dodging a barplot makes narrower bars). They are therefore mostly appropriate for \"width-less\" plot types like scatters or errorbars.","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"If you combine errorbars with a barplot, AlgebraOfGraphics will apply the barplot's dodge width to the errorbars automatically so they match:","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"plt2 = data(df) * mapping(:x, :y, :err, dodge_x = :group) * visual(Errorbars)\nfg = draw(plt + plt2)","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"If you only use \"width-less\" plot types, you will get an error if you don't set a dodge width manually. You can do so via the scales function:","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"df = (\n x = repeat(1:10, inner = 2),\n y = cos.(range(0, 2pi, length = 20)),\n ylow = cos.(range(0, 2pi, length = 20)) .- 0.2,\n yhigh = cos.(range(0, 2pi, length = 20)) .+ 0.3,\n dodge = repeat([\"A\", \"B\"], 10)\n)\n\nf = Figure()\nplt3 = data(df) * (\n mapping(:x, :y, dodge_x = :dodge, color = :dodge) * visual(Scatter) +\n mapping(:x, :ylow, :yhigh, dodge_x = :dodge, color = :dodge) * visual(Rangebars)\n)\nkw(; kwargs...) = (; xticklabelsvisible = false, xticksvisible = false, xlabelvisible = false, kwargs...)\n\ndraw!(f[1, 1], plt3, scales(DodgeX = (; width = 0.25)); axis = kw(title = \"DodgeX = (; width = 0.25)\"))\ndraw!(f[2, 1], plt3, scales(DodgeX = (; width = 0.5)); axis = kw(title = \"DodgeX = (; width = 0.5)\"))\ndraw!(f[3, 1], plt3, scales(DodgeX = (; width = 1.0)); axis = (; title = \"DodgeX = (; width = 1.0)\"))\n\nf","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/prescaled_data.jl\"","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/#Pre-scaled-data","page":"Pre-scaled data","title":"Pre-scaled data","text":"","category":"section"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"using AlgebraOfGraphics, CairoMakie\nusing Colors\n\nx = rand(100)\ny = rand(100)\nz = rand([colorant\"teal\", colorant\"orange\"], 100)\ndf = (; x, y, z)\nplt = data(df) * mapping(:x, :y, color=:z => verbatim)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"Plotting labels instead of markers","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"x = rand(100)\ny = rand(100)\nlabel = rand([\"a\", \"b\"], 100)\ndf = (; x, y, label)\nplt = data(df) * mapping(:x, :y, text=:label => verbatim) * visual(Makie.Text)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/layout/nested_layouts.jl\"","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/#Nested-layouts","page":"Nested layouts","title":"Nested layouts","text":"","category":"section"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"All AlgebraOfGraphics plots can be inserted in any figure position, where the rest of the figure is managed by vanilla Makie. For example","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"fig = Figure(; size=(800, 600))\nax = Axis(fig[1, 1], title=\"Some plot\")\n\ndf = (\n x=rand(500),\n y=rand(500),\n i=rand([\"a\", \"b\", \"c\"], 500),\n j=rand([\"d\", \"e\", \"f\"], 500),\n k=rand(Bool, 500),\n l=rand(Bool, 500)\n)\nplt = data(df) * mapping(:x, :y, col=:i, row=:j, color=:k, marker=:l)\n\nsubfig = fig[1, 2:3]\nag = draw!(subfig, plt)\nfor ae in ag\n ae.axis.xticklabelrotation[] = π/2\nend\nlegend!(fig[end+1, 2], ag, orientation=:horizontal, tellheight=true)\nfig","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"The above also works in more nested situations.","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"f = Figure(; size=(800, 600))\nax = Axis(f[1, 1], title=\"Some plot\")\nsubfig = f[1, 2]\nax2 = Axis(subfig[1, 1])\n\ndf = (\n x=rand(500),\n y=rand(500),\n c=rand([\"a\", \"b\", \"c\"], 500),\n)\nplt = data(df) * mapping(:x, :y, color=:c)\n\ndraw!(subfig[2, 1], plt)\nf","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"It is also possible to let Makie control the axis and plot directly on top of it.","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"f = Figure(; size=(800, 300))\nax1 = Axis(f[1, 1])\nax2 = Axis(f[1, 2])\n\ndf = (x=rand(100), y=rand(100), c=rand([\"a\", \"b\", \"c\"], 100))\nplt = data(df) * mapping(:x, :y, color=:c)\n\nscatter!(ax1, rand(10), rand(10), color=:black)\ngrid = draw!(ax2, plt)\nlegend!(f[1, 3], grid)\n\nf","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/applications/geographic.jl\"","category":"page"},{"location":"gallery/gallery/applications/geographic/#Geographic-data","page":"Geographic data","title":"Geographic data","text":"","category":"section"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"using AlgebraOfGraphics, CairoMakie\nusing Shapefile, ZipFile\nusing Downloads","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"Antarctic coastline. Data from the SCAR Antarctic Digital Database[1].","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"[1]: Gerrish, L., Fretwell, P., & Cooper, P. (2021). Medium resolution vector polygons of the Antarctic coastline (7.4) [Data set]. UK Polar Data Centre, Natural Environment Research Council, UK Research & Innovation. https://doi.org/10.5285/747e63e-9d93-49c2-bafc-cf3d3f8e5afa","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"# Download, extract, and load shapefile\nt = mktempdir() do dir\n url = \"https://ramadda.data.bas.ac.uk/repository/entry/get/add_coastline_medium_res_polygon_v7_4.zip?entryid=synth%3Ae747e63e-9d93-49c2-bafc-cf3d3f8e5afa%3AL2FkZF9jb2FzdGxpbmVfbWVkaXVtX3Jlc19wb2x5Z29uX3Y3XzQuemlw\"\n r = ZipFile.Reader(seekstart(Downloads.download(url, IOBuffer())))\n for f in r.files\n open(joinpath(dir, f.name), write = true) do io\n write(io, read(f, String));\n end\n end\n Shapefile.Table(joinpath(dir, \"add_coastline_medium_res_polygon_v7_4.shp\"))\nend\n\n# Draw map\nplt = data(t) * mapping(:geometry, color = :surface) * visual(Choropleth)\nfg = draw(plt; axis=(aspect=1,))","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"}] +[{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/basic visualizations/statistical_visualizations.jl\"","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/#Statistical-visualizations","page":"Statistical visualizations","title":"Statistical visualizations","text":"","category":"section"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"using AlgebraOfGraphics, CairoMakie, PalmerPenguins, DataFrames\n\npenguins = dropmissing(DataFrame(PalmerPenguins.load()))\n\ndata(penguins) * visual(Violin) *\n mapping(:species, :bill_depth_mm, color=:sex, dodge=:sex) |> draw","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"plt = data(penguins) * visual(Violin, datalimits=extrema)\nplt *= mapping(:species, :bill_depth_mm, color=:sex, side=:sex, dodge=:island)\nfg = draw(plt, axis=(limits=((0.5, 3.5), nothing),))","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"data(penguins) * visual(BoxPlot, show_notch=true) *\n mapping(:species, :bill_depth_mm, color=:sex, dodge=:sex) |> draw","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"data(penguins) *\n mapping(:bill_length_mm, :bill_depth_mm, col=:sex) *\n visual(QQPlot, qqline=:fit) |> draw","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"","category":"page"},{"location":"gallery/gallery/basic visualizations/statistical_visualizations/","page":"Statistical visualizations","title":"Statistical visualizations","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"FAQs/#Frequently-Asked-Questions","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"","category":"section"},{"location":"FAQs/#What-is-the-algebraic-structure-of-AlgebraOfGraphics?","page":"Frequently Asked Questions","title":"What is the algebraic structure of AlgebraOfGraphics?","text":"","category":"section"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"AlgebraOfGraphics is based on two operators, + and *. These two operators induce a semiring structure, with a small caveat. Addition is commutative only up to the drawing order. For example, visual(Lines) + visual(Scatter) is slightly different from visual(Scatter) + visual(Lines), in that the former draws the scatter on top of the lines, and the latter draws the lines on top of the scatter. As a consequence, only right distributivity holds with full generality, whereas left distributivity only holds up to the drawing order.","category":"page"},{"location":"FAQs/#Why-is-the-mapping-pair-syntax-different-from-DataFrames?","page":"Frequently Asked Questions","title":"Why is the mapping pair syntax different from DataFrames?","text":"","category":"section"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The transformations passed within a mapping, e.g. mapping(:x => log => \"log(x)\"), are applied element-wise. Operations that require the whole column are not supported on purpose. An important reason to prefer element-wise operations (other than performance) is that whole-column operations can be error prone in this setting, especially when","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"the data is grouped or\ndifferent datasets are used.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"If you do need column-wise transformations, consider implementing a custom analysis, such as density, which takes the whole data as input, or apply the transformation directly in your data before passing it to AlgebraOfGraphics.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"See also Pair syntax for a detailed description of the pair syntax within a mapping.","category":"page"},{"location":"FAQs/#What-is-the-difference-between-axis-scales-and-data-transformations?","page":"Frequently Asked Questions","title":"What is the difference between axis scales and data transformations?","text":"","category":"section"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"There are two overlapping but distinct ways to rescale data.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Keep the data as is and use a nonlinear scale, e.g. axis=(xscale=log,).\nTransform the data directly, e.g. mapping(:x => log => \"log(x)\").","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Note that the resulting plots may \"look different\" in some cases. Consider for instance the following example.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"using AlgebraOfGraphics\nusing AlgebraOfGraphics: density\ndf = (x = exp.(randn(1000)),)\nkde1 = data(df) * mapping(:x) * density()\ndraw(kde1, axis=(width=225, height=225, xscale=log,))","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"df = (x = exp.(randn(1000)),)\nkde2 = data(df) * mapping(:x => log => \"log(x)\") * density()\ndraw(kde2, axis=(width=225, height=225))","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The two plots look different. The first represents the pdf of x in a log scale, while the second represents the pdf of log(x) in a linear scale. The two curves differ by a factor 1 / x, the derivative of log(x). See e.g. this post for some mathematical background on the topic.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"In general, the second approach (plotting the density of log(x)) could be considered more principled, as it preserves the proportionality between area and probability mass. On the contrary, the first approach (plotting the density of x in a log scale) breaks this proportionality relationship.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"A similar reasoning applies to histograms:","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"using AlgebraOfGraphics\ndf = (x = exp.(rand(1000)),)\nhist1 = data(df) * mapping(:x) * histogram()\ndraw(hist1, axis=(width=225, height=225, xscale=log))","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"df = (x = exp.(rand(1000)),)\nhist2 = data(df) * mapping(:x => log => \"log(x)\") * histogram()\ndraw(hist2, axis=(width=225, height=225))","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"The data transformation approach is preferable as it produces uniform bins, which are easier to interpret.","category":"page"},{"location":"FAQs/#How-to-combine-AlgebraOfGraphics-with-plain-Makie-plots?","page":"Frequently Asked Questions","title":"How to combine AlgebraOfGraphics with plain Makie plots?","text":"","category":"section"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Since AlgebraOfGraphics is built upon the Makie ecosystem we can easily combine plots from both packages. Two approaches can be taken. Firstly, by using draw! you can pass a Figure or FigurePosition created by Makie to be used by AlgebraOfGraphics, e.g.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"using AlgebraOfGraphics, CairoMakie #hide\n\nf, a, p = lines(0..2pi, sin; figure = (size = (600, 400),))\n\ndf = (x = exp.(rand(1000)),)\nhist1 = data(df) * mapping(:x => log => \"log(x)\") * histogram()\ndraw!(f[1, 2], hist1)\n\nf #hide","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"Alternatively, we can create the AlgebraOfGraphics figure first and then add in additional plain Makie axes alongside the result by accessing the .figure field of fg, e.g.","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"using AlgebraOfGraphics, CairoMakie #hide\n\ndf = (x = exp.(rand(1000)),)\nhist2 = data(df) * mapping(:x => log => \"log(x)\") * histogram()\nfg = draw(hist2; figure = (size = (600, 400),))\n\nlines(fg.figure[1, 2], 0..2pi, cos)\n\nfg #hide","category":"page"},{"location":"FAQs/","page":"Frequently Asked Questions","title":"Frequently Asked Questions","text":"note: Note\nWhen setting the width and height dimensions of each axis manually you will need to call resize_to_layout!(fg) before displaying the figure such that each axis is sized correctly.","category":"page"},{"location":"philosophy/#Philosophy","page":"Philosophy","title":"Philosophy","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"AlgebraOfGraphics aims to be a declarative, question-driven language for data visualizations. This section describes its main guiding principles.","category":"page"},{"location":"philosophy/#From-question-to-plot","page":"Philosophy","title":"From question to plot","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"When analyzing a dataset, we often think in abstract, declarative terms. We have questions concerning our data, which can be answered by appropriate visualizations. For instance, we could ask whether a discrete variable :x affects the distribution of a continuous variable :y. We would then like to generate a visualization that answers this question.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"In imperative programming, this would be implemented via the following steps.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Pick the dataset.\nDivide the dataset into subgroups according to the values of :x.\nCompute the density of :y on each subgroup.\nChoose a plot attribute to distinguish subgroups, for instance color.\nSelect as many distinguishable colors as there are unique values of :x.\nPlot all the density curves on top of each other.\nCreate a legend, describing how unique values of :x are associated to colors.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"While the above procedure is certainly feasible, it can introduce a cognitive overhead, especially when more variables and attributes are involved.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"In a declarative framework, the user needs to express the question, and the library will take care of creating the visualization. Let us solve the above problem in a toy dataset.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"using AlgebraOfGraphics, CairoMakie\nusing AlgebraOfGraphics: density\nset_aog_theme!()\nN = 1000\nx = rand([\"Class 1\", \"Class 2\", \"Class 3\", \"Class 4\"], N)\ny = @. (x == \"Class 1\") * randn() + (x == \"Class 2\") - (x == \"Class 3\") + randn()\nz = @. (x == \"Class 2\") * randn() + (x == \"Class 2\") + (x == \"Class 3\") + y + randn()\ndf = (; x, y, z)","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"plt = data(df) # declare the dataset\nplt *= density() # declare the analysis\nplt *= mapping(:y) # declare the arguments of the analysis\nplt *= mapping(color = :x) # declare the grouping and the respective visual attribute\ndraw(plt) # draw the visualization and its legend","category":"page"},{"location":"philosophy/#No-mind-reading","page":"Philosophy","title":"No mind reading","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Plotting packages requires the user to specify a large amount of settings. The temptation is then to engineer a plotting library in such a way that it would guess what the user actually wanted. AlgebraOfGraphics follows a different approach, based on algebraic manipulations of plot descriptors.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"The key intuition is that a large fraction of the \"clutter\" in a plot specification comes from repeating the same information over and over. Different layers of the same plot will share some but not all information, and the user should be able to distinguish settings that are private to a layer from those that are shared across layers.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"We achieve this goal using the distributive properties of addition and multiplication. This is best explained by example. Let us assume that we wish to visually inspect whether a discrete variable :x affects the joint distribution of two continuous variables, :y and :z.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"We would like to have two layers, one with the raw data, the other with an analysis (kernel density estimation).","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Naturally, the axes should represent the same variables (:y and :z) for both layers. Only the density layer should be a contour plot, whereas only the scatter layer should have some transparency and be grouped (according to :x) in different subplots.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"plt = data(df) *\n (\n visual(Scatter, alpha = 0.3) * mapping(layout = :x) +\n density() * visual(Contour, colormap = Reverse(:grays))\n ) *\n mapping(:y, :z)\ndraw(plt)","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"In this case, thanks to the distributive property, it is clear that the dataset and the positional arguments :y, :z are shared across layers, the transparency and the grouping are specific to the data layer, whereas the density analysis, the Contour visualization, and the choice of color map are specific to the analysis layer.","category":"page"},{"location":"philosophy/#User-defined-building-blocks","page":"Philosophy","title":"User-defined building blocks","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"It is common in data analysis tasks to \"pipe\" a sequence of operations. This became very popular in the data science field with the %>% operator in the R language, and it can allow users to seamlessly compose a sequence of tasks:","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"df %>%\n filter(Weight < 3) %>%\n group_by(Species) %>%\n summarise(avg_height = mean(Height))","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Naturally, the alternative would be to create a statement per operation and to assign each intermediate result to its own variable.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"AlgebraOfGraphics is markedly in favor of the latter approach. It is recommended that commonly used building blocks are stored in variables with meaningful names. If we often make a scatter plot with some transparency, we can create a variable transparent_scatter = visual(Scatter, alpha = 0.5) and use it consistently. If some columns of our dataset are always analyzed together, with a similar set of transformations, we can store that information as variables = mapping(variable1 => f1 => label1, variable2 => f2 => label2).","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Working over one or more datasets, the user would then create a library of building blocks to be combined with each other with * and +. These two operators allow for a much larger number of possible combinations than just sequential composition, thus fully justifying the extra characters used to name intermediate entities.","category":"page"},{"location":"philosophy/#Opinionated-defaults","page":"Philosophy","title":"Opinionated defaults","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"While users should be able to customize every aspect of their plots, it is important to note that this customization can be very time-consuming, and many subtleties can escape the attention of the casual user:","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Is the color palette colorblind-friendly?\nWould the colors be distinguishable in black and white (when printed)?\nIs the color gradient perceptually uniform?\nAre the labels and the ticks legible for readers with low vision?\nAre the spacing and typographic hierarchies respected?","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"To remedy this, AlgebraOfGraphics aims to provide solid, opinionated default settings. In particular, it uses a conservative, colorblind-friendly palette and a perceptually uniform, universally readable color map. It follows IBM guidelines to differentiate titles and labels from tick labels via font weight, while using the same typeface at a readable size.","category":"page"},{"location":"philosophy/#Wide-format-support","page":"Philosophy","title":"Wide format support","text":"","category":"section"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"Finally, AlgebraOfGraphics aims to support many different data formats. Different problems require organizing the data in different formats, and AlgebraOfGraphics should support a wide range of options.","category":"page"},{"location":"philosophy/","page":"Philosophy","title":"Philosophy","text":"This is achieved in three different ways. First, the Tables interface ensures integration with a large variety of data sources. Second, using the Wide data syntax, users can compare many different columns in the same visualization, without having to first reshape the dataset to a long format. Finally, tabular datasets are not a requirement: users may also work directly with Pre-grouped data, which are not organized as a table, but rather as a collection of (possibly multi-dimensional) arrays.","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/multiple_color_scales.jl\"","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/#Multiple-color-scales","page":"Multiple color scales","title":"Multiple color scales","text":"","category":"section"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"Continuous and discrete color scales can coexist in the same plot. This should be used sparingly, as it can make the plot harder to interpret.","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"x = range(-π, π, length=100)\ny = sin.(x)\nŷ = y .+ randn.() .* 0.1\nz = cos.(x)\nc = rand([\"a\", \"b\"], 100)\ndf = (; x, y, ŷ, z, c)\nlayers = mapping(:y, color=:z) * visual(Lines) + mapping(:ŷ => \"y\", color=:c)\nplt = data(df) * mapping(:x) * layers\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"","category":"page"},{"location":"gallery/gallery/scales/multiple_color_scales/","page":"Multiple color scales","title":"Multiple color scales","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"EditURL = \"analyses.jl\"","category":"page"},{"location":"generated/analyses/#Analyses","page":"Analyses","title":"Analyses","text":"","category":"section"},{"location":"generated/analyses/#Histogram","page":"Analyses","title":"Histogram","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"histogram","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.histogram","page":"Analyses","title":"AlgebraOfGraphics.histogram","text":"histogram(; bins=automatic, datalimits=automatic, closed=:left, normalization=:none)\n\nCompute a histogram.\n\nThe attribute bins can be an Integer, an AbstractVector (in particular, a range), or a Tuple of either integers or abstract vectors (useful for 2- or 3-dimensional histograms). When bins is an Integer, it denotes the approximate number of equal-width intervals used to compute the histogram. In that case, the range covered by the intervals is defined by datalimits (it defaults to the extrema of the whole data). The keyword argument datalimits can be a tuple of two values, e.g. datalimits=(0, 10), or a function to be applied group by group, e.g. datalimits=extrema. When bins is an AbstractVector, it denotes the intervals directly.\n\nclosed determines whether the the intervals are closed to the left or to the right.\n\nThe histogram can be normalized by setting normalization. Possible values are:\n\n:pdf: Normalize by sum of weights and bin sizes. Resulting histogram has norm 1 and represents a PDF.\n:density: Normalize by bin sizes only. Resulting histogram represents count density of input and does not have norm 1.\n:probability: Normalize by sum of weights only. Resulting histogram represents the fraction of probability mass for each bin and does not have norm 1.\n:none: Do not normalize.\n\nWeighted data is supported via the keyword weights (passed to mapping).\n\nnote: Note\nNormalizations are computed withing groups. For example, in the case of normalization=:pdf, sum of weights within each group will be equal to 1.\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"using AlgebraOfGraphics, CairoMakie\nset_aog_theme!()\n\ndf = (x=randn(5000), y=randn(5000), z=rand([\"a\", \"b\", \"c\"], 5000))\nspecs = data(df) * mapping(:x, layout=:z) * histogram(bins=range(-2, 2, length=15))\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, dodge=:z, color=:z) * histogram(bins=range(-2, 2, length=15))\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, stack=:z, color=:z) * histogram(bins=range(-2, 2, length=15))\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) *\n mapping((:x, :z) => ((x, z) -> x + 5 * (z == \"b\")) => \"new x\", col=:z) *\n histogram(datalimits=extrema, bins=20)\ndraw(specs, facet=(linkxaxes=:minimal,))","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"data(df) * mapping(:x, :y, layout=:z) * histogram(bins=15) |> draw","category":"page"},{"location":"generated/analyses/#Density","page":"Analyses","title":"Density","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"AlgebraOfGraphics.density","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.density","page":"Analyses","title":"AlgebraOfGraphics.density","text":"density(; datalimits=automatic, kernel=automatic, bandwidth=automatic, npoints=200)\n\nFit a kernel density estimation of data.\n\nHere, datalimits specifies the range for which the density should be calculated (it defaults to the extrema of the whole data). The keyword argument datalimits can be a tuple of two values, e.g. datalimits=(0, 10), or a function to be applied group by group, e.g. datalimits=extrema. The keyword arguments kernel and bandwidth are forwarded to KernelDensity.kde. npoints is the number of points used by Makie to draw the line\n\nWeighted data is supported via the keyword weights (passed to mapping).\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"df = (x=randn(5000), y=randn(5000), z=rand([\"a\", \"b\", \"c\", \"d\"], 5000))\nspecs = data(df) * mapping(:x, layout=:z) * AlgebraOfGraphics.density(datalimits=((-2.5, 2.5),))\n\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) *\n mapping((:x, :z) => ((x, z) -> x + 5 * (z ∈ [\"b\", \"d\"])) => \"new x\", layout=:z) *\n AlgebraOfGraphics.density(datalimits=extrema)\ndraw(specs, facet=(linkxaxes=:minimal,))","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"data(df) * mapping(:x, :y, layout=:z) * AlgebraOfGraphics.density(npoints=50) |> draw","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, :y, layout=:z) *\n AlgebraOfGraphics.density(npoints=50) * visual(Surface)\n\ndraw(specs, axis=(type=Axis3, zticks=0:0.1:0.2, limits=(nothing, nothing, (0, 0.2))))","category":"page"},{"location":"generated/analyses/#Frequency","page":"Analyses","title":"Frequency","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"frequency","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.frequency","page":"Analyses","title":"AlgebraOfGraphics.frequency","text":"frequency()\n\nCompute a frequency table of the arguments.\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"df = (x=rand([\"a\", \"b\", \"c\"], 100), y=rand([\"a\", \"b\", \"c\"], 100), z=rand([\"a\", \"b\", \"c\"], 100))\nspecs = data(df) * mapping(:x, layout=:z) * frequency()\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, layout=:z, color=:y, stack=:y) * frequency()\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, :y, layout=:z) * frequency()\ndraw(specs)","category":"page"},{"location":"generated/analyses/#Expectation","page":"Analyses","title":"Expectation","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"expectation","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.expectation","page":"Analyses","title":"AlgebraOfGraphics.expectation","text":"expectation()\n\nCompute the expected value of the last argument conditioned on the preceding ones.\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"df = (x=rand([\"a\", \"b\", \"c\"], 100), y=rand([\"a\", \"b\", \"c\"], 100), z=rand(100), c=rand([\"a\", \"b\", \"c\"], 100))\nspecs = data(df) * mapping(:x, :z, layout=:c) * expectation()\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, :z, layout=:c, color=:y, dodge=:y) * expectation()\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"specs = data(df) * mapping(:x, :y, :z, layout=:c) * expectation()\ndraw(specs)","category":"page"},{"location":"generated/analyses/#Linear","page":"Analyses","title":"Linear","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"linear","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.linear","page":"Analyses","title":"AlgebraOfGraphics.linear","text":"linear(; interval=automatic, level=0.95, dropcollinear=false, npoints=200)\n\nCompute a linear fit of y ~ 1 + x. An optional named mapping weights determines the weights. Use interval to specify what type of interval the shaded band should represent, for a given coverage level (the default 0.95 equates alpha = 0.05). Valid values of interval are :confidence, to delimit the uncertainty of the predicted relationship, and :prediction, to delimit estimated bounds for new data points. Use interval = nothing to only compute the line fit, without any uncertainty estimate. By default, this analysis errors on singular (collinear) data. To avoid that, it is possible to set dropcollinear=true. npoints is the number of points used by Makie to draw the shaded band.\n\nWeighted data is supported via the keyword weights (passed to mapping).\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"x = 1:0.05:10\na = rand(1:7, length(x))\ny = 1.2 .* x .+ a .+ 0.5 .* randn.()\ndf = (; x, y, a)\nspecs = data(df) * mapping(:x, :y, color=:a => nonnumeric) * (linear() + visual(Scatter))\ndraw(specs)","category":"page"},{"location":"generated/analyses/#Smoothing","page":"Analyses","title":"Smoothing","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"smooth","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.smooth","page":"Analyses","title":"AlgebraOfGraphics.smooth","text":"smooth(; span=0.75, degree=2, npoints=200)\n\nFit a loess model. span is the degree of smoothing, typically in [0,1]. Smaller values result in smaller local context in fitting. degree is the polynomial degree used in the loess model. npoints is the number of points used by Makie to draw the line\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"x = 1:0.05:10\na = rand(1:7, length(x))\ny = sin.(x) .+ a .+ 0.1 .* randn.()\ndf = (; x, y, a)\nspecs = data(df) * mapping(:x, :y, color=:a => nonnumeric) * (smooth() + visual(Scatter))\ndraw(specs)","category":"page"},{"location":"generated/analyses/#Contours","page":"Analyses","title":"Contours","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"contours","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.contours","page":"Analyses","title":"AlgebraOfGraphics.contours","text":"contours(; levels=5, kwargs...)\n\nCreate contour lines over the grid spanned over x and y by args 1 and 2 in the mapping, with height values z passed via arg 3. \n\nYou can pass the number of levels as an integer or a vector of levels. The levels are calculated across the whole z data if they are specified as an integer.\n\nNote that visual(Contour) only works in a limited way with AlgebraOfGraphics since version 0.7, because the internal calculations it does are not compatible with the scale system. With visual(Contour), you can only have categorically-colored contours (for example to visualize contours of multiple categories). Alternatively, if you set the colormap attribute, you can get continuously-colored contours but the levels will not be known to AlgebraOfGraphics, so they won't be synchronized across facets and there will not be a colorbar.\n\nAll other keyword arguments are forwarded as attributes to the underlying Contour plot.\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"x = repeat(1:10, 10)\ny = repeat(11:20, inner = 10)\nz = sqrt.(x .* y)\ndf = (; x, y, z)\nspecs = data(df) * mapping(:x, :y, :z) * contours(levels = 8)\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"x = repeat(1:10, 10)\ny = repeat(11:20, inner = 10)\nz = sqrt.(x .* y)\ndf = (; x, y, z)\nspecs = data(df) * mapping(:x, :y, :z) * contours(levels = 8, labels = true)\ndraw(specs)","category":"page"},{"location":"generated/analyses/#Filled-Contours","page":"Analyses","title":"Filled Contours","text":"","category":"section"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"filled_contours","category":"page"},{"location":"generated/analyses/#AlgebraOfGraphics.filled_contours","page":"Analyses","title":"AlgebraOfGraphics.filled_contours","text":"filled_contours(; bands=automatic, levels=automatic)\n\nCreate filled contours over the grid spanned over x and y by args 1 and 2 in the mapping, with height values z passed via arg 3. \n\nYou can pass either the number of bands to bands or pass a vector of levels (the boundaries of the bands) to levels, but not both. The number of bands when levels is passed is length(levels) - 1. The levels are calculated across the whole z data if the number of bands is specified. If neither levels nor bands are specified, the default is bands = 10.\n\nNote that visual(Contourf) does not work with AlgebraOfGraphics since version 0.7, because the internal binning it does is not compatible with the scale system.\n\n\n\n\n\n","category":"function"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"x = repeat(1:10, 10)\ny = repeat(11:20, inner = 10)\nz = sqrt.(x .* y)\ndf = (; x, y, z)\nspecs = data(df) * mapping(:x, :y, :z) * filled_contours(levels = 3:2:15)\ndraw(specs)","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"","category":"page"},{"location":"generated/analyses/","page":"Analyses","title":"Analyses","text":"This page was generated using Literate.jl.","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/data manipulations/pre_grouped_data.jl\"","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/#Pre-grouped-data","page":"Pre-grouped data","title":"Pre-grouped data","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"using AlgebraOfGraphics, CairoMakie\n\n\nx = [rand(10) .+ i for i in 1:3]\ny = [rand(10) .+ i for i in 1:3]\nz = [rand(10) .+ i for i in 1:3]\nc = [\"a\", \"b\", \"c\"]\n\nm = pregrouped(x, y, color=c => (t -> \"Type \" * t ) => \"Category\")\ndraw(m)","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"m = pregrouped(x, (y, z) => (+) => \"sum\", color=c => (t -> \"Type \" * t ) => \"Category\")\ndraw(m)","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"m = pregrouped(x, [y z], color=dims(1) => renamer([\"a\", \"b\", \"c\"])) * visual(Scatter)\ndraw(m)","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"m = pregrouped(x, [y z], color=[\"1\" \"2\"])\nlayers = visual(Scatter) + linear()\nfg = draw(m * layers)","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"","category":"page"},{"location":"gallery/gallery/data manipulations/pre_grouped_data/","page":"Pre-grouped data","title":"Pre-grouped data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/customization/legend.jl\"","category":"page"},{"location":"gallery/gallery/customization/legend/#Legend-tweaking","page":"Legend tweaking","title":"Legend tweaking","text":"","category":"section"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: Source code)","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"To tweak the position and appearance of the legend, simply use the legend keyword when plotting. For example","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"labels = [\"a looooooong label\", \"an even loooooonger label\", \"and one more long label\"]\ndf = (x=rand(100), y=rand(100), group=rand(labels, 100))\nlayers = linear() + mapping(color=:group)\nplt = data(df) * layers * mapping(:x, :y)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"fg = draw(plt, legend=(position=:top, titleposition=:left, framevisible=true, padding=5))","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"To adjust the title and order of labels in a legend you can use the pair syntax.","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"layers = linear() + mapping(color=:group => sorter(labels) => \"Labels\")\nplt = data(df) * layers * mapping(:x, :y)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"Adding a plot to a pre-existing figure with draw! will not draw the legend automatically. In this case, one must use legend! and specify the axis to which it should be added.","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"The tellheight = false, tellwidth = false arguments are useful to avoid changing the dimensions of the axis.","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"makie_fig = Figure()\nax_scatter = Axis(makie_fig[1, 1])\n\ngrid = draw!(ax_scatter, plt)\n\nlegend!(makie_fig[1, 1], grid; tellheight=false, tellwidth=false, halign=:right, valign=:top)\n\nmakie_fig","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"If the automatic legend elements are not legible enough, you can change their properties by passing overrides to the legend attribute of a visual.","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"df = (;\n x = repeat(1:100, 5),\n y = reduce(vcat, [[cos(x) for x in range(0, 8pi, length = 100)] .+ 0.3 .* randn.() for _ in 1:5]),\n group = repeat(1:5, inner = 100),\n)\n\nlin = data(df) *\n mapping(:x, :y, group = :group => nonnumeric) *\n visual(Lines, linewidth = 0.3, label = \"Lines\", legend = (; linewidth = 1.5))\nsca = data(df) *\n mapping(:x, :y => y -> y + 5, group = :group => nonnumeric) *\n visual(Scatter, markersize = 3, label = \"Scatter\", legend = (; markersize = 12))\n\ndraw(lin + sca)","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"","category":"page"},{"location":"gallery/gallery/customization/legend/","page":"Legend tweaking","title":"Legend tweaking","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"EditURL = \"visual.jl\"","category":"page"},{"location":"generated/visual/#Visual","page":"Visual","title":"Visual","text":"","category":"section"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"visual","category":"page"},{"location":"generated/visual/#AlgebraOfGraphics.visual","page":"Visual","title":"AlgebraOfGraphics.visual","text":"visual(plottype; attributes...)\n\nCreate a Layer that will cause a plot spec multiplied with it to be visualized with plot type plottype, together with optional attributes.\n\nThe available plotting functions are documented here. Refer to plotting functions using upper CamelCase for visual's first argument (e.g. visual(Scatter), visual(BarPlot)). See the documentation of each plotting function to discover the available attributes. These attributes can be passed as additional keyword arguments to visual, or as part of the mapping you define.\n\nThe visual function can in principle be used for any plotting function that is defined using the @recipe macro from Makie. AlgebraOfGraphics just needs method definitions for aesthetic_mapping, which define what arguments of the plotting function map to which visual aesthetics. And for legend support, legend_elements must be overloaded for custom recipes as well, as Makie's default legend mechanism relies on instantiated plot objects, while AlgebraOfGraphics must go by the type and attributes alone.\n\nDepending on its aesthetic_mapping, a plot type and its attributes may change certain semantics of a given data(...) * mapping(...) spec. For example, visual(BarPlot) will show mapping 1 on the x axis and 2 on the y axis, while visual(BarPlot, direction = :x) shows mapping 1 on y and 2 on x.\n\n\n\n\n\n","category":"function"},{"location":"generated/visual/#Examples","page":"Visual","title":"Examples","text":"","category":"section"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"using AlgebraOfGraphics, CairoMakie\nset_aog_theme!()\n\ndf = (x=randn(1000), y=randn(1000))\nplt = data(df) * mapping(:x, :y) * AlgebraOfGraphics.density(npoints=50)\ndraw(plt * visual(Heatmap)) # plot as heatmap (the default)","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"From AlgebraOfGraphics version 0.7 on, some attributes of the underlying Makie functions will not have an effect if they are controlled by scales instead. For example, continuous colors are completely controlled by color scales, so setting colormap in visual does not have an effect.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"Set the colormap in the Scale options instead.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"draw(plt, scales(Color = (; colormap = :viridis))) # set a different colormap","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"draw(plt * visual(Contour)) # plot as contour","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"draw(plt * visual(Contour, linewidth=2)) # plot as contour with thicker lines","category":"page"},{"location":"generated/visual/#Manual-legend-entries-via-label","page":"Visual","title":"Manual legend entries via label","text":"","category":"section"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"The legend normally contains entries for all appropriate scales used in the plot. Sometimes, however, you just want to label certain plots such that they appear in the legend without using any scale. You can achieve this by adding the label keyword to all visuals that you want to label. Layers with the same label will be combined within a legend entry.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"x = range(0, 4pi, length = 40)\nlayer1 = data((; x = x, y = cos.(x))) * mapping(:x, :y) * visual(Lines, linestyle = :dash, label = \"A cosine line\")\nlayer2 = data((; x = x, y = sin.(x) .+ 2)) * mapping(:x, :y) *\n (visual(Lines, color = (:tomato, 0.4)) + visual(Scatter, color = :tomato)) * visual(label = \"A sine line + scatter\")\ndraw(layer1 + layer2)","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"If the figure contains other scales, the legend will list the labelled group last by default. If you want to reorder, use the symbol :Label to specify the labelled group.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"df = (; x = repeat(1:10, 3), y = cos.(1:30), group = repeat([\"A\", \"B\", \"C\"], inner = 10))\nspec1 = data(df) * mapping(:x, :y, color = :group) * visual(Lines)\n\nspec2 = data((; x = 1:10, y = cos.(1:10) .+ 2)) * mapping(:x, :y) * visual(Scatter, color = :purple, label = \"Scatter\")\n\nf = Figure()\nfg = draw!(f[1, 1], spec1 + spec2)\nlegend!(f[1, 2], fg)\nlegend!(f[1, 3], fg, order = [:Label, :Color])\n\nf","category":"page"},{"location":"generated/visual/#Legend-element-overrides","page":"Visual","title":"Legend element overrides","text":"","category":"section"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"Sometimes it might be necessary to override legend element properties that are otherwise copied from the visual settings. For example, a scatter plot with many small markers might have a legend that is hard to read. We can use AlgebraOfGraphics's legend keyword in visual to specify override attributes via key-value pairs. Here we increase the markersize for the MarkerElements that are created for a Scatter plot:","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"df = (;\n x = randn(200) .+ repeat([0, 3], 100),\n y = randn(200) .+ repeat([0, 3], 100),\n group = repeat([\"A\", \"B\"], 100)\n)\n\nspec = data(df) *\n mapping(:x, :y, color = :group) *\n visual(Scatter; markersize = 5, legend = (; markersize = 15))\n\ndraw(spec)","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"These are the attributes you can override (note that some of them have convenience aliases like color which applies to all elements while polycolor only applies to PolyElements):","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"MarkerElement\n[marker]points, markersize, [marker]strokewidth, [marker]color, [marker]strokecolor, [marker]colorrange, [marker]colormap\nLineElement\n[line]points, linewidth, [line]color, linestyle, [line]colorrange, [line]colormap\nPolyElement\n[poly]points, [poly]strokewidth, [poly]color, [poly]strokecolor, [poly]colorrange, [poly]colormap","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"More information about legend overrides can be found in Makie's documentation.","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"","category":"page"},{"location":"generated/visual/","page":"Visual","title":"Visual","text":"This page was generated using Literate.jl.","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/customization/axis.jl\"","category":"page"},{"location":"gallery/gallery/customization/axis/#Axis-tweaking","page":"Axis tweaking","title":"Axis tweaking","text":"","category":"section"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"To tweak one or more axes, simply use the axis keyword when plotting. For example","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"df = (x=rand(100), y=rand(100), z=rand(100))\nlayers = linear() + mapping(color=:z)\nplt = data(df) * layers * mapping(:x, :y)\ndraw(plt, axis=(aspect=1,))","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"fg = draw(plt, axis=(aspect=1, xticks=0:0.1:1, yticks=0:0.1:1, ylabel=\"custom label\"))","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"","category":"page"},{"location":"gallery/gallery/customization/axis/","page":"Axis tweaking","title":"Axis tweaking","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/secondary_scales.jl\"","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/#Secondary-scales","page":"Secondary scales","title":"Secondary scales","text":"","category":"section"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"By default, scales with the same aesthetic type have their categories merged. This can be undesirable if there are disjoint sets of categories, for example three different time series with two different event markers:","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"nevents = 500\nngroups = 3\ntime = repeat(1:nevents, ngroups)\ny = reduce(vcat, [cumsum(randn(length(time))) for _ in 1:ngroups])\ngroup = repeat([\"A\", \"B\", \"C\"], inner = nevents)\ndf1 = (; time, y, group)\ndf2 = (; time = [30, 79, 250, 400], event = [\"X\", \"Y\", \"Y\", \"X\"])\n\nspec_a = data(df1) * mapping(:time, :y, color = :group) * visual(Lines)\nspec_b = data(df2) * mapping(:time, color = :event) * visual(VLines)\n\ndraw(spec_a + spec_b)","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"By assigning an arbitrary scale identifier to one of the color mappings, we can split the two scales apart and receive a separate legend for both:","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"split_spec = spec_a + spec_b * mapping(color = :event => scale(:secondary))\ndraw(split_spec)","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"Each scale can then be modified separately in the scales configuration. For example, it is not desired that both scales use the same color palette:","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"fg = draw(split_spec, scales(secondary = (;\n palette = [:gray70, :gray30]\n)))","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"If you don't want to have separate legend groups, you can merge them using the order keyword in the legend config.","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"draw(\n split_spec,\n scales(\n secondary = (; palette = [:gray70, :gray30])\n );\n legend = (; order = [[:Color, :secondary] => \"Legend\"])\n)","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"","category":"page"},{"location":"gallery/gallery/scales/secondary_scales/","page":"Secondary scales","title":"Secondary scales","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/customization/figure.jl\"","category":"page"},{"location":"gallery/gallery/customization/figure/#Figure-tweaking","page":"Figure tweaking","title":"Figure tweaking","text":"","category":"section"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"You can pass attributes to the underlying Makie.Figure using the figure keyword of draw.","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"df = (x=rand(100), y=rand(100), z=rand(100), c=rand([\"a\", \"b\"], 100))\nxyc = data(df) * mapping(:x, :y, layout=:c)\nlayers = linear() + mapping(color=:z)\nplt = xyc * layers\ndraw(\n plt,\n figure = (;\n figure_padding = 10,\n backgroundcolor = :gray80,\n size = (800, 400)\n )\n)","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"You can also add a figure title, subtitle and footnotes.","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"fg = draw(\n plt,\n figure = (;\n figure_padding = 10,\n backgroundcolor = :gray80,\n size = (800, 400),\n title = \"Figure title\",\n subtitle = \"Some subtitle below the figure title\",\n footnotes = [\n rich(superscript(\"1\"), \"First footnote\"),\n rich(superscript(\"2\"), \"Second footnote\"),\n ]\n )\n)","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"The appearance of these elements can be modified further, for all options check the draw function.","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"draw(\n plt,\n figure = (;\n figure_padding = 10,\n backgroundcolor = :gray80,\n size = (800, 400),\n title = \"Figure title\",\n subtitle = \"Some subtitle below the figure title\",\n footnotes = [\n rich(superscript(\"1\"), \"First footnote\"),\n rich(superscript(\"2\"), \"Second footnote\"),\n ],\n titlecolor = :firebrick,\n titlealign = :right,\n footnotefont = :bold,\n )\n)","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"","category":"page"},{"location":"gallery/gallery/customization/figure/","page":"Figure tweaking","title":"Figure tweaking","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"layers/mapping/#Mapping","page":"Mapping","title":"Mapping","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Mappings determine how the data is translated into a plot. For example, this mapping maps columns weight and height to positional arguments 1 and 2, and age to the markersize attribute of the Scatter plotting function:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"mapping(:weight, :height, markersize = :age)","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"mapping","category":"page"},{"location":"layers/mapping/#AlgebraOfGraphics.mapping","page":"Mapping","title":"AlgebraOfGraphics.mapping","text":"mapping(positional...; named...)\n\nCreate a Layer with positional and named selectors. These selectors will be translated into input data for the Makie plotting function or AlgebraOfGraphics analysis that is chosen to visualize the Layer.\n\nA Layer created with mapping does not have a data source by default, you can add one by multiplying with the output of the data function.\n\nThe positional and named selectors of mapping are converted to actual input data for the plotting function that will be selected via visual. The translation from selector to data differs according to the data source.\n\nTabular data\n\nWhen a mapping is combined with a data(tabular) where tabular is some Tables.jl-compatible object, each argument will be interpreted as a column selector. Additionally, it's allowed to specify columns outside of the dataset directly by wrapping the values in direct. The values can either be vectors that have to match the number of rows from the tabular data, or scalars that will be expanded as if they were a column filled with the same value.\n\nmapping(\n :x, # column named \"x\"\n \"a column\"; # column named \"a column\"\n color = 1, # first column\n marker = direct(\"abc\"), # a new column filled with the string \"abc\"\n linestyle = direct(1:3), # a new column, length must match the table\n)\n\nnothing\n\nIf no data is set, each entry of mapping should be an AbstractVector that specifies a column of data directly. Scalars like strings for example will be expanded as if they were a column filled with the same value. This is useful when a legend should be shown, but there's only one group.\n\nmapping(\n 1:3, # a column with values 1 to 3\n [4, 5, 6], # a column with values 4 to 6 \n color = \"group 1\", # a column with repeated value \"group 1\" \n)\n\nPregrouped\n\nWith data(Pregrouped()) * mapping(...) or the shortcut pregrouped(...), each element in mapping specifies input data directly, like with nothing. However, in this mode, data should be passed in pregrouped. Categorical variables should come as a vector of categories, while numerical variables should come as a vector of vectors of values, with as many inner vectors as there are groups in the categorical variables.\n\npregrouped(\n [[1, 2, 3], [4, 5]], # two grouped vectors, of length 3 and 2\n color = [\"A\", \"B\"] # a vector with two categorical group values\n)\n\n\n\n\n\n","category":"function"},{"location":"layers/mapping/#Aesthetics","page":"Mapping","title":"Aesthetics","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"The structure of a mapping is always directly tied to the signature of the plotting function (or analysis) that it is being connected with. What visual aspects of the plot the positional or keyword arguments affect depends on the plotting function in use.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"To be used with AlgebraOfGraphics, a plotting function has to add a declaration which aesthetics (like X, Y, Color, MarkerSize, LineStyle) its arguments map to. This mechanism allows AlgebraOfGraphics to correctly convert the raw input data into visual attributes for each plotting function and to correctly create and label axes, colorbars and legends.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Aesthetics can also change depending on attributes passed to visual.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"For example, for a BarPlot, args 1 and 2 correspond to the X and Y aesthetics by default. But if you change the direction in the visual, then axis labels shift accordingly because the aesthetic mapping has changed to 1 = Y, 2 = X:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (; name = [\"Anna\", \"Beatrix\", \"Claire\"], height_meters = [1.55, 1.76, 1.63])\nm = mapping(:name, :height_meters)\nspec1 = data(df) * m * visual(BarPlot)\nspec2 = data(df) * m * visual(BarPlot, direction = :x)\n\nf = Figure()\ndraw!(f[1, 1], spec1)\ndraw!(f[1, 2], spec2)\nf","category":"page"},{"location":"layers/mapping/#Hardcoded-aesthetics","page":"Mapping","title":"Hardcoded aesthetics","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Most aesthetics are tied to specific attributes of plot types, for example like AesColor to strokecolor of Scatter. There are a few aesthetics, however, which are hardcoded to belong to certain mapping keywords independent of the plot type in use.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"These are layout, row and col for facetting, group for creating a separate plot for each group (like separate lines instead of one long line) and dodge_x and dodge_y for dodging.","category":"page"},{"location":"layers/mapping/#Dodging","page":"Mapping","title":"Dodging","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Dodging refers to the shifting of plots on a (usually categorical) scale depending on the group they belong to. It is used to avoid overlaps. Some plot types, like BarPlot, have their own dodge keyword because their dodging logic additionally needs to transform the visual elements (for example, dodging a bar plot makes thinner bars). For all other plot types, you can use the generic dodge_x and dodge_y keywords.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"They work by shifting each categorical group by some value that depends on the chosen \"dodge width\". The dodge width refers to the width that all dodged elements in a group add up to at a given point. Some plot types have an inherent width, like barplots. Others have no width, like scatters or errorbars. For those plot types that have no width to use for dodging, you have to specify one manually in scales.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Here's an example of a manual width selection:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (\n x = repeat(1:10, inner = 2),\n y = cos.(range(0, 2pi, length = 20)),\n ylow = cos.(range(0, 2pi, length = 20)) .- 0.2,\n yhigh = cos.(range(0, 2pi, length = 20)) .+ 0.3,\n dodge = repeat([\"A\", \"B\"], 10)\n)\n\nf = Figure()\nplt = data(df) * (\n mapping(:x, :y, dodge_x = :dodge, color = :dodge) * visual(Scatter) +\n mapping(:x, :ylow, :yhigh, dodge_x = :dodge, color = :dodge) * visual(Rangebars)\n)\ndraw!(f[1, 1], plt, scales(DodgeX = (; width = 1)), axis = (; title = \"width = 1\"))\ndraw!(f[1, 2], plt, scales(DodgeX = (; width = 0.75)), axis = (; title = \"width = 0.75\"))\ndraw!(f[2, 1], plt, scales(DodgeX = (; width = 0.5)), axis = (; title = \"width = 0.5\"))\ndraw!(f[2, 2], plt, scales(DodgeX = (; width = 0.25)), axis = (; title = \"width = 0.25\"))\nf","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"A common scenario is plotting errorbars on top of barplots. In this case, AlgebraOfGraphics can detect the inherent dodging width of the barplots and adjust accordingly for the errorbars. Note in this example how choosing a manual dodging width only applies to the errorbars (because the barplot plot type handles this internally) and potentially leads to a misalignment between the different plot elements:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (\n x = repeat(1:10, inner = 2),\n y = cos.(range(0, 2pi, length = 20)),\n ylow = cos.(range(0, 2pi, length = 20)) .- 0.2,\n yhigh = cos.(range(0, 2pi, length = 20)) .+ 0.3,\n dodge = repeat([\"A\", \"B\"], 10)\n)\n\nf = Figure()\nplt = data(df) * (\n mapping(:x, :y, dodge = :dodge, color = :dodge) * visual(BarPlot) +\n mapping(:x, :ylow, :yhigh, dodge_x = :dodge) * visual(Rangebars)\n)\ndraw!(f[1, 1], plt, axis = (; title = \"No width specified, auto-determined by AlgebraOfGraphics\"))\ndraw!(f[2, 1], plt, scales(DodgeX = (; width = 0.25)), axis = (; title = \"Manually specifying width = 0.25 leads to a mismatch\"))\nf","category":"page"},{"location":"layers/mapping/#Pair-syntax","page":"Mapping","title":"Pair syntax","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"The Pair operator => can be used for three different purposes within mapping:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"renaming columns\ntransforming columns by row\nmapping data to a custom scale","category":"page"},{"location":"layers/mapping/#Renaming-columns","page":"Mapping","title":"Renaming columns","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndata((; name = [\"Anna\", \"Beatrix\", \"Claire\"], height_meters = [1.55, 1.76, 1.63])) *\n mapping(:name => \"Name\", :height_meters => \"Height (m)\") *\n visual(BarPlot) |> draw ","category":"page"},{"location":"layers/mapping/#Transforming-columns","page":"Mapping","title":"Transforming columns","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"If a Function is paired to the column selector, it is applied by row to the data. Often, you will want to also assign a new name that fits the transformed data, in which case you can use the three-element column => transformation => name syntax:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndata((; name = [\"Anna\", \"Beatrix\", \"Claire\"], height_meters = [1.55, 1.76, 1.63])) *\n mapping(:name => (n -> n[1] * \".\"), :height_meters => (x -> x * 100) => \"Height (cm)\") *\n visual(BarPlot) |> draw","category":"page"},{"location":"layers/mapping/#Row-by-row-versus-whole-column-operations","page":"Mapping","title":"Row-by-row versus whole-column operations","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"The pair syntax acts row by row, unlike, e.g., DataFrames.transform. This has several advantages.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Simpler for the user in most cases.\nLess error prone especially\nwith grouped data (should a column operation apply to each group or the whole dataset?)\nwhen several datasets are used","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Naturally, this also incurs some downsides, as whole-column operations, such as z-score standardization, are not supported: they should be done by adding a new column to the underlying dataset beforehand.","category":"page"},{"location":"layers/mapping/#Functions-of-several-arguments","page":"Mapping","title":"Functions of several arguments","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"In the case of functions of several arguments, such as isequal, the input variables must be passed as a Tuple.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"accuracy = (:species, :predicted_species) => isequal => \"accuracy\"","category":"page"},{"location":"layers/mapping/#Helper-functions","page":"Mapping","title":"Helper functions","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Some helper functions are provided, which can be used within the pair syntax to either rename and reorder unique values of a categorical column on the fly or to signal whether a numerical column should be treated as categorical.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"The complete API of helper functions is available at Mapping helpers, but here are a few examples:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"# column `train` has two unique values, `true` and `false`\n:train => renamer([true => \"training\", false => \"testing\"]) => \"Dataset\"\n# column `price` has three unique values, `\"low\"`, `\"medium\"`, and `\"high\"`\n:price => sorter([\"low\", \"medium\", \"high\"])\n# column `age` is expressed in integers and we want to treat it as categorical\n:age => nonnumeric\n# column `labels` is expressed in strings and we do not want to treat it as categorical\n:labels => verbatim\n# wrap categorical values to signal that the order from the data source should be respected\n:weight => presorted","category":"page"},{"location":"layers/mapping/#Custom-scales","page":"Mapping","title":"Custom scales","text":"","category":"section"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"All columns mapped to the same aesthetic type are represented using the same scale by default. This is evident if you plot two different datasets with two different plot types.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"In the following example, both Scatter and HLines use the Color aesthetic, Scatter for the strokecolor keyword and HLines for color. A single merged legend is rendered for both, which does not have a title because it derives from two differently named columns.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf_a = (; x = 1:9, y = [1, 2, 3, 5, 6, 7, 9, 10, 11], group = repeat([\"A\", \"B\", \"C\"], inner = 3))\n\nspec1 = data(df_a) * mapping(:x, :y, strokecolor = :group) * visual(Scatter, color = :transparent, strokewidth = 3, markersize = 15)\n\ndf_b = (; y = [4, 8], threshold = [\"first\", \"second\"])\n\nspec2 = data(df_b) * mapping(:y, color = :threshold) * visual(HLines)\n\ndraw(spec1 + spec2)","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"If we want to have separate legends for both, we can assign a custom scale identifier to either the strokecolor or the color mapping. The name can be chosen freely, it serves only to disambiguate.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"spec2_custom_scale = data(df_b) * mapping(:y, color = :threshold => scale(:color2)) * visual(HLines)\n\ndraw(spec1 + spec2_custom_scale)","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"Each scale can be customized further by passing configuration options via scales as the second argument of the draw function. More information on scale options can be found under Scale options.","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"As an example, we can pass separate colormaps using the palette keyword:","category":"page"},{"location":"layers/mapping/","page":"Mapping","title":"Mapping","text":"spec2_custom_scale = data(df_b) * mapping(:y, color = :threshold => scale(:color2)) * visual(HLines)\n\ndraw(\n spec1 + spec2_custom_scale,\n scales(\n Color = (; palette = [:red, :green, :blue]),\n color2 = (; palette = [:gray30, :gray80]),\n )\n)","category":"page"},{"location":"changelog/#Changelog","page":"Changelog","title":"Changelog","text":"","category":"section"},{"location":"changelog/#Unreleased","page":"Changelog","title":"Unreleased","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: paginate now splits facet plots into pages after fitting scales and not before #593. This means that, e.g., categorical color mappings are consistent across pages where before each page could have a different mapping if some groups were not represented on a given page. This change also makes pagination work with the split X and Y scales feature enabled by version 0.8.14. paginate's return type changes from PaginatedLayers to Pagination because no layers are stored in that type anymore. The interface to use Pagination with draw and other functions doesn't change compared to PaginatedLayers. paginate now also accepts an optional second positional argument which are the scales that are normally passed to draw when not paginating, but which must be available prior to pagination to fit all scales accordingly.","category":"page"},{"location":"changelog/#v0.8.14-2025-01-16","page":"Changelog","title":"v0.8.14 - 2025-01-16","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added automatic alpha forwarding to all legend elements which will have an effect from Makie 0.22.1 on #588.\nAdded the ability to use multiple different X and Y scales within one facet layout. The requirement is that not more than one X and Y scale is used per facet. Row, Col and Layout scales got the ability to set show_labels = false in scales. Also added the zerolayer function which can be used as a basis to build up the required mappings iteratively #586.\nIncreased compat to Makie 0.22 and GeometryBasics 0.5 #587.\nIncreased compat to Colors 0.13 #589.","category":"page"},{"location":"changelog/#v0.8.13-2024-10-21","page":"Changelog","title":"v0.8.13 - 2024-10-21","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added aesthetics for Stairs #573.","category":"page"},{"location":"changelog/#v0.8.12-2024-10-07","page":"Changelog","title":"v0.8.12 - 2024-10-07","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added legend keyword in visual to allow overriding legend element attributes #570.","category":"page"},{"location":"changelog/#v0.8.11-2024-09-25","page":"Changelog","title":"v0.8.11 - 2024-09-25","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixed lexicographic natural sorting of tuples (this would fall back to default sort order before) #568.","category":"page"},{"location":"changelog/#v0.8.10-2024-09-24","page":"Changelog","title":"v0.8.10 - 2024-09-24","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixed markercolor in ScatterLines legends when it did not match color #567.","category":"page"},{"location":"changelog/#v0.8.9-2024-09-24","page":"Changelog","title":"v0.8.9 - 2024-09-24","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added ability to include layers in the legend without using scales by adding visual(label = \"some label\") #565.","category":"page"},{"location":"changelog/#v0.8.8-2024-09-17","page":"Changelog","title":"v0.8.8 - 2024-09-17","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixed aesthetics of errorbar so that x and y stay labelled correctly when using direction = :x #560.\nAdded ability to specify title, subtitle and footnotes plus settings in the draw function #556.\nAdded dodge_x and dodge_y keywords to mapping that allow to dodge any plot types that have AesX or AesY data #558.","category":"page"},{"location":"changelog/#v0.8.7-2024-09-06","page":"Changelog","title":"v0.8.7 - 2024-09-06","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added ability to return ProcessedLayers from transformations, thereby enabling multi-layer transformations, such as scatter plus errorbars #549.\nFixed bug where mergesorted applied on string vectors used isless instead of natural sort #553.","category":"page"},{"location":"changelog/#v0.8.6-2024-09-02","page":"Changelog","title":"v0.8.6 - 2024-09-02","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added bar_labels to BarPlot's aesthetic mapping #544.\nAdded ability to hide legend or colorbar by passing, e.g., legend = (; show = false) to draw #547.","category":"page"},{"location":"changelog/#v0.8.5-2024-08-27","page":"Changelog","title":"v0.8.5 - 2024-08-27","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added presorted helper function to keep categorical data in the order encountered in the source table, instead of sorting it alphabetically #529.\nAdded from_continuous helper function which allows to sample continuous colormaps evenly to use them as categorical palettes without having to specify how many categories there are #541.","category":"page"},{"location":"changelog/#v0.8.4-2024-08-26","page":"Changelog","title":"v0.8.4 - 2024-08-26","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added fillto to BarPlot aesthetics #535.\nFixed bug when giving datalimits of density as a (low, high) tuple #536.\nFixed bug where facet-local continuous scale limits were used instead of the globally merged ones, possibly leading to mismatches between data and legend #539.","category":"page"},{"location":"changelog/#v0.8.3-2024-08-23","page":"Changelog","title":"v0.8.3 - 2024-08-23","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixed incorrect x/y axis assignment for the violin plot type #528.","category":"page"},{"location":"changelog/#v0.8.2-2024-08-21","page":"Changelog","title":"v0.8.2 - 2024-08-21","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Enable use of LaTeXStrings and rich text in renamer #525.\nFixed widths of boxplots with color groupings #524.","category":"page"},{"location":"changelog/#v0.8.1-2024-08-20","page":"Changelog","title":"v0.8.1 - 2024-08-20","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added back support for Hist, CrossBar, ECDFPlot and Density #522.","category":"page"},{"location":"changelog/#v0.8.0-2024-07-26","page":"Changelog","title":"v0.8.0 - 2024-07-26","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: Columns with element types of Union{Missing,T} are not treated as categorical by default anymore, instead T decides if data is seen as categorical, continuous or geometrical. If you relied on numerical vectors with missings being treated as categorical, you can use :columnname => nonnumeric in the mapping instead.\nBreaking: AbstractString categories are now sorted with natural sort order by default. This means that where you got [\"1\", \"10\", \"2\"] before, you now get [\"1\", \"2\", \"10\"]. You can use sorter, the categories keyword or categorical arrays to sort your data differently if needed.","category":"page"},{"location":"changelog/#v0.7.0-2024-07-16","page":"Changelog","title":"v0.7.0 - 2024-07-16","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: The palette keyword of draw linking palettes to keyword arguments was removed. Instead, palettes need to be passed to specific scales like draw(..., scales(Color = (; palette = :Set1_3)))\nBreaking: All recipes need to have the new function aesthetic_mapping defined for all sets of positional arguments that should be supported, as can be seen in src/aesthetics.jl. This breaks usage of all custom recipes. Additionally, not all Makie plots have been ported to the new system yet. If you encounter missing plots, or missing attributes of already ported plots, please open an issue.\nBreaking: All custom recipes that should be displayed in a legend, need to have legend_elements(P, attributes, scale_args) defined as can be seen in src/guides/legend.jl. AlgebraOfGraphics cannot use the same default mechanism as Makie, which can create a legend from an existing plot, because AlgebraOfGraphics needs to create the legend before the plot is instantiated.\nBreaking: Pregrouped data cannot be passed anymore to the plain mapping(...) without any data(tabular). Instead, you should use pregrouped(...) which is a shortcut for data(Pregrouped()) * mapping(...).\nBreaking: Contour and Contourf generally do not work anymore with visual(). Instead, the contours() and filled_contours() analyses should be used. Contour can still be used with categorical colors, but not with continuous ones.\nBreaking: All colormap properties for continuous color scales need to be passed via scales now, and not through visual. This is to have central control over the scale as it can be used by multiple visuals simultaneously.\nHorizontal barplots, violins, errorbars, rangebars and other plot types that have two different orientations work correctly now. Axis labels switch accordingly when the orientation is changed.\nPlotting functions whose positional arguments don't correspond to X, Y, Z work correctly now. For example, HLines (1 => Y) or rangebars (1 => X, 2 => Y, 3 => Y).\nIt is possible to add categories beyond those present in the data with the categories keyword within a scale's settings. It is also possible to reorder or otherwise transform the existing categories by passing a function to categories.\nThe supported attributes are not limited anymore to a specific set of names, for example, strokecolor can work the same as color did before, and the two can share a scale via their shared aesthetic type.\nThere can be multiple scales of the same aesthetic now. This allows to have separate legends for different plot types using the same aesthetics. Scale separation works by pairing a variable in mapping with a scale(id_symbol).\nLegend entries can be reordered using the legend = (; order = ...) option in draw. Specific scales can opt out of the legend by passing legend = false in scales.\nLabels can now be anything that Makie supports, primarily Strings, LaTeXStrings or rich text.\nLegend elements now usually reflect all attributes set in their corresponding visual.\nSimple column vectors of data can now be passed directly to mapping without using data first. Additionally, scalar values are accepted as a shortcut for columns with the same repeated value.\nColumns from outside a table source in data can now be passed to mapping by wrapping them in the direct function. Scalar values are accepted as a shortcut for columns with the same repeated value. For example, to create a label for columns x and y from a dataframe passed to data, one could now do mapping(:x, :y, color = direct(\"label\")) without having to create a column full of \"label\" strings first.\nThe numbers at which categorical values are plotted on x and y axis can now be changed via scales(X = (; palette = [1, 2, 4])) or similar.\nContinuous marker size scales can now be shown in the legend. Numerical values are proportional to area and not diameter now, which makes more sense with respect to human perception. The min and max marker size can be set using the sizerange property for the respective scale in scales.","category":"page"},{"location":"changelog/#v0.6.11-2022-08-08","page":"Changelog","title":"v0.6.11 - 2022-08-08","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added paginate for pagination of large facet plots. ","category":"page"},{"location":"changelog/#v0.6.8-2022-06-14","page":"Changelog","title":"v0.6.8 - 2022-06-14","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Added choropleth recipe to supersede geodata for geographical data.","category":"page"},{"location":"changelog/#v0.6.1-2022-01-28","page":"Changelog","title":"v0.6.1 - 2022-01-28","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Support level in linear analysis for confidence interval.\nReplaced tuples and named tuples in Layer and Entry with dictionaries from Dictionaries.jl.\nSplit internal Entry type into ProcessedLayer (to be used for analyses) and Entry (to be used for plotting).","category":"page"},{"location":"changelog/#v0.6.0-2021-10-24","page":"Changelog","title":"v0.6.0 - 2021-10-24","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: Default axis linking behavior has changed: now only axes corresponding to the same variable are linked. For consistency with row/col, layout will hide decorations of linked axes and span axis labels if appropriate.\nCustomizable legend and colorbar position and look.\nCustomizable axis linking behavior.","category":"page"},{"location":"changelog/#v0.5-2021-08-05","page":"Changelog","title":"v0.5 - 2021-08-05","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: Axis(ae) has been replaced by ae.axis.\nBreaking: Legend(fg) has been replaced by legend!(fg) and colorbar!(fg).\nlegend! and colorbar! API allows for custom legend placement.","category":"page"},{"location":"changelog/#v0.4-2021-05-21","page":"Changelog","title":"v0.4 - 2021-05-21","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Breaking: Removed deprecations for style and spec (now only mapping and visual are allowed).\nBreaking: Analyses now require parentheses (i.e. linear() instead of linear).\nBreaking: Rename layout_x and layout_y to col and row.\nBreaking: Rename wts keyword argument to weights.\nBreaking: categorical has been replaced by nonnumeric.","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/statistical analyses/density_plots.jl\"","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/#Density-plots","page":"Density plots","title":"Density plots","text":"","category":"section"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"using AlgebraOfGraphics, CairoMakie\nusing AlgebraOfGraphics: density\n\ndf = (x=randn(1000), c=rand([\"a\", \"b\"], 1000))\nplt = data(df) * mapping(:x, color=:c) * density(bandwidth=0.5)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"df = (x=randn(1000), c=rand([\"a\", \"b\"], 1000))\nplt = data(df) * mapping(:x, color=:c) * density(bandwidth=0.5) * visual(orientation=:vertical)\n\"Not yet supported\" # hide","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"\"Not yet supported\"","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"","category":"page"},{"location":"gallery/gallery/statistical analyses/density_plots/","page":"Density plots","title":"Density plots","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"API/types/#Types","page":"Types","title":"Types","text":"","category":"section"},{"location":"API/types/","page":"Types","title":"Types","text":"AlgebraOfGraphics.AbstractDrawable\nAlgebraOfGraphics.AbstractAlgebraic\nAlgebraOfGraphics.Layer\nAlgebraOfGraphics.Layers\nAlgebraOfGraphics.zerolayer\nAlgebraOfGraphics.ProcessedLayer\nAlgebraOfGraphics.ProcessedLayers\nAlgebraOfGraphics.Entry\nAlgebraOfGraphics.AxisEntries","category":"page"},{"location":"API/types/#AlgebraOfGraphics.AbstractDrawable","page":"Types","title":"AlgebraOfGraphics.AbstractDrawable","text":"AbstractDrawable\n\nAbstract type encoding objects that can be drawn via AlgebraOfGraphics.draw.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.AbstractAlgebraic","page":"Types","title":"AlgebraOfGraphics.AbstractAlgebraic","text":"AbstractAlgebraic <: AbstractDrawable\n\nAbstract type encoding objects that can be combined together using + and *.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.Layer","page":"Types","title":"AlgebraOfGraphics.Layer","text":"Layer(transformation, data, positional::AbstractVector, named::AbstractDictionary)\n\nAlgebraic object encoding a single layer of a visualization. It is composed of a dataset, positional and named arguments, as well as a transformation to be applied to those. Layer objects can be multiplied, yielding a novel Layer object, or added, yielding a AlgebraOfGraphics.Layers object.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.Layers","page":"Types","title":"AlgebraOfGraphics.Layers","text":"Layers(layers::Vector{Layer})\n\nAlgebraic object encoding a list of AlgebraOfGraphics.Layer objects. Layers objects can be added or multiplied, yielding a novel Layers object.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.zerolayer","page":"Types","title":"AlgebraOfGraphics.zerolayer","text":"zerolayer()\n\nReturns a Layers with an empty layer list which can act as a zero in the layer algebra.\n\nlayer * zerolayer() ~ zerolayer()\nlayer + zerolayer() ~ layer\n\n\n\n\n\n","category":"function"},{"location":"API/types/#AlgebraOfGraphics.ProcessedLayer","page":"Types","title":"AlgebraOfGraphics.ProcessedLayer","text":"ProcessedLayer(l::Layer)\n\nProcess a Layer and return the resulting ProcessedLayer.\n\nNote that this method should not be used anymore as processing a Layer can now potentially return multiple ProcessedLayer objects. Therefore, you should use the plural form ProcessedLayers(layer).\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.ProcessedLayers","page":"Types","title":"AlgebraOfGraphics.ProcessedLayers","text":"ProcessedLayers(layers::Vector{ProcessedLayer})\n\nObject encoding a list of AlgebraOfGraphics.ProcessedLayer objects. ProcessedLayers objects are the output of the processing pipeline and can be drawn without further processing.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.Entry","page":"Types","title":"AlgebraOfGraphics.Entry","text":"Entry(plottype::PlotType, positional::Arguments, named::NamedArguments)\n\nDefine plottype as well as positional and named arguments for a single plot.\n\n\n\n\n\n","category":"type"},{"location":"API/types/#AlgebraOfGraphics.AxisEntries","page":"Types","title":"AlgebraOfGraphics.AxisEntries","text":"AxisEntries(axis::Union{Axis, Nothing}, entries::Vector{Entry}, categoricalscales, continuousscales)\n\nDefine all ingredients to make plots on an axis. Each categorical scale should be a CategoricalScale, and each continuous scale should be a ContinuousScale.\n\n\n\n\n\n","category":"type"},{"location":"API/recipes/#Recipes","page":"Recipes","title":"Recipes","text":"","category":"section"},{"location":"API/recipes/","page":"Recipes","title":"Recipes","text":"choropleth\nlinesfill","category":"page"},{"location":"API/recipes/#AlgebraOfGraphics.choropleth","page":"Recipes","title":"AlgebraOfGraphics.choropleth","text":"choropleth(geometries; transformation, attributes...)\n\nChoropleth map, where regions are defined by geometries. Use transformation to transform coordinates (see Proj.jl for more information).\n\nwarning: Warning\nThe transformation keyword argument is experimental and could be deprecated (even in a non-breaking release) in favor of a different syntax.\n\nAttributes\n\nAvailable attributes and their defaults for Plot{AlgebraOfGraphics.choropleth} are: \n\n alpha 1.0\n clip_planes MakieCore.Automatic()\n color :gray25\n colormap :batlow\n colorrange MakieCore.Automatic()\n colorscale identity\n cycle [:color => :patchcolor]\n depth_shift 0.0f0\n highclip MakieCore.Automatic()\n inspectable true\n inspector_clear MakieCore.Automatic()\n inspector_hover MakieCore.Automatic()\n inspector_label MakieCore.Automatic()\n joinstyle :miter\n linecap :butt\n linestyle \"nothing\"\n lowclip MakieCore.Automatic()\n miter_limit 1.0471975511965976\n nan_color :transparent\n overdraw false\n shading NoShading\n space :data\n ssao false\n stroke_depth_shift -1.0f-5\n strokecolor :black\n strokecolormap :batlow\n strokewidth 0\n transparency false\n visible true\n\n\n\n\n\n","category":"function"},{"location":"API/recipes/#AlgebraOfGraphics.linesfill","page":"Recipes","title":"AlgebraOfGraphics.linesfill","text":"linesfill(xs, ys; lower, upper, attributes...)\n\nLine plot with a shaded area between lower and upper. If lower and upper are not given, shaded area is between 0 and ys.\n\nAttributes\n\nAvailable attributes and their defaults for Plot{AlgebraOfGraphics.linesfill} are: \n\n color :gray25\n colormap :batlow\n colorrange MakieCore.Automatic()\n fillalpha 0.15\n linestyle \"nothing\"\n linewidth 1.5\n lower MakieCore.Automatic()\n upper MakieCore.Automatic()\n\n\n\n\n\n","category":"function"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/data manipulations/no_data.jl\"","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/#Using-mapping-without-tabular-data","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"Sometimes it's easier to specify columnar data directly within mapping rather than first storing it in some tabular data source and accessing it by column name. Note that you can also use scalar values which will be treated like columns with repeated elements. In the example below, we specify color = \"marker\" instead of the more verbose color = fill(\"marker\", 3).","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"using AlgebraOfGraphics, CairoMakie\n\nx = 1:100\ny = sin.(range(0, 2pi, length = 100))\n\nplt = mapping(x, y, color = repeat([\"high\", \"low\"], inner = 50)) *\n visual(Lines) +\n mapping([20, 28, 51], color = \"marker\" => scale(:secondary)) *\n visual(VLines, linestyle = :dash)\n\nfg = draw(plt, scales(secondary = (; palette = [:gray80])))","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"","category":"page"},{"location":"gallery/gallery/data manipulations/no_data/","page":"Using mapping without tabular data","title":"Using mapping without tabular data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"layers/data/#Data","page":"Data","title":"Data","text":"","category":"section"},{"location":"layers/data/","page":"Data","title":"Data","text":"data","category":"page"},{"location":"layers/data/#AlgebraOfGraphics.data","page":"Data","title":"AlgebraOfGraphics.data","text":"data(table)\n\nCreate a Layer with its data field set to a table-like object.\n\nThere are no type restrictions on this object, as long as it respects the Tables interface. In particular, any one of these formats should work out of the box.\n\nTo create a fully specified layer, the layer created with data needs to be multiplied with the output of mapping.\n\nspec = data(...) * mapping(...)\n\n\n\n\n\n","category":"function"},{"location":"layers/data/","page":"Data","title":"Data","text":"using AlgebraOfGraphics\ndf = (a = rand(10), b = rand(10))\ndata(df)","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/applications/time_series.jl\"","category":"page"},{"location":"gallery/gallery/applications/time_series/#Time-series","page":"Time series","title":"Time series","text":"","category":"section"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"using AlgebraOfGraphics, CairoMakie\nusing Dates\n\nx = today() - Year(1) : Day(1) : today()\ny = cumsum(randn(length(x)))\nz = cumsum(randn(length(x)))\ndf = (; x, y, z)\nlabels = [\"series 1\", \"series 2\", \"series 3\", \"series 4\", \"series 5\"]\nplt = data(df) *\n mapping(:x, [:y, :z] .=> \"value\", color=dims(1) => renamer(labels) => \"series \") *\n visual(Lines)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"(Image: )","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"x = now() - Hour(6) : Minute(1) : now()\ny = cumsum(randn(length(x)))\nz = cumsum(randn(length(x)))\ndf = (; x, y, z)\nplt = data(df) *\n mapping(:x, [:y, :z] .=> \"value\", color=dims(1) => renamer(labels) =>\"series \") *\n visual(Lines)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"(Image: )","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"dates = Date(2022, 1, 1):Day(1):Date(2022, 1, 31)\ntrend = cumsum(randn(31))\ndf = map(1:2000) do _\n idx = rand(1:31)\n date = dates[idx]\n observation = trend[idx] + 2 * rand()\n return (; date, observation)\nend\nplt = data(df) * mapping(:date, :observation) * visual(BoxPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"(Image: )","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"","category":"page"},{"location":"gallery/gallery/applications/time_series/","page":"Time series","title":"Time series","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"layers/draw/#Drawing-Layers","page":"Drawing Layers","title":"Drawing Layers","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"A AlgebraOfGraphics.Layer or AlgebraOfGraphics.Layers object can be plotted using the functions draw or draw!.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Whereas draw automatically adds colorbar and legend, draw! does not, as it would be hard to infer a good default placement that works in all scenarios.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Colorbar and legend, should they be necessary, can be added separately with the colorbar! and legend! helper functions. See also Nested layouts for a complex example.","category":"page"},{"location":"layers/draw/#Scale-options","page":"Drawing Layers","title":"Scale options","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"All properties that decide how scales are visualized can be modified by passing scale options (using the scales function) as the second argument of draw . The properties that are accepted differ depending on the scale aesthetic type (for example Color, Marker, LineStyle) and whether the scale is categorical or continuous.","category":"page"},{"location":"layers/draw/#Shared-categorical-scale-options","page":"Drawing Layers","title":"Shared categorical scale options","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The palette and categories options are implemented across all categorical scale types.","category":"page"},{"location":"layers/draw/#palette","page":"Drawing Layers","title":"palette","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The palette decides which attribute values are passed to Makie's plotting functions for each categorical value in the scale.","category":"page"},{"location":"layers/draw/#Color","page":"Drawing Layers","title":"Color","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"A Symbol is converted to a colormap with Makie.to_colormap. ","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = 'A':'J')) *\n mapping(:x, :y, color = :z) *\n visual(BarPlot)\ndraw(spec, scales(Color = (; palette = :tab10)))","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"It's also possible to directly specify a vector of colors, each of which Makie.to_color can handle:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\nusing CairoMakie.Colors: RGB, RGBA, Gray, HSV\n\nspec = data((; x = 1:10, y = 1:10, z = 'A':'J')) *\n mapping(:x, :y, color = :z) *\n visual(BarPlot)\ndraw(spec, scales(Color = (; palette = [:red, :green, :blue, RGB(1, 0, 1), RGB(1, 1, 0), \"#abcff0\", \"#c88cbccc\", HSV(0.9, 0.3, 0.7), RGBA(0.7, 0.9, 0.6, 0.5), Gray(0.5)])))","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"If you want to use a continuous colormap for categorical data, you can use the from_continuous helper function. It automatically takes care that the continuous colormap is sampled evenly from start to end depending on the number of categories. Any colormap that Makie understands can be passed, including named colormaps such as :viridis.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"This example shows the difference in behavior when the two-element colormap [:red, :blue] is used with or without from_continuous:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = 'A':'J')) *\n mapping(:x, :y, color = :z) *\n visual(BarPlot)\n\nf = Figure()\nfg1 = draw!(f[1, 1], spec, scales(Color = (; palette = [:red, :blue])))\nlegend!(f[1, 2], fg1)\nfg2 = draw!(f[1, 3], spec, scales(Color = (; palette = from_continuous([:red, :blue]))))\nlegend!(f[1, 4], fg2)\nf","category":"page"},{"location":"layers/draw/#Marker","page":"Drawing Layers","title":"Marker","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"A vector of values that Makie.to_spritemarker can handle.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = 'A':'J')) *\n mapping(:x, :y, marker = :z) *\n visual(Scatter, markersize = 20)\n\ndraw(\n spec,\n scales(\n Marker = (; palette = [:rect, :circle, :utriangle, :dtriangle, :diamond, :hline, :vline, :star5, :star6, :hexagon])\n )\n)","category":"page"},{"location":"layers/draw/#LineStyle","page":"Drawing Layers","title":"LineStyle","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"A vector of values that Makie.to_linestyle can handle.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = repeat('A':'E', inner = 2))) *\n mapping(:x, :y, linestyle = :z) *\n visual(Lines, linewidth = 2)\n\ndraw(spec, scales(\n LineStyle = (; palette = [:solid, :dash, :dot, (:dot, :loose), Linestyle([0, 1, 2, 3, 4, 8])])\n))","category":"page"},{"location":"layers/draw/#X-and-Y","page":"Drawing Layers","title":"X & Y","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The \"palette\" values for X and Y axes are by default simply the numbers from 1 to N, the number of categories. In some circumstances, it might be useful to change these values, for example to visualize that one category is different than others. The palette values are normally assigned category-by-category in the sorted order, or in the order provided manually through the categories keyword. However, if you pass a vector of values, you can always use the category => value pair option to assign a specific category directly to a value, while the others cycle. Here, we do this with \"Unknown\" as it would otherwise be sorted before \"X\".","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (; group = [\"A\", \"B\", \"C\", \"X\", \"Y\", \"Unknown\"], count = [45, 10, 20, 32, 54, 72])\n\nspec = data(df) * mapping(:group, :count) * visual(BarPlot)\n\ndraw(spec, scales(X = (; palette = [1, 2, 3, 5, 6, \"Unknown\" => 8])))","category":"page"},{"location":"layers/draw/#Layout","page":"Drawing Layers","title":"Layout","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Normally, with the Layout aesthetic, rows wrap automatically such that an approximately square distribution of facets is attained. You can overwrite these values, however, to place axes at manually chosen positions:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (;\n group = repeat([\"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\"], inner = 20),\n x = randn(160),\n y = randn(160)\n)\n\nspec = data(df) * mapping(:x, :y, layout = :group) * visual(Scatter)\n\nclockwise = [(1, 1), (1, 2), (1, 3), (2, 3), (3, 3), (3, 2), (3, 1), (2, 1)]\n\ndraw(spec, scales(Layout = (; palette = clockwise)))","category":"page"},{"location":"layers/draw/#categories","page":"Drawing Layers","title":"categories","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The categories keyword can be used to reorder, label and even add categorical values.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Some reordering and renaming can be done using the sorter and renamer helper functions applied directly to columns in mapping. However, this works less well when several data sources are combined where not all categories appear in each column. Also, no categories can be added this way, which is something that can be useful if the existence of categories should be shown even though there is no data for them.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"New labels can be assigned using the value => label pair syntax.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; group = [\"A\", \"C\", \"D\"], value = [1, 3, 4])) *\n mapping(:group, :value) * visual(BarPlot)\n\nf = Figure()\n\ndraw!(f[1, 1], spec, scales(\n X = (; categories = [\"A\", \"B\", \"C\", \"D\"])\n))\ndraw!(f[1, 2], spec, scales(\n X = (; categories = [\"D\", \"A\", \"C\"])\n))\ndraw!(f[1, 3], spec, scales(\n X = (; categories = [\"A\" => \"a\", \"C\" => \"c\", \"D\" => \"d\"])\n))\n\nf","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"You can also pass a Function to categories which should take the vector of category values and return a new vector of categories or category/label pairs.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"For example, you could add summary statistics to the facet layout titles this way, by grabbing them from a dictionary computed separately.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nsummary_stats = Dict(\"A\" => 1.32, \"B\" => 4.19, \"C\" => 0.04)\n\ndf = (;\n x = randn(90),\n y = randn(90) .+ repeat([0, 5, 10], inner = 30),\n group = repeat([\"A\", \"B\", \"C\"], inner = 30)\n)\n\nspec = data(df) * mapping(:x, :y, col = :group) * visual(Scatter)\n\ndraw(spec, scales(Col = (;\n categories = cats -> [\n cat => rich(\"$cat\\n\", rich(\"λ = $(summary_stats[cat])\", font = :italic))\n for cat in reverse(cats)\n ]\n)))","category":"page"},{"location":"layers/draw/#Special-categorical-scale-options","page":"Drawing Layers","title":"Special categorical scale options","text":"","category":"section"},{"location":"layers/draw/#Row,-Col-and-Layout","page":"Drawing Layers","title":"Row, Col & Layout","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"All three facetting scales have the option show_labels which is true by default and can be set to false to hide the facet labels.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"This example shows the behavior for Col only:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((;\n x = 1:16,\n y = 17:32,\n group1 = repeat([\"A\", \"B\"], inner = 8),\n group2 = repeat([\"C\", \"D\"], 8))\n) * mapping(:x, :y, row = :group1, col = :group2) * visual(Scatter)\n\ndraw(spec, scales(Col = (; show_labels = false)))","category":"page"},{"location":"layers/draw/#Continuous-scale-options","page":"Drawing Layers","title":"Continuous scale options","text":"","category":"section"},{"location":"layers/draw/#Color-2","page":"Drawing Layers","title":"Color","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Continuous color scales can be modified using the familiar Makie attributes colormap, colorrange, highclip, lowclip and nan_color. By default, colorrange is set to the extrema of the encountered values, so no clipping occurs.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = [1:4; NaN; 6:10])) *\n mapping(:x, :y, color = :z) *\n visual(Scatter, markersize = 20)\n\ndraw(spec, scales(\n Color = (;\n colormap = :plasma,\n nan_color = :cyan,\n lowclip = :lime,\n highclip = :red,\n colorrange = (2, 9)\n )\n))","category":"page"},{"location":"layers/draw/#MarkerSize","page":"Drawing Layers","title":"MarkerSize","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The range of marker sizes can be set with the sizerange attribute. Marker sizes are computed such that their area, and not markersize itself, grows linearly with the scale values. ","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = data((; x = 1:10, y = 1:10, z = 10:10:100)) *\n mapping(:x, :y, markersize = :z) *\n visual(Scatter)\n\nf = Figure()\n\ngrid = draw!(f[1, 1], spec, scales(\n MarkerSize = (;\n sizerange = (5, 15)\n )\n))\nlegend!(f[1, 2], grid)\n\ngrid2 = draw!(f[2, 1], spec, scales(\n MarkerSize = (;\n sizerange = (5, 30)\n )\n))\nlegend!(f[2, 2], grid2)\n\nf","category":"page"},{"location":"layers/draw/#Legend-options","page":"Drawing Layers","title":"Legend options","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"The legend keyword forwards most attributes to Makie's Legend function. The exceptions are listed here.","category":"page"},{"location":"layers/draw/#order","page":"Drawing Layers","title":"order","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"By default, the legend order depends on the order in which layers and mappings have been defined, as well as whether scales are categorical or continuous.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf = (;\n x = 1:12,\n y = 1:12,\n z = 1:12,\n group1 = repeat([\"A\", \"B\", \"C\"], inner = 4),\n group2 = repeat([\"X\", \"Y\"], 6),\n)\n\nspec = data(df) *\n mapping(:x, :y, markersize = :z, color = :group1, marker = :group2) *\n visual(Scatter)\n\ndraw(spec)","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"You can reorder the legend with the order keyword. This expects a vector with either Symbols or Vector{Symbol}s as elements, where each Symbol is the identifier for a scale that's represented in the legend.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Plain Symbols can be used for simple reordering:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"draw(spec; legend = (; order = [:MarkerSize, :Color, :Marker]))","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"Symbols that are grouped into Vectors indicate that their groups should be merged together. For example, consider this plot that features two color scales, but one for a scatter plot and one for a line plot.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\ndf_a = (; x = 1:9, y = [1, 2, 3, 5, 6, 7, 9, 10, 11], group = repeat([\"A\", \"B\", \"C\"], inner = 3))\n\nspec1 = data(df_a) * mapping(:x, :y, strokecolor = :group) * visual(Scatter, color = :transparent, strokewidth = 3, markersize = 15)\n\ndf_b = (; y = [4, 8], threshold = [\"first\", \"second\"])\n\nspec2_custom_scale = data(df_b) * mapping(:y, color = :threshold => scale(:color2)) * visual(HLines)\n\ndraw(spec1 + spec2_custom_scale)","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"You can group the two scales together using order. The titles are dropped.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"draw(spec1 + spec2_custom_scale; legend = (; order = [[:Color, :color2]]))","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"If you want to add a title to a merged group, you can add it with the group => title pair syntax:","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"draw(spec1 + spec2_custom_scale; legend = (; order = [[:Color, :color2] => \"Title\"]))","category":"page"},{"location":"layers/draw/#Figure-options","page":"Drawing Layers","title":"Figure options","text":"","category":"section"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"AlgebraOfGraphics can add a title, subtitle and footnotes to a figure automatically. Settings for these must be passed to the figure keyword. Check the draw function for a complete list.","category":"page"},{"location":"layers/draw/","page":"Drawing Layers","title":"Drawing Layers","text":"using AlgebraOfGraphics\nusing CairoMakie\n\nspec = pregrouped(\n fill(1:5, 6),\n fill(11:15, 6),\n [reshape(sin.(1:25), 5, 5) .+ i for i in 1:6],\n layout = 1:6 => nonnumeric) * visual(Heatmap)\n\ndraw(\n spec;\n figure = (;\n title = \"Numbers in square configuration\",\n subtitle = \"Arbitrary data exhibits sinusoidal properties\",\n footnotes = [\n rich(superscript(\"1\"), \"First footnote\"),\n rich(superscript(\"2\"), \"Second \", rich(\"footnote\", color = :red)),\n ],\n ),\n axis = (; width = 100, height = 100)\n)","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = AlgebraOfGraphics","category":"page"},{"location":"#Introduction","page":"Home","title":"Introduction","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"AlgebraOfGraphics defines a language for data visualization. It is based on a few simple building blocks that can be combined using + and *.","category":"page"},{"location":"","page":"Home","title":"Home","text":"This package can be installed typing","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> import Pkg; Pkg.add(\"AlgebraOfGraphics\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"in the Julia REPL.","category":"page"},{"location":"","page":"Home","title":"Home","text":"See the Tutorial to get started.","category":"page"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/legend_merging.jl\"","category":"page"},{"location":"gallery/gallery/scales/legend_merging/#Legend-merging","page":"Legend merging","title":"Legend merging","text":"","category":"section"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"using AlgebraOfGraphics, CairoMakie\n\nN = 40\n\nx = [1:N; 1:N]\ny = [cumsum(randn(N)); cumsum(randn(N))]\ngrp = [fill(\"a\", N); fill(\"b\", N)]\n\ndf = (; x, y, grp)\n\nlayers = visual(Lines) + visual(Scatter) * mapping(marker = :grp)\nplt = data(df) * layers * mapping(:x, :y, color = :grp)\n\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"","category":"page"},{"location":"gallery/gallery/scales/legend_merging/","page":"Legend merging","title":"Legend merging","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/statistical analyses/regression_plots.jl\"","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/#Regression-plots","page":"Regression plots","title":"Regression plots","text":"","category":"section"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"using AlgebraOfGraphics, CairoMakie\n\nx = rand(100)\ny = @. randn() + x\ndf = (; x, y)\nxy = data(df) * mapping(:x, :y)\nlayers = linear() + visual(Scatter)\ndraw(layers * xy)","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"x = rand(100)\ny = @. randn() + 5 * x ^ 2\ndf = (; x, y)\nxy = data(df) * mapping(:x, :y)\nlayers = smooth() + visual(Scatter)\nfg = draw(layers * xy)","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"","category":"page"},{"location":"gallery/gallery/statistical analyses/regression_plots/","page":"Regression plots","title":"Regression plots","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/continuous_scales.jl\"","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/#Continuous-scales","page":"Continuous scales","title":"Continuous scales","text":"","category":"section"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"using AlgebraOfGraphics, CairoMakie\n\nx = 1:100\ny = @. sqrt(x) + 20x + 100\ndf = (; x, y)\nplt = data(df) *\n mapping(\n :x,\n :y => log => \"√x + 20x + 100 (log scale)\",\n ) * visual(Lines)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"x = 1:100\ny = @. sqrt(x) + 20x + 100\ndf = (; x, y)\nplt = data(df) *\n mapping(\n :x,\n :y => \"√x + 20x + 100 (log scale)\",\n ) * visual(Lines)\ndraw(plt, axis=(yscale=log,))","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"x = 0:100\ny = @. 0.01 + x/1000\ndf = (; x, y)\nplt = data(df) *\n mapping(\n :x,\n :y => \"y\",\n ) * visual(Lines)\nfg = draw(plt, axis=(yscale=log,))","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"","category":"page"},{"location":"gallery/gallery/scales/continuous_scales/","page":"Continuous scales","title":"Continuous scales","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"API/functions/#Functions","page":"Functions","title":"Functions","text":"","category":"section"},{"location":"API/functions/#Drawing-functions","page":"Functions","title":"Drawing functions","text":"","category":"section"},{"location":"API/functions/","page":"Functions","title":"Functions","text":"draw\ndraw!\ncolorbar!\nlegend!\npaginate\nscales","category":"page"},{"location":"API/functions/#AlgebraOfGraphics.draw","page":"Functions","title":"AlgebraOfGraphics.draw","text":"draw(d, scales::Scales = scales(); [axis, figure, facet, legend, colorbar])\n\nDraw a AlgebraOfGraphics.AbstractDrawable object d. In practice, d will often be a AlgebraOfGraphics.Layer or AlgebraOfGraphics.Layers. Scale options can be passed as an optional second argument. The output can be customized by passing named tuples or dictionaries with settings via the axis, figure, facet, legend or colorbar keywords. Legend and colorbar are drawn automatically unless show = false is passed to the keyword arguments of either legend or colorbar.\n\nFor finer control, use draw!, legend!, and colorbar! independently.\n\nFigure options\n\nAlgebraOfGraphics accepts the following special keywords under the figure keyword, the remaining attributes are forwarded to Makie's Figure constructor. The title, subtitle and footnotes arguments accept objects of any kind that Makie's Label or text function can handle, such as rich text.\n\n- `title`\n- `subtitle`\n- `titlesize::Union{Nothing,Float64}`\n- `subtitlesize::Union{Nothing,Float64}`\n- `titlealign::Union{Nothing,Symbol}`\n- `titlecolor`\n- `subtitlecolor`\n- `titlefont`\n- `subtitlefont`\n- `titlelineheight`\n- `subtitlelineheight`\n- `footnotes::Union{Nothing,Vector{Any}}`\n- `footnotesize::Union{Nothing,Float64}`\n- `footnotefont`\n- `footnotecolor`\n- `footnotealign`\n- `footnotelineheight`\n\n\n\n\n\ndraw(p::Pagination; kws...)\n\nDraw each element of Pagination p and return a Vector{FigureGrid}. Keywords kws are passed to the underlying draw calls.\n\n\n\n\n\ndraw(p::Pagination, i::Int; kws...)\n\nDraw the ith element of Pagination p and return a FigureGrid. Keywords kws are passed to the underlying draw call.\n\nYou can retrieve the number of elements using length(p).\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.draw!","page":"Functions","title":"AlgebraOfGraphics.draw!","text":"draw!(fig, d::AbstractDrawable, scales::Scales = scales(); [axis, facet])\n\nDraw a AlgebraOfGraphics.AbstractDrawable object d on fig. In practice, d will often be a AlgebraOfGraphics.Layer or AlgebraOfGraphics.Layers. fig can be a figure, a position in a layout, or an axis if d has no facet specification. The output can be customized by passing named tuples or dictionaries with settings via the axis or facet keywords.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.colorbar!","page":"Functions","title":"AlgebraOfGraphics.colorbar!","text":"colorbar!(figpos, grid; kwargs...)\n\nCompute colorbar for grid (which should be the output of draw!) and draw it in position figpos. Attributes allowed in kwargs are the same as MakieLayout.Colorbar.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.legend!","page":"Functions","title":"AlgebraOfGraphics.legend!","text":"legend!(figpos, grid; order = nothing, kwargs...)\n\nCompute legend for grid (which should be the output of draw!) and draw it in position figpos. All kwargs are forwarded to Makie's Legend constructor.\n\nThe order of scales represented in the legend can be changed with the order keyword. By default, legend sections are ordered the same as they appear in the plot specification. Assuming three scales Color, MarkerSize and custom exist in a spec, you can pass a vector to reorder them like [:MarkerSize, :custom, :Color], or merge multiple entries together with a nested vector like [[:MarkerSize, :custom], :Color], or give merged sections a title with the pair syntax [[:MarkerSize, :custom] => \"Merged group\", :Color].\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.paginate","page":"Functions","title":"AlgebraOfGraphics.paginate","text":"paginate(l, sc = scales(); layout=nothing, row=nothing, col=nothing)\n\nPaginate l, the Layer or Layers object created by an AlgebraOfGraphics spec, to create a Pagination object.\n\ninfo: Info\nThe pages are created by internally starting with one big facet plot first which includes all the input data, and then splitting it into pages. All scales are fit to the full data, not just the data that is visible on a given page, so a color legend, for example, will show all the categories and not just the ones that happen to be visible on the current page. This behavior changed with version 0.9 - before, each page had separately fit scales. The old behavior had the drawback that palettes were not guaranteed to be consistent across pages, for example, the same category could have different colors on two separate pages.\n\nThe Pagination object can be passed to draw which will return a Vector{FigureGrid} rather than a single figure.\n\nThe keywords that limit the number of subplots on each page are the same that are used to specify facets in mapping:\n\nlayout: Maximum number of subplots in a wrapped linear layout.\nrow: Maximum number of rows in a 2D layout.\ncol: Maximum number of columns in a 2D layout.\n\nExample\n\nd = data((\n x = rand(1000),\n y = rand(1000),\n group1 = rand(string.('a':'i'), 1000),\n group2 = rand(string.('j':'r'), 1000),\n))\n\nlayer_1 = d * mapping(:x, :y, layout = :group1) * visual(Scatter)\npaginated_1 = paginate(layer_1, layout = 4)\nfiguregrids = draw(paginated_1)\n\nlayer_2 = d * mapping(:x, :y, row = :group1, col = :group2) * visual(Scatter)\npaginated_2 = paginate(layer_2, row = 4, col = 3)\nfiguregrid = draw(paginated_2, 1) # draw only the first grid\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.scales","page":"Functions","title":"AlgebraOfGraphics.scales","text":"scales(; kwargs...)\n\nCreate a Scales object containing properties for aesthetic scales that can be passed to draw and draw!. Each keyword should be the name of a scale in the spec that is being drawn. That can either be a default one like Color, Marker or LineStyle, or a custom scale name defined in a mapping using the scale function.\n\nThe values attached to the keywords must be dict-like, with Symbols as keys (such as NamedTuples).\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#Mapping-helpers","page":"Functions","title":"Mapping helpers","text":"","category":"section"},{"location":"API/functions/","page":"Functions","title":"Functions","text":"pregrouped\ndirect\nrenamer\nsorter\nnonnumeric\nverbatim\nscale\npresorted","category":"page"},{"location":"API/functions/#AlgebraOfGraphics.pregrouped","page":"Functions","title":"AlgebraOfGraphics.pregrouped","text":"pregrouped(positional...; named...)\n\nEquivalent to data(Pregrouped()) * mapping(positional...; named...). Refer to mapping for more information.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.direct","page":"Functions","title":"AlgebraOfGraphics.direct","text":"direct(x)\n\nReturn DirectData(x) which marks x for direct use in a mapping that's used with a table-like data source. As a result, x will be used directly as data, without lookup in the table. If x is not an AbstractArray, it will be expanded like fill(x, n) where n is the number of rows in the data source.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.renamer","page":"Functions","title":"AlgebraOfGraphics.renamer","text":"renamer(arr::Union{AbstractArray, Tuple})\n\nUtility to rename a categorical variable, as in renamer([value1 => label1, value2 => label2]). The keys of all pairs should be all the unique values of the categorical variable and the values should be the corresponding labels. The order of arr is respected in the legend.\n\nExamples\n\njulia> r = renamer([\"class 1\" => \"Class One\", \"class 2\" => \"Class Two\"])\nAlgebraOfGraphics.Renamer{Vector{String}, Vector{String}}([\"class 1\", \"class 2\"], [\"Class One\", \"Class Two\"])\n\njulia> println(r(\"class 1\"))\nClass One\n\nAlternatively, a sequence of pair arguments may be passed.\n\njulia> r = renamer(\"class 1\" => \"Class One\", \"class 2\" => \"Class Two\")\nAlgebraOfGraphics.Renamer{Tuple{String, String}, Tuple{String, String}}((\"class 1\", \"class 2\"), (\"Class One\", \"Class Two\"))\n\njulia> println(r(\"class 1\"))\nClass One\n\nIf arr does not contain Pairs, elements of arr are assumed to be labels, and the unique values of the categorical variable are taken to be the indices of the array. This is particularly useful for dims mappings.\n\nExamples\n\njulia> r = renamer([\"Class One\", \"Class Two\"])\nAlgebraOfGraphics.Renamer{Nothing, Vector{String}}(nothing, [\"Class One\", \"Class Two\"])\n\njulia> println(r(2))\nClass Two\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.sorter","page":"Functions","title":"AlgebraOfGraphics.sorter","text":"sorter(ks)\n\nUtility to reorder a categorical variable, as in sorter([\"low\", \"medium\", \"high\"]). A vararg method sorter(\"low\", \"medium\", \"high\") is also supported. ks should include all the unique values of the categorical variable. The order of ks is respected in the legend.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.nonnumeric","page":"Functions","title":"AlgebraOfGraphics.nonnumeric","text":"nonnumeric(x)\n\nTransform x into a non numeric type that is printed and sorted in the same way.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.verbatim","page":"Functions","title":"AlgebraOfGraphics.verbatim","text":"verbatim(x)\n\nSignal that x should not be rescaled, but used in the plot as is.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.scale","page":"Functions","title":"AlgebraOfGraphics.scale","text":"scale(id::Symbol)\n\nCreate a ScaleID object that can be used in a mapping to assign a custom id to the mapped variable. This variable will then not be merged into the default scale for its aesthetic type, but instead be handled separately, leading to a separate legend entry.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.presorted","page":"Functions","title":"AlgebraOfGraphics.presorted","text":"presorted(x)\n\nUse within a pair expression in mapping to signal that a categorical column from the data source should be used in the original order and not automatically sorted.\n\nExample:\n\n# normally, categories would be sorted a, b, c but with `presorted`\n# they stay in the order b, c, a\n\ndata((; some_column = [\"b\", \"c\", \"a\"])) * mapping(:some_column => presorted)\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#Theming","page":"Functions","title":"Theming","text":"","category":"section"},{"location":"API/functions/","page":"Functions","title":"Functions","text":"set_aog_theme!\nAlgebraOfGraphics.aog_theme\nfrom_continuous","category":"page"},{"location":"API/functions/#AlgebraOfGraphics.set_aog_theme!","page":"Functions","title":"AlgebraOfGraphics.set_aog_theme!","text":"set_aog_theme!(; kwargs...)\n\nSet the current theme to a predefined and opinionated theme, as defined by the unexported internal function AlgebraOfGraphics.aog_theme.\n\nTo tweak the predefined theme, use the function Makie.update_theme!. See the example below on how to change, e.g., default fontsize, title, and markersize.\n\nFor more information about setting themes, see the Theming section of the Makie.jl docs.\n\nExamples\n\njulia> using CairoMakie, AlgebraOfGraphics\n\njulia> set_aog_theme!() # Sets a prefedined theme\n\njulia> update_theme!( # Tweaks the current theme\n fontsize=30,\n markersize=40,\n Axis=(title=\"MyDefaultTitle\",)\n )\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.aog_theme","page":"Functions","title":"AlgebraOfGraphics.aog_theme","text":"aog_theme(; fonts=[firasans(\"Medium\"), firasans(\"Light\")])\n\nReturn a NamedTuple of theme settings. Intended for internal use. The provided functionality is exposed to the user by the function set_aog_theme!.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.from_continuous","page":"Functions","title":"AlgebraOfGraphics.from_continuous","text":"from_continuous(x)\n\nMark a colormap as continuous such that AlgebraOfGraphics will sample a categorical palette from start to end in n steps, and not by using the first n colors.\n\nYou could also use cgrad(colormap, n; categorical = true), however, this requires you to specify how many levels there are, which from_continuous detects automatically.\n\nExample:\n\ndraw(scales(Color = (; palette = from_continuous(:viridis))))\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#Ticks-helpers","page":"Functions","title":"Ticks helpers","text":"","category":"section"},{"location":"API/functions/","page":"Functions","title":"Functions","text":"datetimeticks","category":"page"},{"location":"API/functions/#AlgebraOfGraphics.datetimeticks","page":"Functions","title":"AlgebraOfGraphics.datetimeticks","text":"datetimeticks(datetimes::AbstractVector{<:TimeType}, labels::AbstractVector{<:AbstractString})\n\nGenerate ticks matching datetimes to the corresponding labels. The result can be passed to xticks, yticks, or zticks.\n\n\n\n\n\ndatetimeticks(f, datetimes::AbstractVector{<:TimeType})\n\nCompute ticks for the given datetimes using a formatting function f. The result can be passed to xticks, yticks, or zticks.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#Internal-functions","page":"Functions","title":"Internal functions","text":"","category":"section"},{"location":"API/functions/","page":"Functions","title":"Functions","text":"AlgebraOfGraphics.scientific_eltype\nAlgebraOfGraphics.scientific_type\nAlgebraOfGraphics.plottypes_attributes\nAlgebraOfGraphics.compute_attributes","category":"page"},{"location":"API/functions/#AlgebraOfGraphics.scientific_eltype","page":"Functions","title":"AlgebraOfGraphics.scientific_eltype","text":"scientific_eltype(v)\n\nDetermine whether v should be treated as a continuous, geometrical, or categorical array.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.scientific_type","page":"Functions","title":"AlgebraOfGraphics.scientific_type","text":"scientific_type(T::Type)\n\nDetermine whether T represents a continuous, geometrical, or categorical variable.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.plottypes_attributes","page":"Functions","title":"AlgebraOfGraphics.plottypes_attributes","text":"plottypes_attributes(entries)\n\nReturn plottypes and relative attributes, as two vectors of the same length, for the given entries.\n\n\n\n\n\n","category":"function"},{"location":"API/functions/#AlgebraOfGraphics.compute_attributes","page":"Functions","title":"AlgebraOfGraphics.compute_attributes","text":"compute_attributes(pl::ProcessedLayer, categoricalscales, continuousscales_grid, continuousscales)\n\nProcess attributes of a ProcessedLayer. In particular,\n\nremove AlgebraOfGraphics-specific layout attributes,\nopt out of Makie cycling mechanism,\ncustomize behavior of color (implementing alpha transparency),\ncustomize behavior of bar width (default to one unit when not specified),\nset correct colorrange.\n\nReturn computed attributes.\n\n\n\n\n\n","category":"function"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/data manipulations/presorted_data.jl\"","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/#Pre-sorted-data","page":"Pre-sorted data","title":"Pre-sorted data","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"using AlgebraOfGraphics, CairoMakie, DataFrames","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"Sometimes we have datasets that have an inherent order we want to preserve. For example, this dataframe has countries sorted by some_value.","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"countries = [\"Algeria\", \"Bolivia\", \"China\", \"Denmark\", \"Ecuador\", \"France\"]\ngroup = [\"2\", \"3\", \"1\", \"1\", \"3\", \"2\"]\nsome_value = exp.(sin.(1:6))\n\ndf = DataFrame(; countries, group, some_value)\nsort!(df, :some_value)\n\ndf","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"
6×3 DataFrame
Rowcountriesgroupsome_value
StringStringFloat64
1Ecuador30.383305
2Denmark10.469164
3France20.756226
4China11.15156
5Algeria22.31978
6Bolivia32.48258
","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"When we plot this, the categorical variable countries is sorted alphabetically by default:","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"spec = data(df) *\n mapping(:countries, :some_value, color = :group) *\n visual(BarPlot, direction = :x)\ndraw(spec)","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"We don't want this, because we have purposefully sorted the dataframe to visualize which countries have the highest value. To retain the order, we can use the presorted helper.","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"spec = data(df) *\n mapping(:countries => presorted, :some_value, color = :group) *\n visual(BarPlot, direction = :x)\nfg = draw(spec)","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"We can also mark multiple variables as presorted, note how the order in the color legend shifts when we do the same for group:","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"spec = data(df) *\n mapping(:countries => presorted, :some_value, color = :group => presorted) *\n visual(BarPlot, direction = :x)\ndraw(spec)","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"","category":"page"},{"location":"gallery/gallery/data manipulations/presorted_data/","page":"Pre-sorted data","title":"Pre-sorted data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/basic visualizations/lines_and_markers.jl\"","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/#Lines-and-markers","page":"Lines and markers","title":"Lines and markers","text":"","category":"section"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/#A-simple-scatter-plot","page":"Lines and markers","title":"A simple scatter plot","text":"","category":"section"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"using AlgebraOfGraphics, CairoMakie\n\ndf = (x=rand(100), y=rand(100))\nxy = data(df) * mapping(:x, :y)\ndraw(xy)","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/#A-simple-lines-plot","page":"Lines and markers","title":"A simple lines plot","text":"","category":"section"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"x = range(-π, π, length=100)\ny = sin.(x)\ndf = (; x, y)\nxy = data(df) * mapping(:x, :y)\nlayer = visual(Lines)\ndraw(layer * xy)","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/#Lines-and-scatter-combined-plot","page":"Lines and markers","title":"Lines and scatter combined plot","text":"","category":"section"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"x = range(-π, π, length=100)\ny = sin.(x)\ndf = (; x, y)\nxy = data(df) * mapping(:x, :y)\nlayers = visual(Scatter) + visual(Lines)\ndraw(layers * xy)","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"x = range(-π, π, length=100)\ny = sin.(x)\ndf1 = (; x, y)\ndf2 = (x=rand(10), y=rand(10))\nlayers = data(df1) * visual(Lines) + data(df2) * visual(Scatter)\nfg = draw(layers * mapping(:x, :y))","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"(Image: )","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"","category":"page"},{"location":"gallery/gallery/basic visualizations/lines_and_markers/","page":"Lines and markers","title":"Lines and markers","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/statistical analyses/histograms.jl\"","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/#Histograms","page":"Histograms","title":"Histograms","text":"","category":"section"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"using AlgebraOfGraphics, CairoMakie\nusing AlgebraOfGraphics: density\n\ndf = (x=rand(0:99, 1000),)\nplt = data(df) * mapping(:x) * histogram(bins=20)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"df = (x=randn(1000), c=rand([\"a\", \"b\"], 1000))\nplt = data(df) * mapping(:x, color=:c, stack=:c) * histogram(bins=20)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"df = (x=rand(1000), y=randn(1000))\nplt = data(df) * mapping(:x, :y) * histogram(bins=20)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"(Image: )","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"","category":"page"},{"location":"gallery/gallery/statistical analyses/histograms/","page":"Histograms","title":"Histograms","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/split_scales_facet.jl\"","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/#Split-scales-across-facets","page":"Split scales across facets","title":"Split scales across facets","text":"","category":"section"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"Usually, facet layout plots use the same scale for all x and y axes, respectively, of every facet. Sometimes you might want to break with this convention, for example, to show how different categorical and continuous variables interact with each other.","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"AlgebraOfGraphics allows you to use multiple different scale ids for the X and Y aesthetics in a plot, as long as only one scale id for x and y axis, respectively, appears in a given facet.","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"Currently, this scenario requires building the plot in multiple separate layers rather than using wide input data with the dims selector for layout, row or col mappings. You need one layer for each set of scale ids. Multiple facets are allowed to share scale ids, but a single facet may not have multiple scale ids for x or y, respectively.","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"using AlgebraOfGraphics, CairoMakie\n\ndat = data((;\n fruit = rand([\"Apple\", \"Orange\", \"Pear\"], 150),\n taste = randn(150) .* repeat(1:3, inner = 50),\n weight = repeat([\"Heavy\", \"Light\", \"Medium\"], inner = 50),\n cost = randn(150) .+ repeat([10, 20, 30], inner = 50),\n))\n\nfruit = :fruit => \"Fruit\" => scale(:X1)\nweights = :weight => \"Weight\" => scale(:Y1)\ntaste = :taste => \"Taste Score\" => scale(:X2)\ncost = :cost => \"Cost\" => scale(:Y2)\n\nlayer1 = mapping(\n fruit,\n weights,\n col = direct(\"col1\"), # this controls what facet this mapping belongs to\n row = direct(\"row1\")\n) * frequency()\n\nlayer2 = mapping(\n fruit,\n cost,\n col = direct(\"col1\"),\n row = direct(\"row2\")\n) * visual(Violin)\n\nlayer3 = mapping(\n weights, # note X and Y are flipped here for a horizontal violin\n taste,\n col = direct(\"col2\"),\n row = direct(\"row1\")\n) * visual(Violin, orientation = :horizontal)\n\nlayer4 = mapping(\n taste,\n cost,\n col = direct(\"col2\"),\n row = direct(\"row2\")\n) * visual(Scatter)\n\nspec = dat * (layer1 + layer2 + layer3 + layer4)\n\nfg = draw(spec, scales(Row = (; show_labels = false), Col = (; show_labels = false)))","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"","category":"page"},{"location":"gallery/gallery/scales/split_scales_facet/","page":"Split scales across facets","title":"Split scales across facets","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/data manipulations/wide_data.jl\"","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/#Wide-data","page":"Wide data","title":"Wide data","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"using AlgebraOfGraphics, CairoMakie\nusing AlgebraOfGraphics: density\n\ndf = (a=randn(100), b=randn(100), c=randn(100))\nlabels = [\"Trace 1\", \"Trace 2\", \"Trace 3\"]\nplt = data(df) *\n density() *\n mapping([:a, :b, :c] .=> \"some label\") *\n mapping(color=dims(1) => renamer(labels))\ndraw(plt)","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"df = (a=rand(100), b=rand(100), c=rand(100), d=rand(100))\nlabels = [\"Trace One\", \"Trace Two\", \"Trace Three\"]\nlayers = linear() + visual(Scatter)\nplt = data(df) * layers * mapping(1, 2:4 .=> \"value\", color=dims(1) => renamer(labels))\ndraw(plt)","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"The wide format is combined with broadcast semantics.","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/#Axes-are-linked-when-they-correspond-to-the-same-variable","page":"Wide data","title":"Axes are linked when they correspond to the same variable","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"df = (\n sepal_length = 1 .+ rand(100),\n sepal_width = 2 .+ rand(100),\n petal_length = 3 .+ rand(100),\n petal_width = 4 .+ rand(100)\n)\nxvars = [\"sepal_length\", \"sepal_width\"]\nyvars = [\"petal_length\" \"petal_width\"]\nlayers = linear() + visual(Scatter)\nplt = data(df) * layers * mapping(xvars, yvars, col=dims(1), row=dims(2))\ndraw(plt)","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/#Axes-can-be-fully-linked-or-fully-unlinked","page":"Wide data","title":"Axes can be fully linked or fully unlinked","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"draw(plt, facet = (; linkxaxes = :all, linkyaxes = :all))","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"fg = draw(plt, facet = (; linkxaxes = :none, linkyaxes = :none))","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"","category":"page"},{"location":"gallery/gallery/data manipulations/wide_data/","page":"Wide data","title":"Wide data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"layers/operations/#Algebraic-Operations","page":"Algebraic Operations","title":"Algebraic Operations","text":"","category":"section"},{"location":"layers/operations/","page":"Algebraic Operations","title":"Algebraic Operations","text":"There are two algebraic types that can be added or multiplied with each other: AlgebraOfGraphics.Layer and AlgebraOfGraphics.Layers.","category":"page"},{"location":"layers/operations/#Multiplication-on-individual-layers","page":"Algebraic Operations","title":"Multiplication on individual layers","text":"","category":"section"},{"location":"layers/operations/","page":"Algebraic Operations","title":"Algebraic Operations","text":"Each layer is composed of data, mappings, and transformations. Datasets can be replaced, mappings can be merged, and transformations can be concatenated. These operations, taken together, define an associative operation on layers, which we call multiplication *.","category":"page"},{"location":"layers/operations/","page":"Algebraic Operations","title":"Algebraic Operations","text":"Multiplication is primarily useful to combine partially defined layers.","category":"page"},{"location":"layers/operations/#Addition","page":"Algebraic Operations","title":"Addition","text":"","category":"section"},{"location":"layers/operations/","page":"Algebraic Operations","title":"Algebraic Operations","text":"The operation + is used to superimpose separate layers. a + b has as many layers as la + lb, where la and lb are the number of layers in a and b respectively.","category":"page"},{"location":"layers/operations/#Multiplication-on-lists-of-layers","page":"Algebraic Operations","title":"Multiplication on lists of layers","text":"","category":"section"},{"location":"layers/operations/","page":"Algebraic Operations","title":"Algebraic Operations","text":"Multiplication naturally extends to lists of layers. Given two Layers objects a and b, containing la and lb layers respectively, the product a * b contains la * lb layers—all possible pair-wise products.","category":"page"},{"location":"layers/introduction/#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"layers/introduction/","page":"Introduction","title":"Introduction","text":"Layers are the key building blocks of AlgebraOfGraphics. Each layer is the product of the following elementary objects.","category":"page"},{"location":"layers/introduction/","page":"Introduction","title":"Introduction","text":"Data (encoding the dataset).\nMapping (associating variables to plot attributes).\nVisual (encoding data-independent plot information).\nAnalyses (encoding transformations that are applied to the data before plotting).","category":"page"},{"location":"layers/introduction/","page":"Introduction","title":"Introduction","text":"Data, mappings, visuals and analyses can be combined together using Algebraic Operations to form one or more layers.","category":"page"},{"location":"layers/introduction/","page":"Introduction","title":"Introduction","text":"The output of these algebraic operations can be visualized, as shown in the section Drawing Layers.","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/discrete_scales.jl\"","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/#Discrete-scales","page":"Discrete scales","title":"Discrete scales","text":"","category":"section"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"By default categorical ticks, as well as names from legend entries, are taken from the value of the variable converted to a string. Scales can be equipped with labels to overwrite that. You can either use the renamer function to apply relabeling or reordering to some column on the fly, or you use the categories keyword for the respective scale in the draw call.","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"note: Note\nThe categories keyword (added in v0.7) also allows adding categories not present in the data.","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"df = (x=rand([\"a\", \"b\", \"c\"], 100), y=rand(100))\nplt = data(df) * mapping(:x, :y) * visual(BoxPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"plt = data(df) * mapping(:x, :y) * visual(BoxPlot)\ndraw(plt, scales(X = (;\n categories = [\"a\" => \"label1\", \"b\" => \"label2\", \"c\" => \"label3\"]\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"The same operation can be done with renamer as well which modifies the input data","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"plt = data(df) *\n mapping(\n :x => renamer(\"a\" => \"label1\", \"b\" => \"label2\", \"c\" => \"label3\"),\n :y\n ) * visual(BoxPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"With categories, you can add further categories that might be missing from your data","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"plt = data(df) * mapping(:x, :y) * visual(BoxPlot)\ndraw(plt, scales(X = (;\n categories = [\"a\", \"missing\", \"b\", \"c\"]\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"The order can also be changed:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"plt = data(df) * mapping(:x, :y) * visual(BoxPlot)\ndraw(plt, scales(X = (;\n categories = [\"b\" => \"label b\", \"a\" => \"label a\", \"c\" => \"label c\"]\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"Or with renamer:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"plt = data(df) *\n mapping(\n :x => renamer(\"b\" => \"label b\", \"a\" => \"label a\", \"c\" => \"label c\"),\n :y\n ) * visual(BoxPlot)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"When categories come from different datasets, you can either apply the same renamer to multiple mappings, or set the ordering at one place in categories:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"df1 = (; x = rand([\"one\", \"two\"], 100), y = randn(100))\ndf2 = (; x = rand([\"three\", \"four\"], 50), y = randn(50))\nplt = (data(df1) + data(df2)) * mapping(:x, :y) * visual(BoxPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"draw(plt, scales(X = (;\n categories = [\"one\", \"two\", \"three\", \"four\"]\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"You can also pass a function to categories, which has to return a vector with (optionally labelled) categories in the desired order. For example, strings are by default ordered alphabetically:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"df = (; name = [\"Anna Coolidge\", \"Berta Bauer\", \"Charlie Archer\"], age = [34, 79, 58])\nplt = data(df) * mapping(:name, :age) * visual(BarPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"Instead of specifying the order manually, we could use a function to order by last name:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"draw(plt, scales(X = (;\n categories = cats -> sort(cats; by = name -> split(name)[2])\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"Or even combine this with a relabeling function that shortens the first name to the initial:","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"function initialed(name)\n a, b = split(name)\n return name => \"$(first(a)). $b\"\nend\n\ndraw(plt, scales(X = (;\n categories = cats -> initialed.(sort(cats; by = name -> split(name)[2]))\n)))","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"","category":"page"},{"location":"gallery/gallery/scales/discrete_scales/","page":"Discrete scales","title":"Discrete scales","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/layout/faceting.jl\"","category":"page"},{"location":"gallery/gallery/layout/faceting/#Faceting","page":"Faceting","title":"Faceting","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-grid","page":"Faceting","title":"Facet grid","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"df = let\n N = 100\n x0 = rand(1:10, N)\n i = rand([\"α\", \"β\"], N)\n j = rand([\"a\", \"b\", \"c\"], N)\n\n x = map(zip(x0, j)) do (xx, jj)\n shift = jj == \"a\" ? -2.9 : jj == \"c\" ? 2.9 : 0.0\n xx + shift\n end\n\n y = map(zip(x0, i)) do (xx, ii)\n shift = ii == \"α\" ? -3.9 : 3.9\n xx + 2 + shift + rand()\n end\n\n (; x, y, i, j)\nend\n\nplt = data(df) * mapping(:x, :y, row=:i, col=:j)\n\ndraw(plt)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-grid-with-minimal-axes-linking-needed-to-remove-ticks","page":"Faceting","title":"Facet grid with minimal axes linking needed to remove ticks","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"draw(plt, facet=(; linkxaxes=:minimal, linkyaxes=:minimal))","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-grid-with-unlinked-x-axes","page":"Faceting","title":"Facet grid with unlinked x-axes","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"draw(plt, facet=(; linkxaxes=:none))","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-wrap","page":"Faceting","title":"Facet wrap","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"df = (x=rand(100), y=rand(100), l=rand([\"a\", \"b\", \"c\", \"d\", \"e\"], 100))\nplt = data(df) * mapping(:x, :y, layout=:l)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-wrap-with-unlinked-axes","page":"Faceting","title":"Facet wrap with unlinked axes","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"draw(plt, facet=(; linkxaxes=:none, linkyaxes=:none))","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Facet-wrap-with-specified-layout-for-rows-and-cols","page":"Faceting","title":"Facet wrap with specified layout for rows and cols","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"draw(plt, scales(Layout = (; palette = [(1, 1), (2, 1), (3, 1), (1, 2), (2, 2)])))","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Adding-traces-to-only-some-subplots","page":"Faceting","title":"Adding traces to only some subplots","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"df1 = (x=rand(100), y=rand(100), i=rand([\"a\", \"b\", \"c\"], 100), j=rand([\"d\", \"e\", \"f\"], 100))\ndf2 = (x=[0, 1], y=[0.5, 0.5], i=fill(\"a\", 2), j=fill(\"e\", 2))\nlayers = data(df1) * visual(Scatter) + data(df2) * visual(Lines)\nfg = draw(layers * mapping(:x, :y, col=:i, row=:j))","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Caveats","page":"Faceting","title":"Caveats","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"The faceting variable must be non-numeric. If the source is numeric, you can convert it with nonnumeric.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"df = (x=rand(100), y=rand(100), l=rand([1, 2, 3, 4, 5], 100))\nplt = data(df) * mapping(:x, :y, layout=:l => nonnumeric)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/#Pagination","page":"Faceting","title":"Pagination","text":"","category":"section"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"If you have too many facets for one figure, you can use paginate to split the data into several subsets given a maximum number of plots per layout, row or column.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"Scales are synchronized across pages. Note, however, that linked axis limits are currently not synchronized across pages. The exact synchronization behavior can be subject to change in non-breaking versions.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"df = (x=rand(500), y=rand(500), l=rand([\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"], 500))\nplt = data(df) * mapping(:x, :y, layout=:l)\npag = paginate(plt, layout = 4)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"Pagination with 2 entries (layout = 4)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"The object returned from draw will be a Vector{FigureGrid}.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"figuregrids = draw(pag)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"2-element Vector{AlgebraOfGraphics.FigureGrid}:\n FigureGrid()\n FigureGrid()","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"You can either extract single figures from this vector...","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"figuregrids[1]","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"or use draw with an optional second argument specifying the index of the page to draw.","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"draw(pag, 2)","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"","category":"page"},{"location":"gallery/gallery/layout/faceting/","page":"Faceting","title":"Faceting","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"EditURL = \"penguins.jl\"","category":"page"},{"location":"generated/penguins/#Tutorial","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"This is a gentle and lighthearted tutorial on how to use tools from AlgebraOfGraphics, using as example dataset a collection of measurements on penguins[1]. See the Palmer penguins website for more information.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"[1]: Gorman KB, Williams TD, Fraser WR (2014) Ecological Sexual Dimorphism and Environmental Variability within a Community of Antarctic Penguins (Genus Pygoscelis). PLoS ONE 9(3): e90081. DOI","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"To follow along this tutorial, you will need to install a few packages. All the required packages can be installed with the following command.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"julia> import Pkg; Pkg.add([\"AlgebraOfGraphics\", \"CairoMakie\", \"DataFrames\", \"LIBSVM\", \"PalmerPenguins\"])","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"After the above command completes, we are ready to go.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"using PalmerPenguins, DataFrames\n\npenguins = dropmissing(DataFrame(PalmerPenguins.load()))\nfirst(penguins, 6)","category":"page"},{"location":"generated/penguins/#Frequency-plots","page":"Tutorial 🐧","title":"Frequency plots","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Let us start by getting a rough idea of how the data is distributed.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"note: Note\nDue to julia's compilation model, the first plot may take a while to appear.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"using AlgebraOfGraphics, CairoMakie\nset_aog_theme!()\n\naxis = (width = 225, height = 225)\npenguin_frequency = data(penguins) * frequency() * mapping(:species)\n\ndraw(penguin_frequency; axis = axis)","category":"page"},{"location":"generated/penguins/#Small-intermezzo:-saving-the-plot","page":"Tutorial 🐧","title":"Small intermezzo: saving the plot","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"If you are working in an interactive enviroment with inline plotting support, such VSCode or Pluto.jl, the above should have displayed a bar plot. If you are working directly in the console, you can simply save the plot and inspect it in the file explorer.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"fg = draw(penguin_frequency; axis = axis)\nsave(\"figure.png\", fg, px_per_unit = 3) # save high-resolution png","category":"page"},{"location":"generated/penguins/#Styling-by-categorical-variables","page":"Tutorial 🐧","title":"Styling by categorical variables","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Next, let us see whether the distribution is the same across islands.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_frequency * mapping(color = :island)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Oops! The bars are in the same spot and are hiding each other. We need to specify how we want to fix this. Bars can either dodge each other, or be stacked on top of each other.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_frequency * mapping(color = :island, dodge = :island)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"This is our first finding. Adelie is the only species of penguins that can be found on all three islands. To be able to see both which species is more numerous and how different species are distributed across islands in a unique plot, we could have used stack.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_frequency * mapping(color = :island, stack = :island)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/#Correlating-two-variables","page":"Tutorial 🐧","title":"Correlating two variables","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Now that we have understood the distribution of these three penguin species, we can start analyzing their features.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"penguin_bill = data(penguins) * mapping(:bill_length_mm, :bill_depth_mm)\ndraw(penguin_bill; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We would actually prefer to visualize these measures in centimeters, and to have cleaner axes labels. As we want this setting to be preserved in all of our bill visualizations, let us save it in the variable penguin_bill, to be reused in subsequent plots.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"penguin_bill = data(penguins) * mapping(\n :bill_length_mm => (t -> t / 10) => \"bill length (cm)\",\n :bill_depth_mm => (t -> t / 10) => \"bill depth (cm)\",\n)\ndraw(penguin_bill; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Much better! Note the parentheses around the function t -> t / 10. They are necessary to specify that the function maps t to t / 10, and not to t / 10 => \"bill length (cm)\".","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"There does not seem to be a strong correlation between the two dimensions, which is odd. Maybe dividing the data by species will help.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_bill * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Ha! Within each species, penguins with a longer bill also have a deeper bill. We can confirm that with a linear regression","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_bill * linear() * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"This unfortunately no longer shows our data! We can use + to plot both things on top of each other:","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_bill * linear() * mapping(color = :species) + penguin_bill * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Note that the above expression seems a bit redundant, as we wrote the same thing twice. We can \"factor it out\" as follows","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_bill * (linear() + mapping()) * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"where mapping() is a neutral multiplicative element. Of course, the above could be refactored as","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = linear() + mapping()\nplt = penguin_bill * layers * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We could actually take advantage of the spare mapping() and use it to pass some extra info to the scatter, while still using all the species members to compute the linear fit.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = linear() + mapping(marker = :sex)\nplt = penguin_bill * layers * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"This plot is getting a little bit crowded. We could instead show female and male penguins in separate subplots.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = linear() + mapping(col = :sex)\nplt = penguin_bill * layers * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"See how both plots show the same fit, because the sex mapping is not applied to linear(). The following on the other hand produces a separate fit for males and females:","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = linear() + mapping()\nplt = penguin_bill * layers * mapping(color = :species, col = :sex)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/#Smooth-density-plots","page":"Tutorial 🐧","title":"Smooth density plots","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"An alternative approach to understanding how two variables interact is to consider their joint probability density distribution (pdf).","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"using AlgebraOfGraphics: density\nplt = penguin_bill * density(npoints=50) * mapping(col = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"The default colormap is multi-hue, but it is possible to pass single-hue colormaps as well. The color range is inferred from the data by default, but it can also be passed manually. Both settings are passed via scales to draw, because multiple plots can share the same colormap, so visual is not the appropriate place for this setting.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"draw(plt, scales(Color = (; colormap = :grayC, colorrange = (0, 6))); axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We could also use a Contour plot instead:","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"axis = (width = 225, height = 225)\nlayer = density() * visual(Contour)\nplt = penguin_bill * layer * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"The data and the linear fit can also be added back to the plot:","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = density() * visual(Contour) + linear() + mapping()\nplt = penguin_bill * layers * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"In the case of many layers (contour, density and scatter) it is important to think about balance. In the above plot, the markers are quite heavy and can obscure the linear fit and the contour lines. We can lighten the markers using alpha transparency.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"layers = density() * visual(Contour) + linear() + visual(alpha = 0.5)\nplt = penguin_bill * layers * mapping(color = :species)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/#Correlating-three-variables","page":"Tutorial 🐧","title":"Correlating three variables","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We are now mostly up to speed with bill size, but we have not considered how it relates to other penguin features, such as their weight. For that, a possible approach is to use a continuous color on a gradient to denote weight and different marker shapes to denote species. Here we use group to split the data for the linear regression without adding any additional style.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"body_mass = :body_mass_g => (t -> t / 1000) => \"body mass (kg)\"\nlayers = linear() * mapping(group = :species) + mapping(color = body_mass, marker = :species)\nplt = penguin_bill * layers\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"plt = penguin_bill * mapping(body_mass, color = :species, layout = :sex)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Note that static 3D plot can be misleading, as they only show one projection of 3D data. They are mostly useful when shown interactively.","category":"page"},{"location":"generated/penguins/#Machine-Learning","page":"Tutorial 🐧","title":"Machine Learning","text":"","category":"section"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Finally, let us use Machine Learning techniques to build an automated penguin classifier!","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We would like to investigate whether it is possible to predict the species of a penguin based on its bill size. To do so, we will use a standard classifier technique called Support-Vector Machine.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"The strategy is quite simple. We split the data into training and testing subdatasets. We then train our classifier on the training dataset and use it to make predictions on the whole data. We then add the new columns obtained this way to the dataset and visually inspect how well the classifier performed in both training and testing.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"using LIBSVM, Random\n\n# use approximately 80% of penguins for training\nRandom.seed!(1234) # for reproducibility\nN = nrow(penguins)\ntrain = fill(false, N)\nperm = randperm(N)\ntrain_idxs = perm[1:floor(Int, 0.8N)]\ntrain[train_idxs] .= true\nnothing # hide\n\n# fit model on training data and make predictions on the whole dataset\nX = hcat(penguins.bill_length_mm, penguins.bill_depth_mm)\ny = penguins.species\nmodel = SVC() # Support-Vector Machine Classifier\nfit!(model, X[train, :], y[train])\nŷ = predict(model, X)\n\n# incorporate relevant information in the dataset\npenguins.train = train\npenguins.predicted_species = ŷ\nnothing #hide","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Now, we have all the columns we need to evaluate how well our classifier performed.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"axis = (width = 225, height = 225)\ndataset =:train => renamer(true => \"training\", false => \"testing\") => \"Dataset\"\naccuracy = (:species, :predicted_species) => isequal => \"accuracy\"\nplt = data(penguins) *\n expectation() *\n mapping(:species, accuracy) *\n mapping(col = dataset)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"That is a bit hard to read, as all values are very close to 1. Let us visualize the error rate instead.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"error_rate = (:species, :predicted_species) => !isequal => \"error rate\"\nplt = data(penguins) *\n expectation() *\n mapping(:species, error_rate) *\n mapping(col = dataset)\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"So, mostly our classifier is doing quite well, but there are some mistakes, especially among Chinstrap penguins. Using at the same time the species and predicted_species mappings on different attributes, we can see which penguins are problematic.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"prediction = :predicted_species => \"predicted species\"\ndatalayer = mapping(color = prediction, row = :species, col = dataset)\nplt = penguin_bill * datalayer\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"Um, some of the penguins are indeed being misclassified... Let us try to understand why by adding an extra layer, which describes the density of the distributions of the three species.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"pdflayer = density() * visual(Contour, colormap=Reverse(:grays)) * mapping(group = :species)\nlayers = pdflayer + datalayer\nplt = penguin_bill * layers\ndraw(plt; axis = axis)","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"We can conclude that the classifier is doing a reasonable job: it is mostly making mistakes on outlier penguins.","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"","category":"page"},{"location":"generated/penguins/","page":"Tutorial 🐧","title":"Tutorial 🐧","text":"This page was generated using Literate.jl.","category":"page"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/applications/geometries.jl\"","category":"page"},{"location":"gallery/gallery/applications/geometries/#Geometries","page":"Geometries","title":"Geometries","text":"","category":"section"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"using AlgebraOfGraphics, CairoMakie\nusing GeometryBasics\n\ngeometry = [Rect(Vec(i, j), Vec(1, 1)) for i in 0:7 for j in 0:7]\ngroup = [isodd(i + j) ? \"light square\" : \"dark square\" for i in 0:7 for j in 0:7]\ndf = (; geometry, group)\n\nplt = data(df) * visual(Poly) * mapping(:geometry, color = :group)\nfg = draw(plt; axis=(aspect=1,))","category":"page"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"(Image: )","category":"page"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"","category":"page"},{"location":"gallery/gallery/applications/geometries/","page":"Geometries","title":"Geometries","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/index.md\"","category":"page"},{"location":"gallery/#Gallery","page":"Gallery","title":"Gallery","text":"","category":"section"},{"location":"gallery/#Basic-visualizations","page":"Gallery","title":"Basic visualizations","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Lines and markers\n

\n

\n Basic linear and scatter plots.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Statistical visualizations\n

\n

\n Violin plot, boxplot, qqplot.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Statistical-analyses","page":"Gallery","title":"Statistical analyses","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Density plots\n

\n

\n Visualizing kernel density estimation of data.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Histograms\n

\n

\n Computing 1- and 2-dimensional histograms.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Regression plots\n

\n

\n Linear and nonlinear regressions.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Data-manipulations","page":"Gallery","title":"Data manipulations","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Renaming and transforming variables\n

\n

\n Transforming data before generating the plot.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Using mapping without tabular data\n

\n

\n Passing columnar data directly to `mapping`.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Pre-grouped data\n

\n

\n Working with arrays of arrays.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Pre-sorted data\n

\n

\n Preserving the original order of categorical data.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Wide data\n

\n

\n Working with data in the wide format.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Scales","page":"Gallery","title":"Scales","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"Some advanced keywords to tweak the plot","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Discrete scales\n

\n

\n Sorting and renaming categorical variables.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Continuous scales\n

\n

\n Applying nonlinear transformations.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Custom scales\n

\n

\n Custom palettes and custom attributes.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Split scales across facets\n

\n

\n Using different categorical and continuous scales across a facet layout.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Secondary scales\n

\n

\n Categorical and continuous scales in the same plot.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Multiple color scales\n

\n

\n Categorical and continuous scales in the same plot.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Pre-scaled data\n

\n

\n Pass data to the plot as is.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Legend merging\n

\n

\n Multiple scales for the same variable.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Dodging\n

\n

\n Dodging groups to avoid overlaps.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Customization","page":"Gallery","title":"Customization","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"Some advanced keywords to tweak the plot","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Axis tweaking\n

\n

\n Setting axis attributes.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Figure tweaking\n

\n

\n Setting figure attributes.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Legend tweaking\n

\n

\n Setting legend attributes.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Colorbar tweaking\n

\n

\n Setting colorbar attributes.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Layout","page":"Gallery","title":"Layout","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Faceting\n

\n

\n Generating a grid of plots.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Nested layouts\n

\n

\n AlgebraOfGraphics plots within a Makie figure.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/#Applications","page":"Gallery","title":"Applications","text":"","category":"section"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"Example applications with different types of data","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Geographic data\n

\n

\n Antarctic coastline.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Geometries\n

\n

\n Visualizing geometries.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
\n

\n Time series\n

\n

\n Visualizing time series data.\n

\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"(Image: card image)","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
\n
\n
","category":"page"},{"location":"gallery/","page":"Gallery","title":"Gallery","text":"
","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/data manipulations/new_columns_on_the_fly.jl\"","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/#Renaming-and-transforming-variables","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"","category":"section"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"using AlgebraOfGraphics, CairoMakie\n\ndf = (x=rand(100), y=rand(100), z=rand(100), c=rand([\"a\", \"b\"], 100))\nlayers = linear() + mapping(color=:z)\n\nplt = data(df) * layers * mapping(:x => (x -> x^2) => L\"x^2\", :y => L\"This variable is called $y$\")\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"Use a Tuple to pass combine several columns into a unique operation.","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"plt = data(df) * layers * mapping(:x, (:x, :y, :z) => (+) => L\"the new variable $x + y + z$\", layout=:c)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"(Image: )","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"","category":"page"},{"location":"gallery/gallery/data manipulations/new_columns_on_the_fly/","page":"Renaming and transforming variables","title":"Renaming and transforming variables","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/customization/colorbar.jl\"","category":"page"},{"location":"gallery/gallery/customization/colorbar/#Colorbar-tweaking","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"","category":"section"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"(Image: Source code)","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"To tweak the position and appearance of the colorbar, simply use the colorbar keyword when plotting. For example","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"df = (x=rand(100), y=rand(100), z=rand(100))\nplt = data(df) * mapping(:x, :y, color=:z)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"fg = draw(plt, colorbar=(position=:top, size=25))","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"To change the colormap, you have to modify the corresponding scale. Usually, this will be the Color scale.","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"note: Note\nBefore AlgebraOfGraphics v0.7, you would change the colormap by passing it via visual. This was changed so that each color scale, which can be used by multiple plot layers, has a single source of truth for these settings.","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"draw(plt, scales(Color = (; colormap = :thermal)))","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"Other continuous color parameters are highclip, lowclip, nan_color and colorrange.","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"draw(plt, scales(Color = (;\n colormap = :thermal,\n colorrange = (0.25, 0.75),\n highclip = :cyan,\n lowclip = :lime,\n)))","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"(Image: )","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"","category":"page"},{"location":"gallery/gallery/customization/colorbar/","page":"Colorbar tweaking","title":"Colorbar tweaking","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/custom_scales.jl\"","category":"page"},{"location":"gallery/gallery/scales/custom_scales/#custom_scales","page":"Custom scales","title":"Custom scales","text":"","category":"section"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"using AlgebraOfGraphics, CairoMakie\nusing Colors","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"A palette maps categorical values to particular attribute specifications (e.g. the first value maps to green, the second maps to red, and so on).","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"x=repeat(1:20, inner=20)\ny=repeat(1:20, outer=20)\nu=cos.(x)\nv=sin.(y)\nc=rand(Bool, length(x))\nd=rand(Bool, length(x))\ndf = (; x, y, u, v, c, d)\ncolors = [colorant\"#E24A33\", colorant\"#348ABD\"]\nheads = ['◮', '◭']\nplt = data(df) *\n mapping(:x, :y, :u, :v) *\n mapping(arrowhead = :c => nonnumeric) *\n mapping(color = :d => nonnumeric) *\n visual(Arrows, arrowsize=10, lengthscale=0.4, linewidth = 1)\nfg = draw(plt, scales(Marker = (; palette = heads), Color = (; palette = colors)))","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"To associate specific attribute values to specific data values, use pairs. Missing keys will cycle over values that are not pairs.","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"x = rand(100)\ny = rand(100)\nz = rand([\"a\", \"b\", \"c\", \"d\"], 100)\ndf = (; x, y, z)\nplt = data(df) * mapping(:x, :y, color=:z)\ncolors = [\"a\" => :tomato, \"c\" => :lime, colorant\"#988ED5\", colorant\"#777777\"]\ndraw(plt, scales(Color = (; palette = colors)))","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"Categorical color gradients can also be passed to palettes. You can use the from_continuous helper function to wrap continuous colormaps which you want to sample from start to end in n steps, where n is the number of categories you are visualizing.","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"x = rand(200)\ny = rand(200)\nz = rand([\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"], 200)\ndf = (; x, y, z)\nplt = data(df) * mapping(:x, :y, color=:z)\ndraw(plt, scales(Color = (; palette = from_continuous(:cividis))))","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"","category":"page"},{"location":"gallery/gallery/scales/custom_scales/","page":"Custom scales","title":"Custom scales","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/dodging.jl\"","category":"page"},{"location":"gallery/gallery/scales/dodging/#dodging","page":"Dodging","title":"Dodging","text":"","category":"section"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"using AlgebraOfGraphics, CairoMakie\nusing Colors","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"Some plot types like barplots natively support a dodge attribute which avoids overlap between groups that share the same coordinates.","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"df = (; x = [\"One\", \"One\", \"Two\", \"Two\"], y = 1:4, err = [0.2, 0.3, 0.4, 0.5], group = [\"A\", \"B\", \"A\", \"B\"])\nplt = data(df) * mapping(:x, :y, dodge = :group, color = :group) * visual(BarPlot)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"Other plot types like errorbars do not have a dodge keyword, however you can dodge them using AlgebraOfGraphic's hardcoded dodge_x or dodge_y mappings. These will only shift the data away from the category centers but will not change other plot attributes (like dodging a barplot makes narrower bars). They are therefore mostly appropriate for \"width-less\" plot types like scatters or errorbars.","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"If you combine errorbars with a barplot, AlgebraOfGraphics will apply the barplot's dodge width to the errorbars automatically so they match:","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"plt2 = data(df) * mapping(:x, :y, :err, dodge_x = :group) * visual(Errorbars)\nfg = draw(plt + plt2)","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"If you only use \"width-less\" plot types, you will get an error if you don't set a dodge width manually. You can do so via the scales function:","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"df = (\n x = repeat(1:10, inner = 2),\n y = cos.(range(0, 2pi, length = 20)),\n ylow = cos.(range(0, 2pi, length = 20)) .- 0.2,\n yhigh = cos.(range(0, 2pi, length = 20)) .+ 0.3,\n dodge = repeat([\"A\", \"B\"], 10)\n)\n\nf = Figure()\nplt3 = data(df) * (\n mapping(:x, :y, dodge_x = :dodge, color = :dodge) * visual(Scatter) +\n mapping(:x, :ylow, :yhigh, dodge_x = :dodge, color = :dodge) * visual(Rangebars)\n)\nkw(; kwargs...) = (; xticklabelsvisible = false, xticksvisible = false, xlabelvisible = false, kwargs...)\n\ndraw!(f[1, 1], plt3, scales(DodgeX = (; width = 0.25)); axis = kw(title = \"DodgeX = (; width = 0.25)\"))\ndraw!(f[2, 1], plt3, scales(DodgeX = (; width = 0.5)); axis = kw(title = \"DodgeX = (; width = 0.5)\"))\ndraw!(f[3, 1], plt3, scales(DodgeX = (; width = 1.0)); axis = (; title = \"DodgeX = (; width = 1.0)\"))\n\nf","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"","category":"page"},{"location":"gallery/gallery/scales/dodging/","page":"Dodging","title":"Dodging","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/scales/prescaled_data.jl\"","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/#Pre-scaled-data","page":"Pre-scaled data","title":"Pre-scaled data","text":"","category":"section"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"using AlgebraOfGraphics, CairoMakie\nusing Colors\n\nx = rand(100)\ny = rand(100)\nz = rand([colorant\"teal\", colorant\"orange\"], 100)\ndf = (; x, y, z)\nplt = data(df) * mapping(:x, :y, color=:z => verbatim)\ndraw(plt)","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"Plotting labels instead of markers","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"x = rand(100)\ny = rand(100)\nlabel = rand([\"a\", \"b\"], 100)\ndf = (; x, y, label)\nplt = data(df) * mapping(:x, :y, text=:label => verbatim) * visual(Makie.Text)\nfg = draw(plt)","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"","category":"page"},{"location":"gallery/gallery/scales/prescaled_data/","page":"Pre-scaled data","title":"Pre-scaled data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/layout/nested_layouts.jl\"","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/#Nested-layouts","page":"Nested layouts","title":"Nested layouts","text":"","category":"section"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"using AlgebraOfGraphics, CairoMakie","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"All AlgebraOfGraphics plots can be inserted in any figure position, where the rest of the figure is managed by vanilla Makie. For example","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"fig = Figure(; size=(800, 600))\nax = Axis(fig[1, 1], title=\"Some plot\")\n\ndf = (\n x=rand(500),\n y=rand(500),\n i=rand([\"a\", \"b\", \"c\"], 500),\n j=rand([\"d\", \"e\", \"f\"], 500),\n k=rand(Bool, 500),\n l=rand(Bool, 500)\n)\nplt = data(df) * mapping(:x, :y, col=:i, row=:j, color=:k, marker=:l)\n\nsubfig = fig[1, 2:3]\nag = draw!(subfig, plt)\nfor ae in ag\n ae.axis.xticklabelrotation[] = π/2\nend\nlegend!(fig[end+1, 2], ag, orientation=:horizontal, tellheight=true)\nfig","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"The above also works in more nested situations.","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"f = Figure(; size=(800, 600))\nax = Axis(f[1, 1], title=\"Some plot\")\nsubfig = f[1, 2]\nax2 = Axis(subfig[1, 1])\n\ndf = (\n x=rand(500),\n y=rand(500),\n c=rand([\"a\", \"b\", \"c\"], 500),\n)\nplt = data(df) * mapping(:x, :y, color=:c)\n\ndraw!(subfig[2, 1], plt)\nf","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"It is also possible to let Makie control the axis and plot directly on top of it.","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"f = Figure(; size=(800, 300))\nax1 = Axis(f[1, 1])\nax2 = Axis(f[1, 2])\n\ndf = (x=rand(100), y=rand(100), c=rand([\"a\", \"b\", \"c\"], 100))\nplt = data(df) * mapping(:x, :y, color=:c)\n\nscatter!(ax1, rand(10), rand(10), color=:black)\ngrid = draw!(ax2, plt)\nlegend!(f[1, 3], grid)\n\nf","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"(Image: )","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"","category":"page"},{"location":"gallery/gallery/layout/nested_layouts/","page":"Nested layouts","title":"Nested layouts","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"EditURL = \"/home/runner/work/AlgebraOfGraphics.jl/AlgebraOfGraphics.jl/docs/gallery/gallery/applications/geographic.jl\"","category":"page"},{"location":"gallery/gallery/applications/geographic/#Geographic-data","page":"Geographic data","title":"Geographic data","text":"","category":"section"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"(Image: Source code) (Image: Author)","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"using AlgebraOfGraphics, CairoMakie\nusing Shapefile, ZipFile\nusing Downloads","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"Antarctic coastline. Data from the SCAR Antarctic Digital Database[1].","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"[1]: Gerrish, L., Fretwell, P., & Cooper, P. (2021). Medium resolution vector polygons of the Antarctic coastline (7.4) [Data set]. UK Polar Data Centre, Natural Environment Research Council, UK Research & Innovation. https://doi.org/10.5285/747e63e-9d93-49c2-bafc-cf3d3f8e5afa","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"# Download, extract, and load shapefile\nt = mktempdir() do dir\n url = \"https://ramadda.data.bas.ac.uk/repository/entry/get/add_coastline_medium_res_polygon_v7_4.zip?entryid=synth%3Ae747e63e-9d93-49c2-bafc-cf3d3f8e5afa%3AL2FkZF9jb2FzdGxpbmVfbWVkaXVtX3Jlc19wb2x5Z29uX3Y3XzQuemlw\"\n r = ZipFile.Reader(seekstart(Downloads.download(url, IOBuffer())))\n for f in r.files\n open(joinpath(dir, f.name), write = true) do io\n write(io, read(f, String));\n end\n end\n Shapefile.Table(joinpath(dir, \"add_coastline_medium_res_polygon_v7_4.shp\"))\nend\n\n# Draw map\nplt = data(t) * mapping(:geometry, color = :surface) * visual(Choropleth)\nfg = draw(plt; axis=(aspect=1,))","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"(Image: )","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"","category":"page"},{"location":"gallery/gallery/applications/geographic/","page":"Geographic data","title":"Geographic data","text":"This page was generated using DemoCards.jl and Literate.jl.","category":"page"}] }