[英]How to make a chart with SVG marker whose size increases in only one aspect or show a custom SVG marker for each data point in Vega/Vega-Lite?
I want to make a chart that has "spikes" as markers.我想制作一个以“尖峰”为标记的图表。 And to denote the "severity" or the "quantitative" nature of the data, I want to scale the "spikes" longer but NOT wider.
为了表示数据的“严重性”或“定量”性质,我想将“尖峰”缩放得更长但不更宽。 Currently, when I use the
size
encoding it increases the area of the "spike", which is undesirable.目前,当我使用
size
编码时,它会增加“尖峰”的面积,这是不可取的。 I used "aspect": false
too but the results did not change -我也使用了
"aspect": false
但结果没有改变 -
Vega-Lite Spec Vega-Lite 规格
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "A simple bar chart with embedded data.",
"data": {
"values": [
{"a": "A", "b": 28}, {"a": "B", "b": 55}, {"a": "C", "b": 43},
{"a": "D", "b": 91}, {"a": "E", "b": 81}, {"a": "F", "b": 53},
{"a": "G", "b": 19}, {"a": "H", "b": 87}, {"a": "I", "b": 52}
]
},
"mark": {"type": "point", "shape":"M -1 0 L0 -10 L1 0", "fill": "red", "opacity": 0.5, "stroke": "black", "strokeOpacity": 1 },
"encoding": {
"x": {"field": "a", "type": "ordinal"},
"y": {"field": "b", "type": "quantitative"},
"size": {"field": "b", "type": "quantitative"}
}
}
Then I thought that maybe I can specify shape
as an encoding and provide custom SVG that only changes in height, as PATH value to the data itself and pass that in the shape encoding.然后我想也许我可以将
shape
指定为编码并提供仅高度变化的自定义 SVG,作为数据本身的 PATH 值并将其传递给形状编码。 But of course that didn't work.但这当然没有用。 Vega-Lite assigned its own shapes -
Vega-Lite 分配了自己的形状 -
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "A simple bar chart with embedded data.",
"data": {
"values": [
{"a": "A", "b": 28, "c":"M -1 0 L0 -10 L1 0"}, {"a": "B", "b": 55, "c":"M -1 0 L0 -5 L1 0"}, {"a": "C", "b": 43, "c":"M -1 0 L0 -20 L1 0"},
{"a": "D", "b": 91, "c":"M -1 0 L0 -1 L1 0"}
]
},
"mark": {"type": "point", "fill": "red", "opacity": 0.5, "stroke": "black", "strokeOpacity": 1 },
"encoding": {
"x": {"field": "a", "type": "ordinal"},
"y": {"field": "b", "type": "quantitative"},
"shape": {"field": "c", "type": "quantitative"}
}
}
I also played around with url
encoding in point
mark as well as image
mark, but they did not yield anything.我还在
point
标记和image
标记中使用了url
编码,但它们没有产生任何结果。
I saw Path Mark in Vega, which may be useful but I do not see it in Vega-Lite.我在 Vega 中看到了Path Mark ,这可能很有用,但我在 Vega-Lite 中看不到它。 If it can somehow be used then that is fine too.
如果它可以以某种方式使用,那也很好。
Any idea how do I make this happen?知道如何实现这一点吗?
Main idea is to have the width of the marker same, but scale the height.主要思想是使标记的宽度相同,但缩放高度。 I don't mind doing it via encoding channels or arguments/parameters or specifying an SVG PATH for each data point, either way is fine.
我不介意通过编码通道或参数/参数或为每个数据点指定 SVG PATH 来实现,无论哪种方式都可以。
After fiddling with vega, I got around to the following -在摆弄 vega 之后,我得到了以下内容 -
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A simple bar chart with embedded data.",
"background": "white",
"padding": 5,
"height": 700,
"style": "cell",
"data": [
{
"name": "source_0",
"values": [
{"a": "A", "b": 1.5, "c": 0},
{"a": "B", "b": 0.5, "c": 0},
{"a": "C", "b": 10, "c": 0},
{"a": "D", "b": 1, "c": 0}
]
},
{
"name": "data_0",
"source": "source_0",
"transform": [
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
}
]
}
],
"signals": [
{"name": "x_step", "value": 20},
{
"name": "width",
"update": "bandspace(domain('x').length, 1, 0.5) * x_step"
}
],
"marks": [
{
"name": "marks",
"type": "symbol",
"style": ["path"],
"from": {"data": "data_0"},
"encode": {
"update": {
"opacity": {"value": 0.7},
"fill": {"value": "red"},
"stroke": {"value": "red"},
"strokeOpacity": {"value": 1},
"strokeWidth": {"value": 0.25},
"shape": {"value": "M -1 0 L0 -10 L1 0 Z"},
"ariaRoleDescription": {"value": "point"},
"description": {
"signal": "\"a\" + \": \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; \" + \"b\" + \": \" + (format(datum[\"b\"], \"\"))"
},
"x": {"scale": "x", "field": "a"},
"y": {"scale": "y", "field": "c"},
"scaleY": {"field": "b", "type": "quantitative"}
}
}
}
],
"scales": [
{
"name": "x",
"type": "point",
"domain": {"data": "data_0", "field": "a", "sort": true},
"range": {"step": {"signal": "x_step"}},
"padding": 0.5
},
{
"name": "y",
"type": "linear",
"domain": {"data": "data_0", "field": "b"},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
},
{
"name": "size",
"type": "linear",
"domain": {"data": "data_0", "field": "b"},
"range": [0, 361],
"zero": true
}
],
"axes": [
{
"scale": "y",
"orient": "left",
"gridScale": "x",
"grid": true,
"tickCount": {"signal": "ceil(height/40)"},
"domain": false,
"labels": false,
"aria": false,
"maxExtent": 0,
"minExtent": 0,
"ticks": false,
"zindex": 0
},
{
"scale": "x",
"orient": "bottom",
"grid": false,
"title": "a",
"labelAlign": "right",
"labelAngle": 270,
"labelBaseline": "middle",
"labelOverlap": true,
"zindex": 0
},
{
"scale": "y",
"orient": "left",
"grid": false,
"title": "b",
"labelOverlap": true,
"tickCount": {"signal": "ceil(height/40)"},
"zindex": 0
}
]
}
I tried to convert this to Vega-Lite but it doesn't seem to work -我试图将其转换为 Vega-Lite,但它似乎不起作用 -
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "A simple bar chart with embedded data.",
"data": {
"values": [
{"a": "A", "b": 2}, {"a": "B", "b": 5}, {"a": "C", "b": 4},
{"a": "D", "b": 9}
]
},
"mark": {"type": "point", "shape":"M -1 0 L0 -10 L1 0", "fill": "red", "opacity": 0.5, "stroke": "black", "strokeOpacity": 1 },
"encoding": {
"x": {"field": "a", "type": "ordinal", "axis": {"labelAngle": 0}},
"y": {"field": "b", "type": "quantitative"},
"scaleY": {"field": "b", "type": "quantitative"}
}
}
Error错误
Property scaleY is not allowed.
Your second approach, of providing the SVG path in the shape
encoding, will work if you set the scale
to null
( open in editor ):如果您将
scale
设置为null
( 在编辑器中打开),则第二种方法(在shape
编码中提供 SVG 路径)将起作用:
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "A simple bar chart with embedded data.",
"data": {
"values": [
{"a": "A", "b": 28, "c":"M -1 0 L0 -10 L1 0"},
{"a": "B", "b": 55, "c":"M -1 0 L0 -5 L1 0"},
{"a": "C", "b": 43, "c":"M -1 0 L0 -20 L1 0"},
{"a": "D", "b": 91, "c":"M -1 0 L0 -1 L1 0"}
]
},
"mark": {"type": "point", "fill": "red", "opacity": 0.5, "stroke": "black", "strokeOpacity": 1 },
"encoding": {
"x": {"field": "a", "type": "ordinal"},
"y": {"field": "b", "type": "quantitative"},
"shape": {"field": "c", "type": "quantitative", "scale": null}
}
}
Vega-Lite does not provide the equivalent of Vega's ScaleY
encoding, so if you want that approach you will have to work in Vega directly. Vega-Lite 不提供与 Vega 的
ScaleY
编码等效的功能,因此如果您想要这种方法,则必须直接在 Vega 中工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.