使用合并值制作维加热图
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:
- 上午 6 点至上午 11 点,中午 2 点至下午 6 点,晚上 7 点至凌晨 12 点
对于 x 轴,我们将创建 12 个 bin:
- 每个月一个垃圾桶
然后,热图将有 3 行和 12 列,并且热图中每个单元格的颜色将对应于相应 bin 中温度值的平均值。
问题:
你会如何用 vega 做这个?我们可以使用 transform
来完成这个任务吗?
我们是否应该使用另一个 javascript 库先进行分箱,然后将结果传递给 vega?
您能否分享一个代码片段或推荐一个用于高效二维分箱的库(例如,对于具有连续 x、y 位置的一百万个项目)?
假设某些 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
让我们从这个例子开始:
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:
- 上午 6 点至上午 11 点,中午 2 点至下午 6 点,晚上 7 点至凌晨 12 点
对于 x 轴,我们将创建 12 个 bin:
- 每个月一个垃圾桶
然后,热图将有 3 行和 12 列,并且热图中每个单元格的颜色将对应于相应 bin 中温度值的平均值。
问题:
你会如何用 vega 做这个?我们可以使用
transform
来完成这个任务吗?我们是否应该使用另一个 javascript 库先进行分箱,然后将结果传递给 vega?
您能否分享一个代码片段或推荐一个用于高效二维分箱的库(例如,对于具有连续 x、y 位置的一百万个项目)?
假设某些 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