skip to Main Content

I have a metric and want to show a gradient color in an area chart corresponding to good (0 to .1 = green), ok (>.1 to .3 = yellow), bad (> .3 = red) for that metric at various time points. How an I make the color cut points relative to the actual scale on the y axis?

I thought I could specify the color breaks with offset and it looked correct with my first pass:

{
  "width": 600,
  "data": {
    "values": [
      {
        "__row__": 0,
        "calendar_month_year": "Dec-23",
        "concentration_risk_monthly": 0.51
      },
      {
        "__row__": 1,
        "calendar_month_year": "Jan-24",
        "concentration_risk_monthly": 0.5
      },
      {
        "__row__": 2,
        "calendar_month_year": "Feb-24",
        "concentration_risk_monthly": 0.27
      },
      {
        "__row__": 3,
        "calendar_month_year": "Mar-24",
        "concentration_risk_monthly": 0.22
      },
      {
        "__row__": 4,
        "calendar_month_year": "Apr-24",
        "concentration_risk_monthly": 0.25
      },
      {
        "__row__": 5,
        "calendar_month_year": "May-24",
        "concentration_risk_monthly": 0.22
      }
    ]
  },
  "mark": {
    "type": "area",
    "color": {
      "x1": 1,
      "y1": 1,
      "x2": 1,
      "y2": 0,
      "gradient": "linear",
      "stops": [
        {"offset": 0, "color": "#00800166"},
        {"offset": 0.3, "color": "#F7B50066"},
        {"offset": 1, "color": "#A9281F66"}
      ]
    }
  },
  "encoding": {
    "x": {
      "field": "calendar_month_year",
      "type": "ordinal",
      "sort": {"field": "__row__"},
      "axis": {"title": null},
      "scale": {"padding": 0}
    },
    "y": {
      "field": "concentration_risk_monthly",
      "type": "quantitative",
      "axis": {"title": null}
    }
  }
}

Gives:
enter image description here

But if I change the data to be below .05 for that metric (well below the .1 for green):

{
  "width": 600,
  "data": {
    "values": [
      {
        "__row__": 0,
        "calendar_month_year": "Dec-23",
        "concentration_risk_monthly": 0.051
      },
      {
        "__row__": 1,
        "calendar_month_year": "Jan-24",
        "concentration_risk_monthly": 0.05
      },
      {
        "__row__": 2,
        "calendar_month_year": "Feb-24",
        "concentration_risk_monthly": 0.027
      },
      {
        "__row__": 3,
        "calendar_month_year": "Mar-24",
        "concentration_risk_monthly": 0.022
      },
      {
        "__row__": 4,
        "calendar_month_year": "Apr-24",
        "concentration_risk_monthly": 0.025
      },
      {
        "__row__": 5,
        "calendar_month_year": "May-24",
        "concentration_risk_monthly": 0.022
      }
    ]
  },
  "mark": {
    "type": "area",
    "color": {
      "x1": 1,
      "y1": 1,
      "x2": 1,
      "y2": 0,
      "gradient": "linear",
      "stops": [
        {"offset": 0.0, "color": "#00800166"},
        {"offset": 0.3, "color": "#F7B50066"},
        {"offset": 1.0, "color": "#A9281F66"}
      ]
    }
  },
  "encoding": {
    "x": {
      "field": "calendar_month_year",
      "type": "ordinal",
      "sort": {"field": "__row__"},
      "axis": {"title": null},
      "scale": {"padding": 0}
    },
    "y": {
      "field": "concentration_risk_monthly",
      "type": "quantitative",
      "axis": {"title": null}
    }
  }
}

I’d expect the entire area to be green but it seems that the offsets are relative to the overall area and now there are still red areas even though all metrics are below .1:
enter image description here

2

Answers


  1. Try this. It isn’t working 100% and is very clunky but might be good enough for your use case.

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "width": 600,
      "data": {
        "values": [
          {
            "__row__": 0,
            "calendar_month_year": "Dec-23",
            "concentration_risk_monthly": 0.051
          },
          {
            "__row__": 1,
            "calendar_month_year": "Jan-24",
            "concentration_risk_monthly": 0.05
          },
          {
            "__row__": 2,
            "calendar_month_year": "Feb-24",
            "concentration_risk_monthly": 0.027
          },
          {
            "__row__": 3,
            "calendar_month_year": "Mar-24",
            "concentration_risk_monthly": 0.022
          },
          {
            "__row__": 4,
            "calendar_month_year": "Apr-24",
            "concentration_risk_monthly": 0.025
          },
          {
            "__row__": 5,
            "calendar_month_year": "May-24",
            "concentration_risk_monthly": 0.022
          }
        ]
      },
      "transform": [{"extent": "concentration_risk_monthly", "param": "myExtent"}],
      "mark": {
        "type": "area",
        "fill": {
          "expr": "{'gradient': 'linear', 'x1':0,'y1':1,'x2':0,'y2':0,  'stops': [{'offset': 0, 'color': scale('stroke',  myExtent[0]>1?1:myExtent[0]>0.3?0.3:0)},{'offset': 0.3, 'color':  scale('stroke', myExtent[1]>1?1:myExtent[1]>0.3?0.3:0)},{'offset': 1, 'color':  scale('stroke', myExtent[1]>=1?1:myExtent[1]>0.3?0.3:0)}]}"
        },
        "strokeOpacity": 0
      },
      "encoding": {
        "stroke": {
          "field": "1",
          "legend": null,
          "scale": {
            "type": "linear",
            "range": ["green", "yellow", "red"],
            "domain": [0, 0.3, 1]
          }
        },
        "x": {
          "field": "calendar_month_year",
          "type": "ordinal",
          "sort": {"field": "__row__"},
          "axis": {"title": null},
          "scale": {"padding": 0}
        },
        "y": {
          "field": "concentration_risk_monthly",
          "type": "quantitative",
          "axis": {"title": null}
        }
      }
    }
    
    Login or Signup to reply.
  2. Just a very minor tweak to Davide’s answer.

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "width": 600,
      "data": {
        "values": [
          {
            "__row__": 0,
            "calendar_month_year": "Dec-23",
            "concentration_risk_monthly": 0.8
          },
          {
            "__row__": 1,
            "calendar_month_year": "Jan-24",
            "concentration_risk_monthly": 0.3
          },
          {
            "__row__": 2,
            "calendar_month_year": "Feb-24",
            "concentration_risk_monthly": 0.027
          },
          {
            "__row__": 3,
            "calendar_month_year": "Mar-24",
            "concentration_risk_monthly": 0.022
          },
          {
            "__row__": 4,
            "calendar_month_year": "Apr-24",
            "concentration_risk_monthly": 0.125
          },
          {
            "__row__": 5,
            "calendar_month_year": "May-24",
            "concentration_risk_monthly": 0.022
          }
        ]
      },
      "transform": [{"extent": "concentration_risk_monthly", "param": "myExtent"}],
      "mark": {
        "type": "area",
        "fill": {
          "expr": "{'gradient': 'linear', 'x1':0,'y1':1,'x2':0,'y2':0,  'stops': [{'offset': 0, 'color': scale('stroke',  myExtent[0]>1?1:myExtent[0]>0.3?0.3:0)},{'offset': 0.3, 'color':  scale('stroke', myExtent[1]>1?1:myExtent[1]>0.3?0.3:0)},{'offset': 1, 'color':  scale('stroke', myExtent[1]>=1?1:myExtent[1]>0.3?1:0.3)}]}"
        },
        "strokeOpacity": 0
      },
      "encoding": {
        "stroke": {
          "field": "1",
          "legend": null,
          "scale": {
            "type": "linear",
            "range": ["#00800166", "#F7B50066", "#A9281F66"],
            "domain": [0, 0.3, 1]
          }
        },
        "x": {
          "field": "calendar_month_year",
          "type": "ordinal",
          "sort": {"field": "__row__"},
          "axis": {"title": null},
          "scale": {"padding": 0}
        },
        "y": {
          "field": "concentration_risk_monthly",
          "type": "quantitative",
          "axis": {"title": null}
        }
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search