Search code examples
vega-litevega

Conditionally define color channel on multi-line graph


I have a graph with two lines, I want the option to toggle a param to combine the two lines into one.

Vega-lite allows you to encode a field with a condition, but I can't seem to "define nothing" if the condition fails. I can give a value: red but that just sets both lines to the same color, or value: false/null which removes the lines entirely.

The condition docs describe the "else" fields as optional, but without any value or field I never see two lines -- which seems like the channel is never defined.

Eg, I have this graph:

And when I toggle the "combine" checkbox, I would like to get this (the same effect as simply not defining a 'color' channel):

Instead I get this:

enter image description here

Example spec for use on https://vega.github.io/editor/

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {
    "values": [
      {"y": -1, "x": 1, "name": "north"},
      {"y": 2, "x": 2, "name": "north"},
      {"y": 0, "x": 3, "name": "north"},
      {"y": -3, "x": 1, "name": "south"},
      {"y": 1, "x": 2, "name": "south"},
      {"y": 4, "x": 3, "name": "south"}
    ]
  },
  "encoding": {
    "color": {
      "condition": {"param": "combine", "field": "name"},
      "value": "red",
    },
    "x": {"field": "x", "type": "quantitative"},
    "y": {
      "aggregate": "median",
      "field": "y",
      "scale": {"domain": [-10, 10]},
      "type": "quantitative"
    }
  },
  "height": "container",
  "layer": [{"mark": {"interpolate": "basis", "type": "line"}}],
  "params": [
    {
      "bind": {"input": "checkbox"},
      "name": "combine",
      "value": "Yes"
    }
  ],
  "width": 300
}

Solution

  • Best I can do.

    enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "data": {
        "values": [
          {"y": -1, "x": 1, "name": "north"},
          {"y": 2, "x": 2, "name": "north"},
          {"y": 0, "x": 3, "name": "north"},
          {"y": -3, "x": 1, "name": "south"},
          {"y": 1, "x": 2, "name": "south"},
          {"y": 4, "x": 3, "name": "south"}
        ]
      },
      "encoding": {
        "x": {"field": "x", "type": "quantitative"},
        "y": {
          "aggregate": "median",
          "field": "y",
          "scale": {"domain": [-10, 10]},
          "type": "quantitative"
        }
      },
      "height": "container",
      "layer": [
        {
          "transform": [{"filter": "combine?true:false"}],
          "mark": {"interpolate": "basis", "type": "line"},
          "encoding": {"color": {"field": "name"}}
        },
        {
          "transform": [{"filter": "combine?false:true"}],
          "mark": {
            "interpolate": "basis",
            "type": "line",
            "color": "red"
          }
        }
      ],
      "params": [{"bind": {"input": "checkbox"}, "name": "combine", "value": true}],
      "width": 300
    }