Search code examples
vega-litevega

Text overlay in heatmap


Is it possible to overlay text in selectable heatmap

https://vega.github.io/editor/#/examples/vega-lite/selection_heatmap

If I plot a heatmap of actual vs predicted for binary in the selectable heatmap, can I overlay text as True Positives, FP, TN, FN with corresponding values and turn off legend

Here full code

{
  "$schema": "https://vega.github.io/schema/vega-lite/v2.4.json",
  "data": {
    "values": [
      {"actual": "Good", "predicted": "Bad", "count": 6386},
      {"actual": "Bad", "predicted": "Good", "count": 1261},
      {"actual": "Bad", "predicted": "Bad", "count": 6386},
      {"actual": "Good", "predicted": "Good", "count": 24030}
    ]
  },
  "mark": {"type": "rect", "strokeWidth": 2},
  "encoding": {
    "y": {
      "field": "actual",
      "type": "nominal"
    },
    "x": {
      "field": "predicted",
      "type": "nominal"
    },
    "fill": {
      "field": "count",
      "type": "quantitative"
    },
  "config": {
    "scale": {
      "bandPaddingInner": 0,
      "bandPaddingOuter": 0
    }
  }
}

Output like enter image description here

Is it possible to extract values from index and feed to count values

    "url" : {
        "%context%": true,
        "index": "index",
        "body": {
          "size":1000,
          "_source": ["modelMetrics"],
        }
      }  
    "format": {"property": "hits.hits"}
  },

where index has

        "_source" : {
          "modelMetrics" : {
            "TN" : 110868,
            "FP" : 6386,
            "FN" : 1261,
            "TP" : 24030,
          }
         }

Solution

  • You can do this using a Layered chart construct. For example (view in editor):

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v2.4.json",
      "data": {
        "values": [
          {"actual": "Good", "predicted": "Bad", "label": "FP", "count": 6386},
          {"actual": "Bad", "predicted": "Good", "label": "FN", "count": 1261},
          {"actual": "Bad", "predicted": "Bad", "label": "TN", "count": 6386},
          {"actual": "Good", "predicted": "Good", "label": "TP", "count": 24030}
        ]
      },
      "encoding": {
        "y": {"field": "actual", "type": "nominal"},
        "x": {"field": "predicted", "type": "nominal"}
      },
      "layer": [
        {
          "mark": {"type": "rect", "strokeWidth": 2},
          "encoding": {
            "fill": {"field": "count", "type": "quantitative", "legend": null}
          }
        },
        {
          "mark": {"type": "text", "dy": -5},
          "encoding": {
            "text": {"field": "label", "type": "nominal"},
            "color": {
              "condition": {"test": "datum.count < 10000", "value": "black"},
              "value": "white"
            }
          }
        },
        {
          "mark": {"type": "text", "dy": 5},
          "encoding": {
            "text": {"field": "count", "type": "nominal"},
            "color": {
              "condition": {"test": "datum.count < 10000", "value": "black"},
              "value": "white"
            }
          }
        }
      ],
      "width": 100,
      "height": 100
    }
    

    enter image description here