使用合并值制作维加热图

Make a vega heatmap with means of binned values

让我们从这个例子开始:

https://vega.github.io/vega/examples/heatmap/

这是底层数据的一瞥:

date    pressure    temperature wind
2010-01-01T01:00:00 1016.6  4   3.8
2010-01-01T02:00:00 1016.6  3.9 3.8
2010-01-01T03:00:00 1016.7  3.8 3.8
2010-01-01T04:00:00 1016.7  3.8 3.7
2010-01-01T05:00:00 1016.5  3.7 3.8
2010-01-01T06:00:00 1016.4  3.7 3.8

在上图中,热图中每个单元格的颜色代表数据 table.

中单行的 temperature 的值

假设我们要更改显示方式,使热图中每个单元格的颜色代表数据 多行 的平均值 table?

例如,假设我们要对 x 轴和 y 轴都应用分箱。

对于 y 轴,我们将创建 3 个 bin:

对于 x 轴,我们将创建 12 个 bin:

然后,热图将有 3 行和 12 列,并且热图中每个单元格的颜色将对应于相应 bin 中温度值的平均值。

问题:

  1. 你会如何用 vega 做这个?我们可以使用 transform 来完成这个任务吗?

  2. 我们是否应该使用另一个 javascript 库先进行分箱,然后将结果传递给 vega?

  3. 您能否分享一个代码片段或推荐一个用于高效二维分箱的库(例如,对于具有连续 x、y 位置的一百万个项目)?

  4. 假设某些 bin 对应于无数据(数据中的 0 行 table)。我们可以完全跳过绘制它们吗?或者用背景颜色给它们上色?

感谢您的帮助!

您可以使用变换 calculate 使用三元条件将它们分组到您的波段中并创建一个新字段作为 timeGroup 然后在您的 y 轴中使用它,如下所示或在

在编辑器中试试:link

这是数字:

代码如下:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "autosize": {"contains": "padding", "type": "fit", "resize": true},
  "width": 600,
  "height": 150,
  "padding": {"left": 15, "right": 60, "bottom": 5},
  "data": {
    "url": "data/seattle-weather-hourly-normals.csv",
    "format": {"type": "csv", "parse": {"date": "date"}}
  },
  "transform": [
    {"calculate": "month(datum.date)", "as": "cvDate"},
    {"calculate": "utchours(datum.date)", "as": "hoursDate"},
    {
      "calculate": "0 < datum.hoursDate && datum.hoursDate < 7 ? '1 am - 6 am': 6 < datum.hoursDate && datum.hoursDate < 13 ? '7 am - 12 pm' : 12 < datum.hoursDate && datum.hoursDate < 19 ? '1 pm - 6 pm': '7 pm - 12 am'",
      "as": "timeGroup"
    },
    {
      "calculate": "datum.timeGroup == '1 am - 6 am' ? 0 : datum.timeGroup == '7 am - 12 pm' ? 1 : datum.timeGroup == '1 pm - 6 pm' ? 2 : 3",
      "as": "orderRank"
    }
  ],
  "encoding": {
    "y": {
      "field": "timeGroup",
      "type": "ordinal",
      "sort": {"field": "orderRank", "order": "descending"}
    },
    "x": {
      "field": "date",
      "type": "ordinal",
      "timeUnit": "month",
      "sort": null
    }
  },
  "layer": [
    {
      "mark": {"type": "rect"},
      "encoding": {
        "fill": {
          "field": "temperature", "type": "quantitative",
          "aggregate": "mean"
        }
      }
    }
  ]
}

再次查看 vega-lite 文档后,我认为我偶然发现了一个看起来不错的答案。

在编辑器中试试:link

这是数字:

代码:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {"url": "data/movies.json"},
  "transform": [
    {
      "filter": {
        "and": [
          {"field": "IMDB Rating", "valid": true},
          {"field": "Rotten Tomatoes Rating", "valid": true}
        ]
      }
    }
  ],
  "mark": "rect",
  "width": 300,
  "height": 200,
  "encoding": {
    "x": {
      "bin": {"maxbins": 60},
      "field": "IMDB Rating",
      "type": "quantitative"
    },
    "y": {
      "bin": {"maxbins": 40},
      "field": "Rotten Tomatoes Rating",
      "type": "quantitative"
    },
    "color": {
      "aggregate": "mean",
      "field": "Worldwide Gross",
      "type": "quantitative"
    }
  },
  "config": {"view": {"stroke": "transparent"}}
}

以及 link 关于如何使用 "aggregate" 的文档:

https://vega.github.io/vega-lite/docs/aggregate.html#aggregate-op-def