vega / vega

A visualization grammar.
https://vega.github.io/vega
BSD 3-Clause "New" or "Revised" License
11.17k stars 1.5k forks source link

Marks do not show when `domain()` is used with an ordinal scale range #3959

Open joelostblom opened 1 month ago

joelostblom commented 1 month ago

I'm working on https://github.com/vega/altair/pull/3394 and have encountered an issue where it seems like computed domains (e.g. a parameter with "update": "domain('color')") do not work with ordinal scale ranges in Vega. The minimal Vega-Lite spec for this is rather concise but leads to a quite large Vega spec. The issue is that with an ordinal range the marks do not show up in the legend or the chart.

image

If I change the color scale's range to 'category' instead of 'ordinal' (or the name of any categorical color scheme) then the chart data points will show up as expected (but remain unordered):

image

This is the part of the code I'm changing:

{
  "name": "color",
  "type": "ordinal",
  "domain": {"signal": "param_24"},
  "range": "category"
  // "range": "ordinal" // Does not work
}

There are no warnings in the console, so I'm not sure how to start troubleshooting this. Any ideas of what is going on?

PBI-David commented 1 month ago

Is there not some circular logic going on in your VL spec?

You're setting up the color encoding with param66 which refers to param 65 which refers to the scale domain for color which refers to param66 (i.e. a full circle)

param66 is undefined and param65 is an empty array. Removing the scale works:


{
  "data": {
    "url": "https://cdn.jsdelivr.net/npm/vega-datasets@v1.29.0/data/cars.json"
  },
  "mark": {"type": "point"},
  "encoding": {
    "color": {
      "field": "Cylinders",
      "type": "ordinal"
    },
    "x": {"field": "Horsepower", "type": "quantitative"},
    "y": {"field": "Miles_per_Gallon", "type": "quantitative"}
  },
  "params": [
    {
      "name": "param_64",
      "select": {"type": "point", "encodings": ["color"]},
      "bind": "legend"
    },
    {"name": "param_65", "expr": "domain('color')"},
    {"name": "param_66", "expr": "param_65", "react": false}
  ],
  "$schema": "https://vega.github.io/schema/vega-lite/v5.20.1.json"
}

image

joelostblom commented 1 month ago

Thanks for the quick reply! I don't think there is any circular logic since I have set react: false. My understanding is that param65 will compute the color domain on the first chart load; then this value will be read by param66 which is non-reactive and thus does not update even when the color domain changes. If I set react: true it would be circular which is also detected by the Vega editor that raises the error: Cycle detected in dataflow graph.

Unfortunately I need to set a constant domain for the scale because in https://github.com/vega/altair/pull/3394 we want to keep the values in the legend constant when clicking it to filter out groups of data. This is another reason for the non-reactive parameter, we don't want the legend to update as the data is filtered out (see more detailed discussion in that PR). I'm open to other ways of doing this, but so far it seems the most promising to set a constant domain.