Heatmap Example

A heatmap of annual temperatures in Seattle, organized by day versus hour. How do different choices of color palette affect the clarity of the patterns? For an alternative design using area charts, see the Annual Temperature example. This example uses a grid of rect marks. For an example that instead generates heatmaps as rendered image marks, see the Density Heatmaps example.

Vega JSON Specification <>

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "width": 800,
  "height": 500,
  "padding": 5,

  "title": {
    "text": "Seattle Annual Temperatures",
    "anchor": "middle",
    "fontSize": 16,
    "frame": "group",
    "offset": 4
  },

  "signals": [
    {
      "name": "palette", "value": "Viridis",
      "bind": {
        "input": "select",
        "options": [
          "Viridis",
          "Magma",
          "Inferno",
          "Plasma",
          "DarkBlue",
          "DarkGold",
          "DarkGreen",
          "DarkMulti",
          "DarkRed",
          "LightGreyRed",
          "LightGreyTeal",
          "LightMulti",
          "LightOrange",
          "LightTealBlue",
          "Blues",
          "Browns",
          "Greens",
          "Greys",
          "Oranges",
          "Purples",
          "Reds",
          "TealBlues",
          "Teals",
          "WarmGreys",
          "BlueOrange",
          "BrownBlueGreen",
          "PurpleGreen",
          "PinkYellowGreen",
          "PurpleOrange",
          "RedBlue",
          "RedGrey",
          "RedYellowBlue",
          "RedYellowGreen",
          "BlueGreen",
          "BluePurple",
          "GoldGreen",
          "GoldOrange",
          "GoldRed",
          "GreenBlue",
          "OrangeRed",
          "PurpleBlueGreen",
          "PurpleBlue",
          "PurpleRed",
          "RedPurple",
          "YellowGreenBlue",
          "YellowGreen",
          "YellowOrangeBrown",
          "YellowOrangeRed"
        ]
      }
    },
    {
      "name": "reverse", "value": false, "bind": {"input": "checkbox"}
    }
  ],

  "data": [
    {
      "name": "temperature",
      "url": "data/seattle-temps.csv",
      "format": {"type": "csv", "parse": {"temp": "number", "date": "date"}},
      "transform": [
        {"type": "formula", "as": "hour", "expr": "hours(datum.date)"},
        { "type": "formula", "as": "day",
          "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))"}
      ]
    }
  ],

  "scales": [
    {
      "name": "x",
      "type": "time",
      "domain": {"data": "temperature", "field": "day"},
      "range": "width"
    },
    {
      "name": "y",
      "type": "band",
      "domain": [
        6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
        0, 1, 2, 3, 4, 5
      ],
      "range": "height"
    },
    {
      "name": "color",
      "type": "linear",
      "range": {"scheme": {"signal": "palette"}},
      "domain": {"data": "temperature", "field": "temp"},
      "reverse": {"signal": "reverse"},
      "zero": false, "nice": true
    }
  ],

  "axes": [
    {"orient": "bottom", "scale": "x", "domain": false, "title": "Month", "format": "%b"},
    {
      "orient": "left", "scale": "y", "domain": false, "title": "Hour",
      "encode": {
        "labels": {
          "update": {
            "text": {"signal": "datum.value === 0 ? 'Midnight' : datum.value === 12 ? 'Noon' : datum.value < 12 ? datum.value + ':00 am' : (datum.value - 12) + ':00 pm'"}
          }
        }
      }
    }
  ],

  "legends": [
    {
      "fill": "color",
      "type": "gradient",
      "title": "Avg. Temp (°F)",
      "titleFontSize": 12,
      "titlePadding": 4,
      "gradientLength": {"signal": "height - 16"}
    }
  ],

  "marks": [
    {
      "type": "rect",
      "from": {"data": "temperature"},
      "encode": {
        "enter": {
          "x": {"scale": "x", "field": "day"},
          "y": {"scale": "y", "field": "hour"},
          "width": {"value": 5},
          "height": {"scale": "y", "band": 1},
          "tooltip": {"signal": "timeFormat(datum.date, '%b %d %I:00 %p') + ': ' + datum.temp + '°'"}
        },
        "update": {
          "fill": {"scale": "color", "field": "temp"}
        }
      }
    }
  ]
}