You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Vega规格将线性刻度转换为等宽四分位数分段展示

问题

我有一个Vega规格,当前沿线性刻度展示一个被手动划分为四段的数值。这些分段目前以线性刻度显示,但实际上它们代表预计算的四分位数。如何修改规格,使每个分段占图表宽度的25%,并在分段内拉伸数值以适配刻度?

当前效果:
当前Vega图表

原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%宽度,同时让分数在对应分段内拉伸适配,需要做以下调整:

  1. 新增序数比例尺分配分段宽度:创建一个序数比例尺scale_segment_x,把四个分段映射到图表宽度的四个均等区间,确保每个分段占25%宽度。
  2. 计算分数的相对位置:不再直接用线性比例尺映射分数,而是先判断分数属于哪个分段,再计算该分数在分段内的相对比例,最后结合序数比例尺的分段位置得出最终x坐标。
  3. 调整分段矩形的坐标:用新的序数比例尺替代原来的线性比例尺,确定每个分段的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:07:17