如何修改Vega规格将线性刻度转换为等宽四分位数分段展示
问题
我有一个Vega规格,当前沿线性刻度展示一个被手动划分为四段的数值。这些分段目前以线性刻度显示,但实际上它们代表预计算的四分位数。如何修改规格,使每个分段占图表宽度的25%,并在分段内拉伸数值以适配刻度?
当前效果:
原Vega规格:
{ "$schema": "https://vega.github.io/schema/vega/v5.json", "description": "Chart showing nesting score for selected location.", "width": 294, "height": 16, "padding": 0, "data": [ { "name": "data_segments", "values": [ {"segmentLabel": "min", "segmentStart": 0, "segmentEnd": 26.3}, {"segmentLabel": "low", "segmentStart": 26.3, "segmentEnd": 42.9}, {"segmentLabel": "mid", "segmentStart": 42.9, "segmentEnd": 54.8}, {"segmentLabel": "high", "segmentStart": 54.8, "segmentEnd": 70.7} ] } ], "signals": [ {"name": "signal_score", "value": "38"} ], "scales": [ { "name": "scale_x", "type": "linear", "domain": { "data": "data_segments", "fields": ["segmentStart", "segmentEnd"] }, "range": "width", "padding": 0.05, "round": true }, {"name": "scale_y", "domain": [0, 1], "range": "height"}, { "name": "scale_segment_color", "type": "ordinal", "domain": ["min", "low", "mid", "high"], "range": ["#f6eff7", "#bdc9e1", "#67a9cf", "#02818a"] } ], "marks": [ { "type": "rect", "from": {"data": "data_segments"}, "encode": { "enter": { "x": {"scale": "scale_x", "field": "segmentStart"}, "x2": {"scale": "scale_x", "field": "segmentEnd"}, "y": {"scale": "scale_y", "value": 0.1}, "y2": {"scale": "scale_y", "value": 0.9}, "fill": {"scale": "scale_segment_color", "field": "segmentLabel"}, "stroke": {"value": "white"} } } }, { "type": "rect", "from": {"data": "data_segments"}, "encode": { "update": { "x": {"signal": "scale('scale_x', signal_score) - 3"}, "x2": {"signal": "scale('scale_x', signal_score) + 3"}, "y": {"scale": "scale_y", "value": 0}, "y2": {"scale": "scale_y", "value": 1}, "fill": {"value": "white"}, "stroke": {"value": "grey"}, "tooltip": {"signal": "signal_score"} } } } ] }
修改方案
要让每个四分位段占25%宽度,同时让分数在对应分段内拉伸适配,需要做以下调整:
- 新增序数比例尺分配分段宽度:创建一个序数比例尺
scale_segment_x,把四个分段映射到图表宽度的四个均等区间,确保每个分段占25%宽度。 - 计算分数的相对位置:不再直接用线性比例尺映射分数,而是先判断分数属于哪个分段,再计算该分数在分段内的相对比例,最后结合序数比例尺的分段位置得出最终x坐标。
- 调整分段矩形的坐标:用新的序数比例尺替代原来的线性比例尺,确定每个分段的x和x2位置。
修改后的完整Vega规格:
{ "$schema": "https://vega.github.io/schema/vega/v5.json", "description": "Chart showing nesting score for selected location with equal quartile segments.", "width": 294, "height": 16, "padding": 0, "data": [ { "name": "data_segments", "values": [ {"segmentLabel": "min", "segmentStart": 0, "segmentEnd": 26.3}, {"segmentLabel": "low", "segmentStart": 26.3, "segmentEnd": 42.9}, {"segmentLabel": "mid", "segmentStart": 42.9, "segmentEnd": 54.8}, {"segmentLabel": "high", "segmentStart": 54.8, "segmentEnd": 70.7} ] }, // 筛选当前分数所属的分段 { "name": "score_segment", "source": "data_segments", "transform": [ {"filter": "datum.segmentStart <= signal_score && signal_score <= datum.segmentEnd"} ] } ], "signals": [ {"name": "signal_score", "value": 38} ], "scales": [ // 序数比例尺,分配每个分段25%宽度 { "name": "scale_segment_x", "type": "ordinal", "domain": {"data": "data_segments", "field": "segmentLabel"}, "range": "width", "padding": 0, "round": true }, {"name": "scale_y", "domain": [0, 1], "range": "height"}, { "name": "scale_segment_color", "type": "ordinal", "domain": ["min", "low", "mid", "high"], "range": ["#f6eff7", "#bdc9e1", "#67a9cf", "#02818a"] } ], "marks": [ { "type": "rect", "from": {"data": "data_segments"}, "encode": { "enter": { // 用序数比例尺确定分段的起始和结束位置 "x": {"scale": "scale_segment_x", "field": "segmentLabel"}, "x2": {"signal": "scale('scale_segment_x', datum.segmentLabel) + width/4"}, "y": {"scale": "scale_y", "value": 0.1}, "y2": {"scale": "scale_y", "value": 0.9}, "fill": {"scale": "scale_segment_color", "field": "segmentLabel"}, "stroke": {"value": "white"} } } }, { "type": "rect", "from": {"data": "score_segment"}, "encode": { "update": { // 计算分数在分段内的相对位置,结合分段起始坐标得到最终位置 "x": {"signal": "scale('scale_segment_x', datum.segmentLabel) + (width/4) * ((signal_score - datum.segmentStart)/(datum.segmentEnd - datum.segmentStart)) - 3"}, "x2": {"signal": "scale('scale_segment_x', datum.segmentLabel) + (width/4) * ((signal_score - datum.segmentStart)/(datum.segmentEnd - datum.segmentStart)) + 3"}, "y": {"scale": "scale_y", "value": 0}, "y2": {"scale": "scale_y", "value": 1}, "fill": {"value": "white"}, "stroke": {"value": "grey"}, "tooltip": {"signal": "signal_score"} } } } ] }
说明
- 新增的
score_segment数据会自动筛选出当前分数所属的分段,用于计算相对位置 scale_segment_x序数比例尺确保每个分段占据width/4的宽度(即25%)- 分数的x坐标通过
(分数 - 分段起始)/(分段结束 - 分段起始)计算相对比例,再乘以分段宽度并加上分段起始x坐标得到,实现了分段内的拉伸适配
内容的提问来源于stack exchange,提问作者Dave McLaughlin
相关产品推荐
相关产品推荐

