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

如何在Vega-Lite中为堆叠条形图分配自定义颜色并配置图例

问题描述

在Vega-Lite中构建了包含2个堆叠条形图、1个普通条形图及1个折线图的分层图表,遇到两个问题:

  1. 尝试通过scale与domain声明为堆叠条形图分配自定义颜色,但未达到预期效果;
  2. 希望在图例中显示Bikes Sales、Car Sales、Bike Sales LY、Car Sales LY,当前无法实现。

当前代码如下:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {
    "values": [
      {
        "Month": 1,
        "Category": "Bikes",
        "Sales": 100,
        "Sales LY": 90,
        "Target": 95,
        "Volume": 300
      },
      {
        "Month": 1,
        "Category": "Cars",
        "Sales": 560,
        "Sales LY": 800,
        "Target": 880,
        "Volume": 1200
      },
      {
        "Month": 2,
        "Category": "Bikes",
        "Sales": 130,
        "Sales LY": 170,
        "Target": 190,
        "Volume": 450
      },
      {
        "Month": 2,
        "Category": "Cars",
        "Sales": 600,
        "Sales LY": 665,
        "Target": 680,
        "Volume": 1200
      },
      {
        "Month": 3,
        "Category": "Bikes",
        "Sales": 200,
        "Sales LY": 150,
        "Target": 165,
        "Volume": 400
      },
      {
        "Month": 3,
        "Category": "Cars",
        "Sales": 750,
        "Sales LY": 1000,
        "Target": 1100,
        "Volume": 1200
      },
      {
        "Month": 4,
        "Category": "Bikes",
        "Sales": 80,
        "Sales LY": 105,
        "Target": 120,
        "Volume": 500
      },
      {
        "Month": 4,
        "Category": "Cars",
        "Sales": 800,
        "Sales LY": 600,
        "Target": 660,
        "Volume": 1200
      }
    ]
  },
    "transform": [
      {"calculate": "'Volume'", "as": "Volume Legend"},        
      {"calculate": "'Target'", "as": "Target Legend"},      
      {"calculate": "datum.Category", "as": "Category2"}             
      ],
  "height": 300,
  "width": 300,  
  "layer": [
    {
      "name": "SALES",
      "mark": {"type": "bar", "xOffset": 0, "size": 10},
      "encoding": {
        "x": {"field": "Month", "type": "ordinal", "axis": {"labelAngle": 0}},
        "y": {"field": "Sales", "type": "quantitative"},
          "color": {
        "field": "Category",             
          "type" : "nominal",          
            "scale": 
          {"domain": [ "Bikes","Cars"], "range": ["#4CD964", "#39A34B"]}
    }
      }
    },
    {
      "name": "SALES LY",
      "mark": {"type": "bar", "xOffset": -11, "size": 10},
      "encoding": {
        "x": {"field": "Month", "type": "ordinal", "axis": {"labelAngle": 0}},
        "y": {"field": "Sales LY", "type": "quantitative", "axis": null},
          "color": {
        "field": "Category2",             
          "type" : "nominal",          
            "scale": 
          {"domain": [ "Bikes","Cars"], "range": [ "#5AC8FA", "#4496BC" ]}
        }
      }
    },
    {
      "name": "TARGET",
      "mark": {"type": "bar", "xOffset": 11, "size": 10},
      "encoding": {
        "x": {"field": "Month", "type": "ordinal", "axis": {"labelAngle": 0}},
        "y": {"aggregate": "sum", "field": "Target", "type": "quantitative", "axis": null},
         "color": {        
          "field": "Target Legend",          
          "scale": { "range": ["#FFCC00" ]},
          "legend": {"title": ""}
      }}
    },
    {
      "name": "VOLUME",
      "mark": {"type": "line"},
      "encoding": {
        "x": {"field": "Month", "type": "ordinal"},
        "y": {"aggregate": "sum", "field": "Volume", "type": "quantitative"},
        "stroke": {
          "field": "Volume Legend",
          "scale": {"range": ["green"]},
          "legend": {"title": ""}
        }
      }
    }
  ],
  "resolve": {"scale": {"y": "independent"}}
}

当前效果:
current results


解决方案

核心问题分析

  1. 自定义颜色失效:每个图层单独定义颜色比例尺,导致颜色映射不统一,且未将销售类型(当前/去年)与类别关联;
  2. 图例条目缺失:未生成包含销售类型的唯一字段,无法让图例识别出Bikes Sales等目标条目。

修改方案及代码

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {
    "values": [
      {
        "Month": 1,
        "Category": "Bikes",
        "Sales": 100,
        "Sales LY": 90,
        "Target": 95,
        "Volume": 300
      },
      {
        "Month": 1,
        "Category": "Cars",
        "Sales": 560,
        "Sales LY": 800,
        "Target": 880,
        "Volume": 1200
      },
      {
        "Month": 2,
        "Category": "Bikes",
        "Sales": 130,
        "Sales LY": 170,
        "Target": 190,
        "Volume": 450
      },
      {
        "Month": 2,
        "Category": "Cars",
        "Sales": 600,
        "Sales LY": 665,
        "Target": 680,
        "Volume": 1200
      },
      {
        "Month": 3,
        "Category": "Bikes",
        "Sales": 200,
        "Sales LY": 150,
        "Target": 165,
        "Volume": 400
      },
      {
        "Month": 3,
        "Category": "Cars",
        "Sales": 750,
        "Sales LY": 1000,
        "Target": 1100,
        "Volume": 1200
      },
      {
        "Month": 4,
        "Category": "Bikes",
        "Sales": 80,
        "Sales LY": 105,
        "Target": 120,
        "Volume": 500
      },
      {
        "Month": 4,
        "Category": "Cars",
        "Sales": 800,
        "Sales LY": 600,
        "Target": 660,
        "Volume": 1200
      }
    ]
  },
  "transform": [
    {"calculate": "'Volume'", "as": "Volume Legend"},        
    {"calculate": "'Target'", "as": "Target Legend"},
    // 生成包含销售类型的类别字段,用于图例显示
    {"calculate": "datum.Category + ' Sales'", "as": "Sales Category"},
    {"calculate": "datum.Category + ' Sales LY'", "as": "Sales LY Category"}
  ],
  "height": 300,
  "width": 300,
  // 顶层定义全局统一的颜色比例尺,包含所有图例项
  "encoding": {
    "color": {
      "type": "nominal",
      "scale": {
        "domain": ["Bikes Sales", "Car Sales", "Bikes Sales LY", "Car Sales LY", "Target", "Volume"],
        "range": ["#4CD964", "#39A34B", "#5AC8FA", "#4496BC", "#FFCC00", "green"]
      }
    }
  },
  "layer": [
    {
      "name": "SALES",
      "mark": {"type": "bar", "xOffset": 0, "size": 10},
      "encoding": {
        "x": {"field": "Month", "type": "ordinal", "axis": {"labelAngle": 0}},
        "y": {"field": "Sales", "type": "quantitative"},
        "color": {"field": "Sales Category"}
      }
    },
    {
      "name": "SALES LY",
      "mark": {"type": "bar", "xOffset": -11, "size": 10},
      "encoding": {
        "x": {"field": "Month", "type": "ordinal", "axis": {"labelAngle": 0}},
        "y": {"field": "Sales LY", "type": "quantitative", "axis": null},
        "color": {"field": "Sales LY Category"}
      }
    },
    {
      "name": "TARGET",
      "mark": {"type": "bar", "xOffset": 11, "size": 10},
      "encoding": {
        "x": {"field": "Month", "type": "ordinal", "axis": {"labelAngle": 0}},
        "y": {"aggregate": "sum", "field": "Target", "type": "quantitative", "axis": null},
        "color": {"field": "Target Legend"}
      }
    },
    {
      "name": "VOLUME",
      "mark": {"type": "line"},
      "encoding": {
        "x": {"field": "Month", "type": "ordinal"},
        "y": {"aggregate": "sum", "field": "Volume", "type": "quantitative"},
        "color": {"field": "Volume Legend"}
      }
    }
  ],
  "resolve": {"scale": {"y": "independent"}}
}

修改说明

  1. 数据转换:新增Sales Category和Sales LY Category字段,将类别与销售类型组合,生成图例所需的完整名称;
  2. 全局颜色配置:在顶层encoding中定义统一的颜色映射,确保所有图层的颜色遵循同一规则,解决自定义颜色失效问题;
  3. 图层关联:各图层的color字段直接映射到生成的组合字段,自动关联全局颜色配置,图例将自动显示所有目标条目。

内容的提问来源于stack exchange,提问作者Deston

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:07:09