Plot: Legend and Dynamic Fill Issue

Is it possible to have a domain/range-based Plot Legend when the fill attribute for an overlapping barX Mark is utilized?

See: Plot Issue / Mario Delgado / Observable and toggle the ‘Legend Object’ radio input for an example.

When fill is a constant color (your first bar), it can be specified as a css color (“green”).

However a dynamic color (your second bar), will pass through the color scale if it exists. If that scale has a domain, each of the colors is going to be compared to the domain, and the mark will not be drawn if its value is not in the domain (“red” or “blue”).

A solution could be something like

  color: {
    legend: true,
    domain: ["Expense<50", "Expense+50"],
    range: ["blue", "red"]
  marks: [
    Plot.barX(data, {
      x: "Income",
      y: "Year",
      fill: "green"
    Plot.barX(data, {
      x: "Expense",
      y: "Year",
      // Dynamic fill
      fill: (d) => (d.Expense < 50 ? "Expense<50" : "Expense+50")


Your recommendation addressed the Legend, but the dynamic bar fill value is not assigned by Plot:

See updated notebook: Plot Issue / Mario Delgado / Observable

It’s because the second bar mark uses the fixed data variable, instead of the value set by the slider.

1 Like