Force order on fill option of a plot

Hi there,

I’m looking for some guidance on specifying the display/plot order of the fill option on a plot.

For example, consider the following chart,

Plot.plot({
  marks: [
    Plot.barY(data,{
        x: "x_value",
        y: "y_value",
        fill: "fill_value"
      }
    )
  ]
})

I’m not entirely sure how OJS decides the order that the fill will plot itself in a shared bar chart, but what if I want to have it be specific?

Let’s assume that data.fill_value = ["A","B","C"]. The order it is plotted in the bar has a default that I want to override so that maybe “C” is plotted on the bottom of the bar.

Hopefully this is enough to go on without building a notebook, but I’m open to learning how to do that if more context is needed.

Let’s say in your example, you have:

  • A: red
  • B: green
  • C: blue

as default, but you want to reverse this and use

  • A: blue
  • B: green
    *C: red

instead?

If so, you can do this by passing in color: {domain: ["C", "B", "A"]} to adjust color scale.

E.g. adjusted from the out of box Histogram example
image

color domain

Thanks for the quick response! This indeed works on example data, however, I seem to have a couple of categories that refuse to follow my domain. Here is an example of the code I have written,

Plot.plot({
  // Plot area config
  insetLeft: 0,
  insetRight: 0,
  
  // Configure the x-axis
  x: {
    tickFormat: "d",
    label: "Year"
  },
  
  // Configure the y-axis
  y: {
    grid: true,
    label: "Generation (GWh)"
  },
  
  // Plotting the series
  marks: [
    Plot.barY(
      data.filter(d => d.region === "region_1"),
      Plot.groupX(
        {
          y: "sum"
        },
        {
          x: "year",
          y: "generation",
          fill: "fuel_type",
          tip: {format: {x: "d"}}
        }
      )
    ),
    Plot.ruleY([0])
  ],
  
  // Legend
  color: {
    domain: ["Oil","Gas","Hydro","Wind","Solar","Other"],
    range: ["#BFBFBF","#DCD9C5","#96B3DF","#F79646","#F5C243","#C0504D"],
    legend: true
  }
})

Which produces the following,

The domain should force “Oil” to come first, but the actual plotted order ends up being Gas → Hydro → Oil → etc.

My two cents is that it might have something to do with the filtering, but I’m not sure if/why that is possible.

The order of stacked elements can be controlled with the order option of the stack transform, which is implicitly added by the bar mark. This option offers a lot of possibilities; for this case you can specify it as an explicit array of ordinal values:

       {
          x: "year",
          y: "generation",
          fill: "fuel_type",
          order: ["Oil","Gas","Hydro","Wind","Solar","Other"]
          …

You are an absolute saint. Thank you so much. Is there a resource I can point to to find all the options available in these marks?

1 Like

The documentation has all the options on each dedicated page, as well as in the API index. They are also distributed as types — which can be shown in context by your code editor.

1 Like

This is great! I never noticed the API index page.

For where types are not directly handy (e.g. while working with Observable Framework, or Notebook), I also installed Observable Plot in a pet project with Typescript, where I can go to node_modules/@observablehq/plot and quickly jump through types/interfaces for quick reference.

Thank you everyone, this has been an immense help.

1 Like