I recently started tinkering with Vega-Lite templates to make a confusion matrix for an open-source data science software called DVC. You can see the template in my PR here, but I'll also repeat a simplified version below:
{
...
"data": {
"values": [
{"actual": "Wake", "predicted": "Wake", "rev": "HEAD"},
{"actual": "Wake", "predicted": "Deep", "rev": "HEAD"},
{"actual": "Light", "predicted": "Wake", "rev": "HEAD"},
{"actual": "REM", "predicted": "Light", "rev": "HEAD"},
....
],
},
"spec": {
"transform": [
{
"aggregate": [{"op": "count", "as": "xy_count"}],
"groupby": ["actual", "predicted"],
},
{
"joinaggregate": [
{"op": "max", "field": "xy_count", "as": "max_count"}
],
"groupby": [],
},
{
"calculate": "datum.xy_count / datum.max_count",
"as": "percent_of_max",
},
],
"encoding": {
"x": {"field": "predicted", "type": "nominal", "sort": "ascending"},
"y": {"field": "actual", "type": "nominal", "sort": "ascending"},
},
"layer": [
{
"mark": "rect",
"width": 300,
"height": 300,
"encoding": {
"color": {
"field": "xy_count",
"type": "quantitative",
"title": "",
"scale": {"domainMin": 0, "nice": True},
}
},
},
{
"mark": "text",
"encoding": {
"text": {
"field": "xy_count",
"type": "quantitative"
},
"color": {
"condition": {
"test": "datum.xy_count / datum.max_count > 0.5",
"value": "white"
},
"value": "black"
}
}
}
]
}
}
So, since I'm doing a groupby aggregation, it's possible for there to be cells in the confusion matrix with no entries. Here's an example output: link
How can I fill in these cells with "fallback" or something. I also looked at using pivot and impute, but couldn't quite figure it out. Help much appreciated :)