Контурная диаграмма
Контурная диаграмма показывает плотность точек данных несколькими уровнями. Как и изолинии на топографической карте, каждая граница контура соответствует постоянной плотности. Преобразование kde2d выполняет ядерную оценку плотности, создавая непрерывное приближение плотности выборки для каждой группы. Преобразование heatmap создаёт тепловые карты по этим оценкам, а isocontour строит контуры уровней в виде полигонов GeoJSON.
Спецификация Vega в JSON <>
{
"$schema": "https://vega.github.io/schema/vega/v6.json",
"description": "Контурная диаграмма с оценкой плотности поверх точек рассеяния.",
"width": 500,
"height": 400,
"padding": 5,
"autosize": "pad",
"signals": [
{
"name": "bandwidth", "value": -1,
"bind": {"name": "Ширина окна", "input": "range", "min": -1, "max": 100, "step": 1}
},
{
"name": "resolve", "value": "shared",
"bind": {"name": "Способ расчёта", "input": "select", "options": ["independent", "shared"], "labels": ["Независимо", "Совместно"]}
},
{
"name": "counts", "value": true,
"bind": {"name": "Показывать частоты", "input": "checkbox"}
}
],
"data": [
{
"name": "source",
"url": "data/cars.json",
"transform": [
{
"type": "filter",
"expr": "datum.Horsepower != null && datum.Miles_per_Gallon != null"
}
]
},
{
"name": "density",
"source": "source",
"transform": [
{
"type": "kde2d",
"groupby": ["Origin"],
"size": [{"signal": "width"}, {"signal": "height"}],
"x": {"expr": "scale('x', datum.Horsepower)"},
"y": {"expr": "scale('y', datum.Miles_per_Gallon)"},
"bandwidth": {"signal": "[bandwidth, bandwidth]"},
"counts": {"signal": "counts"}
}
]
},
{
"name": "contours",
"source": "density",
"transform": [
{
"type": "isocontour",
"field": "grid",
"resolve": {"signal": "resolve"},
"levels": 3
}
]
}
],
"scales": [
{
"name": "x",
"type": "linear",
"round": true,
"nice": true,
"zero": true,
"domain": {"data": "source", "field": "Horsepower"},
"range": "width"
},
{
"name": "y",
"type": "linear",
"round": true,
"nice": true,
"zero": true,
"domain": {"data": "source", "field": "Miles_per_Gallon"},
"range": "height"
},
{
"name": "color",
"type": "ordinal",
"domain": {
"data": "source", "field": "Origin",
"sort": {"order": "descending"}
},
"range": "category"
}
],
"axes": [
{
"scale": "x",
"grid": true,
"domain": false,
"orient": "bottom",
"tickCount": 5,
"title": "Мощность (л. с.)"
},
{
"scale": "y",
"grid": true,
"domain": false,
"orient": "left",
"titlePadding": 5,
"title": "Миль на галлон"
}
],
"legends": [
{"stroke": "color", "symbolType": "stroke"}
],
"marks": [
{
"name": "marks",
"type": "symbol",
"from": {"data": "source"},
"encode": {
"update": {
"x": {"scale": "x", "field": "Horsepower"},
"y": {"scale": "y", "field": "Miles_per_Gallon"},
"size": {"value": 4},
"fill": {"value": "#ccc"}
}
}
},
{
"type": "image",
"from": {"data": "density"},
"encode": {
"update": {
"x": {"value": 0},
"y": {"value": 0},
"width": {"signal": "width"},
"height": {"signal": "height"},
"aspect": {"value": false}
}
},
"transform": [
{
"type": "heatmap",
"field": "datum.grid",
"resolve": {"signal": "resolve"},
"color": {"expr": "scale('color', datum.datum.Origin)"}
}
]
},
{
"type": "path",
"clip": true,
"from": {"data": "contours"},
"encode": {
"enter": {
"strokeWidth": {"value": 1},
"strokeOpacity": {"value": 1},
"stroke": {"scale": "color", "field": "Origin"}
}
},
"transform": [
{ "type": "geopath", "field": "datum.contour" }
]
}
]
}