Search code examples
visualizationvega-lite

Conditional gradient for bar graph in Vega Lite


I have some trouble changing colors based on value for gradient bars in Vega lite.

I am using the following lines that seem to work for changing the general color for the bars but not colors for the gradient:

"color": {
          "condition": [{"test": "datum['b'] < 0", "value": "red"}],
          "value": "green"
        }

This is the complete code, I have commented the section that works and the one that does not work (gradient):

Code in Vega editor

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "description": "A bar chart with negative values. We can hide the axis domain line, and instead use a conditional grid color to draw a zero baseline.",
  "data": {
    "values": [
      {"a": "A", "b": -28},
      {"a": "B", "b": 55},
      {"a": "C", "b": -33},
      {"a": "D", "b": 91},
      {"a": "E", "b": 81},
      {"a": "F", "b": 53},
      {"a": "G", "b": -19},
      {"a": "H", "b": 87},
      {"a": "I", "b": 52}
    ]
  },
  "mark": {
    "type": "bar",
    "color": {
      "x1": 1,
      "y1": 1,
      "x2": 1,
      "y2": 0,
      "gradient": "linear",
      "stops": [
        {
          "offset": 0,
          "color": {
            "condition": [{"test": "datum['b'] < 0", "value": "black"}],
            "value": "white"
          }
        },
        {"offset": 1,
         "color": {
            "condition": [{"test": "datum['b'] > 0", "value": "white"}],
            "value": "black"
          }
        }
      ]
    }
  },
  "encoding": {
    "x": {
      "field": "a",
      "type": "nominal",
      "axis": {
        "domain": false,
        "ticks": false,
        "labelAngle": 0,
        "labelPadding": 4
      }
    },
    "y": {
      "field": "b",
      "type": "quantitative",
      "axis": {
        "gridColor": {
          "condition": {"test": "datum.value === 0", "value": "black"},
          "value": "#ddd"
        }
      }
    },
    "color": {
      "condition": [{"test": "datum['b'] < 0", "value": "red"}],
      "value": "green"
    }
  }
}

What I am trying to do is to make the gradient display the same way for positive and negative values (0 = black to 10 = white and 0 = black to -10 = white).

Kind of the opposite of how it is shown in the following image

enter image description here


Solution

  • enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "description": "A bar chart with negative values. We can hide the axis domain line, and instead use a conditional grid color to draw a zero baseline.",
      "data": {
        "values": [
          {"a": "A", "b": -28},
          {"a": "B", "b": 55},
          {"a": "C", "b": -33},
          {"a": "D", "b": 91},
          {"a": "E", "b": 81},
          {"a": "F", "b": 53},
          {"a": "G", "b": -19},
          {"a": "H", "b": 87},
          {"a": "I", "b": 52}
        ]
      },
      "layer": [
        {
         "transform": [{"filter": "datum.b > 0"}],
          "mark": {
            "type": "bar",
            "color": {
              "x1": 1,
              "y1": 1,
              "x2": 1,
              "y2": 0,
              "gradient": "linear",
              "stops": [
                {
                  "offset": 0,
                  "color": "black"
                },
                {
                  "offset": 1,
                  "color":  "white"
                }
              ]
            }
          },
          "encoding": {
            "x": {
              "field": "a",
              "type": "nominal",
              "axis": {
                "domain": false,
                "ticks": false,
                "labelAngle": 0,
                "labelPadding": 4
              }
            },
            "y": {
              "field": "b",
              "type": "quantitative",
              "axis": {
                "gridColor": {
                  "condition": {"test": "datum.value === 0", "value": "black"},
                  "value": "#ddd"
                }
              }
            }
          }
        },
          {
         "transform": [{"filter": "datum.b < 0"}],
          "mark": {
            "type": "bar",
            "color": {
              "x1": 1,
              "y1": 1,
              "x2": 1,
              "y2": 0,
              "gradient": "linear",
              "stops": [
                {
                  "offset": 0,
                  "color": "white"
                },
                {
                  "offset": 1,
                  "color":  "black"
                }
              ]
            }
          },
          "encoding": {
            "x": {
              "field": "a",
              "type": "nominal",
              "axis": {
                "domain": false,
                "ticks": false,
                "labelAngle": 0,
                "labelPadding": 4
              }
            },
            "y": {
              "field": "b",
              "type": "quantitative",
              "axis": {
                "gridColor": {
                  "condition": {"test": "datum.value === 0", "value": "black"},
                  "value": "#ddd"
                }
              }
            }
          }
        }
      ]
    }