AlgebraOfGraphics.jl
AlgebraOfGraphics.jl copied to clipboard
Simpler syntax for data+mapping
This is to discuss a simpler syntax for passing data and mappings together, as requested on Discourse.
The given example was
x = range(-π, π, length=100)
y = sin.(x)
df = (; x, y)
data(df) * mapping(:x, :y) * visual(Lines)
In Gadfly the last two lines are simply layer(x = x, y = y, Geom.line).
It's actually not that bad currently as we can use the pre-grouped syntax and write
x = range(-π, π, length=100)
y = sin.(x)
mapping([x] => "x", [y] => "y") * visual(Lines) |> draw

or more complex:
mapping([x] => "x", [sin.(x), cos.(x)] => "y", color=["sin", "cos"]) * visual(Lines) |> draw

What I see missing is
-
Support for
mapping(x, y)as shorthand formapping([x], [y])Maybe also support matrices. For example if
A = [a1 a2]is a two-column matrix,mapping(A)could be a shorthand formapping([[a1] [a2]]). -
A way to unlink axes (#203), to support unrelated subplots such as
a = 0:0.1:3 b = 5:0.1:7 mapping([a, b], [sin.(a), sqrt.(b)], layout=["sin", "sqrt"]) * visual(Lines) |> draw -
Some bug(?)fixes as the following don't seem to work:
mapping([x], [sin.(x), cos.(x)], layout=["sin", "cos"])works but withcolit givesInexactError: trunc(Int64, NaN)mapping([x], [sin.(x), cos.(x)], color=dims(1))works but it fails with[sin.(x), cos.(x)] => "y"(gives only one color, and with.=>it produces garbage).mapping([a, b] => ["a", "b"], [sin.(a), sqrt.(b)], layout=["sin", "sqrt"])fails withMethodError: objects of type Vector{String} are not callable, and with.=>it produces garbage.
Regarding the support for mapping(x, y) as shorthand for mapping([x], [y]), I thought it could be useful to have a list of accepted types, to see how this would fit.
Here's what I found based on the documentation (these are actually valid types that could be used in dispatch):
-
StringLikeandPair{<:StringLike}: Name of a data column.Examples:
:x:h => "Height":y => log => "y"
-
Array{<:StringLike}andArray{<:Pair{<:StringLike}}: Names of data columns (for wide data).Examples:
[:a, :b, :c][:a, :b, :c] .=> "some label"[:a :b :c](fordims(2))
-
DimsSelectorandPair{<:DimsSelector}: Index identifying a dimension in the group space.Examples:
dims(1)dims(1) => renamer(["Trace 1", "Trace 2"])
-
Pair{<:Tuple{Vararg{StringLike}}}: Names of data columns (for creating new column on the fly).Example:
(:x, :y, :z) => (+) => "x + y + z"
-
Array{<:Vector}: Data itself as an array of groups (for pre-grouped data).Example:
[rand(10) for i in 1:3][[rand(10) for i in 1:3] [rand(10) for i in 1:3]]
-
Pair{<:Tuple{Vararg{Array{<:Vector}}}}: Data itself as arrays of groups (for on the fly column from pre-grouped data).Example:
([rand(10) for i in 1:3], [rand(10) for i in 1:3]) => (+) => "sum"
It seems that Array{<:Number} and Pair{<:Array{<:Number}} would fit nicely without ambiguity?
Nice tip to use mapping([x] => "x", [y] => "y") * visual(Lines). :smile: You can also use mapping([x] => :x, [y] => :y) * visual(Lines), by the way.