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
ERROR: LoadError: There was no `AbstractPlotting.convert_arguments` overload found for
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