Cezembre
Cezembre

Reputation: 13

Ordinal Scale used unexpected colors when there are duplicates in the range in Vega

I have a table with 2 columns : country and color. Each country is unique, while one color can be associated with one or more countries : Below lightblue is associated with Italy and Spain.

 "data": [
    { "name": "myTable",
      "values":[
        {"country":"BE_blue", "color":"blue"},
        {"country":"FR_red", "color":"red"},
        {"country":"IT_lightblue", "color":"lightblue"},
        {"country":"GB_yellow", "color":"yellow"},
        {"country":"DE_green", "color":"green"},
        {"country":"ES_lightblue", "color":"lightblue"},
        {"country":"NL_black", "color":"black"},
        {"country":"AT_pink", "color":"pink"}
      ]
    }
  ],

In my Vega graph, I want to display a legend that shows the color for each country. So I have defined an ordinal scale whose Domain is based on the country column and range is based on the color column of my table. Then I have created a Legend whose fill attribute is linked to this scale.

  "scales": [
    { "name":"myScale",
      "type":"ordinal",
      "domain":{"data": "myTable", "field":"country"},
      "range":{"data": "myTable", "field":"color"}
    }
  ],

  "legends": [
    { "type":"symbol",
      "fill": "myScale"
    }
  ]

Problem : The legend does not display the colors correctly in front of each contry : In the below screenshot we see that AT is marked as blue instead of pink, NL is marked as pink instead as black ... etc.

enter image description here

I have created 2 signals to see the domain and range of my scale :

  "signals": [
    { "name": "myScale_range",
      "update": "range('myScale')"
    },
    { "name": "myScale_domain",
      "update": "domain('myScale')"
    }
  ],

Here is the value of these 2 signals :

myScale_domain : ["BE_blue","FR_red","IT_lightblue","GB_yellow","DE_green","ES_lightblue","NL_black","AT_pink"]
myScale_range : ["blue","red","lightblue","yellow","green","black","pink"]

The signal myScale_domain contains 8 countries, while signal myScale_range contains 7 colors ! One color is missing in the range : The lightblue color that was present twice in the source table is only present once in the range of the scale. I assume it is the reason of the problem in the legend.

How can I fix this ? Do I miss something or is there an issue in Vega ?

Thanks for you help

Upvotes: 1

Views: 20

Answers (1)

Cameron Yick
Cameron Yick

Reputation: 750

For discrete rather than continuous scales, the domain and range must be the same length to get your intended result. From the Vega-Lite docs:

Note: This (Setting Color Range based on a Field) only works if there is a 1:1 mapping between the color domain field (l) and the range field (c).

Since you already have the colors in your data, there is no need for a scale, we can reference the color field directly. We do this by setting scale: null, there is no need to create myScale.

This is easiest to see with a Vega-Lite encoding rather than Vega:

  "encoding": {
    "x": {"field": "country", "type": "nominal" },
    "y": {"field": "country", "type": "nominal"},
    "color": {"field": "color", "type": "nominal", "scale": null}
  }

Here's an example graph using the provided data

color coded graph of countries

Upvotes: 0

Related Questions