# Categorical heatmap

Can I use AoG for a categorical heatmap?

using RDatasets
let
diamonds = dataset("ggplot2", "diamonds")
p = data(diamonds) * mapping(:Cut => categorical, :Color => categorical, color=:Price) * visual(Heatmap)
draw(p)
end
the plot type Combined{AbstractPlotting.heatmap,Tuple{Array{Int16,1},Array{Int16,1}}}, or its conversion trait AbstractPlotting.SurfaceLike().
The arguments were:
(Array{Int16,1}, Array{Int16,1})

To fix this, define `AbstractPlotting.convert_arguments(::Combined{AbstractPlotting.heatmap,Tuple{Array{Int16,1},Array{Int16,1}}}, ::Array{Int16,1}, ::Array{Int16,1})`.

Do not know about AlgebraOfGraphics.jl but in case it helps, VegaLite.jl can be used for this interesting task:

using VegaLite, RDatasets

diamonds = RDatasets.dataset("ggplot2", "diamonds")

diamonds |>
@vlplot(
:rect, width=300, height=200,
x="Cut:n", y="Color:n",
color={"mean(Price)", title="Mean price", scale={scheme="blueorange"}},
config={view={stroke="transparent"}}
)

julia> diamonds
53940ร10 DataFrame
Row โ Carat    Cut        Color  Clarity  Depth    Table    Price  X        Y        Z
โ Float64  Catโฆ       Catโฆ   Catโฆ     Float64  Float64  Int32  Float64  Float64  Float64
โโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
1 โ    0.23  Ideal      E      SI2         61.5     55.0    326     3.95     3.98     2.43
2 โ    0.21  Premium    E      SI1         59.8     61.0    326     3.89     3.84     2.31
3 โ    0.23  Good       E      VS1         56.9     65.0    327     4.05     4.07     2.31
โฎ   โ    โฎ         โฎ        โฎ       โฎ        โฎ        โฎ       โฎ       โฎ        โฎ        โฎ
53938 โ    0.7   Very Good  D      SI1         62.8     60.0   2757     5.66     5.68     3.56
53939 โ    0.86  Premium    H      SI2         61.0     58.0   2757     6.15     6.12     3.74
53940 โ    0.75  Ideal      D      SI2         62.2     55.0   2757     5.83     5.87     3.64
53923 rows omitted
1 Like

If I understand correctly you want to basically create a table with as x and y axes Cut and Color and content the mean Price, and then draw a heatmap of that. Creating this objects is done with the analysis reducer.

However here this wonโt quite work, because this would then call a heatmap with 3 vectors (which is essentially a โnon-fullโ heatmap). I wonder if this, ie heatmap(x::Vector, y::Vector, z::Vector) is something Makie can support out of the box (using some default value for missing x, y combinations), or whether it needs to be handled on the side of AlgebraOfGraphics.

1 Like

@piever Can you say why the code I tried doesnโt work?

AlgebraOfGraphics is essentially a way to do some preprocessing before sending data to Makie for the plot. In your case, you end up calling heatmap with the following signature:

heatmap(diamonds.cut::Vector, diamonds.color::Vector, color::Vector=diamonds.Price)

but heatmap(x, y, color=z) is not supported in Makie. Beyond that, there is no way to guess that you actually want the mean price given the x and y variable. Taking the mean value can be handled by AoG with reducer. For example, here is the 1D case:

using AlgebraOfGraphics, CairoMakie, RDatasets
using AlgebraOfGraphics: reducer

diamonds = dataset("ggplot2", "diamonds")
p = data(diamonds) *
mapping(:Cut => categorical, :Price) *
reducer() *
visual(BarPlot)
draw(p)

I was imagining that the following

diamonds = dataset("ggplot2", "diamonds")
p = data(diamonds) *
mapping(:Cut => categorical, :Color => categorical, :Price) *
reducer() *
visual(Heatmap)
draw(p)

would just work, but unfortunately it looks like heatmap(x::Vector, y::Vector, z::Vector) is not supported out of the box in Makie. I can check over at Makie if it makes sense to add it there, otherwise the small reshape necessary (from the โlongโ to the โmatrixโ format) can be handled in AoG.

UPDATE: the syntax

diamonds = dataset("ggplot2", "diamonds")
p = data(diamonds) *  mapping(:Cut => categorical, :Color => categorical, :Price) * reducer
draw(p)

now works on AlgebraOfGraphics master branch.

2 Likes