Observable Plot: how to set custom colors based of field values?

Hi,
I’m building my first dots map using Plot.

I have a dot layer (citta) and I want to style the dots based on the values I read in livello field.

Currently the colors are assigned automatically, but I have 4 categorical values (“Livello0”, “Livello1”, “Livello2” and “Livello3”) and I would like to assign distinct custom color to each one.

In the documentation I have read about channel and scale, but I’m not able to use them and reach my goal.

Is there some “hello world” Observable Plot example that I can use?

Thank you

try this:

color: {
  domain: ["Livello0", "Livello1", "Livello2", "Livello3"],
  range: ["yellow", "blue", "green", "black"]
},
2 Likes

Thank you very much @Fil , but how to use it to apply it to a Plot.dot layer.
It’s not in this way.

The name of the field that contains the category values is livello.

Thank you

Plot.plot({
  width: 400,
  height: 400,
  projection: { type: "mercator", domain: Reg01012023_g_WGS84 },
  marks: [
    Plot.geo(Reg01012023_g_WGS84, {
      fill: "#f5f5f5",
      fillOpacity: 1,
      stroke: "#797979"
    }),
    Plot.dot(citta, {
      x: "longitude",
      y: "latitude",
      r: 4,
      stroke: "#000000",
      fill: "livello",
      tip: true,
      color: {
        domain: ["Livello0", "Livello1", "Livello2", "Livello3"],
        range: ["yellow", "blue", "green", "black"]
      }
    })
  ]
})

Almost there - just move the color specification to outside the marks list (e.g. under the projection line).

1 Like

It works, thank you very much!!

I don’t understand, however, why it must be inserted outside the reference layer.
And if I had two dot layers, with two distinctive styles to apply, how should I write the instruction to apply style “1” to layer “a” and style “2” to layer “b”?

The point of the “grammar of graphics” is that there is a unique meaning for each visual variable, in that case a single and shared scale for colors. If you need to specify a color scale for a specific mark, though, you can do so by giving explicit colors in the mark:

Plot.dot(…, {fill: “red”})

or even a variable color:

Plot.dot(…, {fill: d => d.category === “city” ? “red” : “grey”})

But then , you’ll need to create the scale yourself. Which you can do by using Plot.scale()

Hi @Fil ,
starting from this template, I have built this observable plot chart.

I would like to use livello_n value and this colors definition to fill the cells.

  color: {
    domain: [0, 1, 2, 3],
    range: ["#5bd601", "#e8d203", "#ff7f02", "#c40001"]
  }

But my code is wrong. What do I must correct to associate those colors to those values?

Thank you

If you look at your complete code, you’ll notice that you’ve specified color twice. Your second color specification looks like so:

  color: { legend: true, zero: true },

I guess that second specification comes from the template you started with. You’ve got to get rid of it, though, since it’s overriding the color specification that you want.

1 Like

I’m stupid, now it works, thank you very much @mcmcclur

1 Like