【问题标题】:Make a vega heatmap with means of binned values使用分箱值制作 vega 热图
【发布时间】:2021-06-16 16:59:09
【问题描述】:

让我们从这个例子开始:

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

上图中,热图中每个单元格的颜色代表了数据表中单行中temperature的值。

假设我们要改变显示,让热图中每个单元格的颜色代表数据表中多行的平均值

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

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

  • 6am-11am、12pm-6pm、7pm-12am

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

  • 每个月一个垃圾箱

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

问题:

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

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

  3. 您能否分享一个代码 sn-p 或建议一个用于高效 2d 分箱的库(例如,对于具有连续 x、y 位置的一百万个项目)?

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

感谢您的帮助!

【问题讨论】:

  • 你是在问如何在 Vega 或 Vega-Lite 中做到这一点?
  • 杰克,我还在学习,所以任何关于如何使用 vega 或 vega-lite 来解决这个问题的技巧都会很棒!在这种情况下,您认为哪一种更合适?

标签: javascript data-visualization vega-lite vega


【解决方案1】:

您可以使用转换 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"
        }
      }
    }
  ]
}

【讨论】:

  • 谢谢!我认为这个答案中唯一缺少的可能是平均值,但我们可以像这样添加它: {"aggregate": "mean", "field": "temperature", "type": "quantitative"}
  • 您可以根据需要添加添加内容,但问题是如何创建具有“上午 6 点 - 上午 11 点”等组的垃圾箱。所以我的答案就是这个。
【解决方案2】:

再次查看 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"}}
}

还有关于如何使用"aggregate"的文档链接:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 2020-07-02
    • 2021-08-09
    • 2017-05-08
    相关资源
    最近更新 更多