When you set the sort mark option to a field name such as latitude, youāre applying a sort transform to sort the order in which the marks are drawn, i.e. the z order. (And here because thereās also a group transform, youāre sorting the data prior to grouping, which has no effect on the resulting display.) Likewise the reverse mark option simply reverses the z order.
In Plot speak, what youāre asking is how to set the domain of the y scale.
The most literal way of setting the domain would be to supply the list of values in the desired order:
Plot.plot({
y: {
label: null,
domain: [
"CATANIA",
"REGGIO CALABRIA",
"PALERMO",
"MESSINA",
"CAGLIARI",
"NAPOLI",
"BARI",
"LATINA",
"CAMPOBASSO",
ā¦
]
},
marks: ā¦
})
But there are various ways to do this more implicitly from the data.
One way is to use d3.groupSort: you group by the data by citta and then return the corresponding latitude for that citta. Assuming that your data is consistent and all rows with a given citta have the same latitude, you can pull out the first row for each group and return its latitude:
Plot.plot({
y: {
label: null,
domain: d3.groupSort(
diecigiorni,
([d]) => d.latitude,
(d) => d.citta
)
},
marks: ā¦
})
In other cases, you might do something like compute the median value for each group:
Plot.plot({
y: {
label: null,
domain: d3.groupSort(
diecigiorni,
(D) => d3.median(D, (d) => d.latitude),
(d) => d.citta
)
},
marks: ā¦
})
In Plot, you can implicitly set an ordinal scaleās domain using the mark sort option. This imputes the given ordinal scaleās domain from the values in a given mark channel. This feature is often used to produce a sorted bar chart, where the bars are ordered from shortest to longest or vice versa (second example here).
Itās a little trickier to use this feature here because the latitude field is not used as a visual encoding; itās merely associated with the citta field. And also, youāre using a group transform ā although the group transform doesnāt seem to be necessary here since there is only one row in the dataset per citta and data. So just to demonstrate, if you set the y channel to the latitude field instead of the citta field, and removed the group transform, you can use the sort option like so:
Plot.plot({
ā¦,
marks: [
Plot.cell(diecigiorni, {
x: "data",
y: "latitude",
fill: "livello_n",
inset: 1,
sort: { y: "y" }
})
]
})
If you want the group transform still, itās like so (the group transform groups by x and y, so you can still reference it for imputing the y scale domain after grouping):
Plot.plot({
ā¦,
marks: [
Plot.cell(
diecigiorni,
Plot.group(
{ fill: "max" },
{
x: "data",
y: "latitude",
fill: "livello_n",
inset: 1,
sort: { y: "y" }
}
)
)
]
})
But now your y scale ticks are hard to read, clearly, and the chart wouldnāt correctly handle two cities having the same latitude.
So now that weāve seen how the sort option works in the most direct case, letās go back to using the citta field for y and change the sort option to use the reduce option to find the latitude of each city:
Plot.plot({
ā¦,
marks: [
Plot.cell(diecigiorni, {
x: "data",
y: "citta",
fill: "livello_n",
inset: 1,
sort: {
y: "y",
reduce: ([y]) => diecigiorni.find((d) => d.citta === y).latitude
}
})
]
})
Note that the reduce function is passed an array of values from the markās y channel: thatās because there are multiple rows in the data associated with each citta, but to order the y domain we must return a single orderable value for each distinct citta. Again, as long as the data is consistent with the citta and latitude columns, itās fine to just pull out the first value using square brackets. (I also omitted the group transform, but you could put it back in as shown in the other examples; it doesnāt affect how the reduce function is defined here.)
Lastly, you could do this by passing data to the sort option for the y scale; that way you donāt have to reference diecigiorni
in the reduce function. Then the reduce function is passed an array of data instead of an array of y channel values. That looks like this:
Plot.plot({
ā¦,
marks: [
Plot.cell(diecigiorni, {
x: "data",
y: "citta",
fill: "livello_n",
inset: 1,
sort: {
y: "data",
reduce: ([d]) => d.latitude
}
})
]
})
If you still want the group transform, youāll need an extra set of brackets in your reduce function because now the reducer will be passed the grouped data for each y value:
Plot.plot({
ā¦,
marks: [
Plot.cell(
diecigiorni,
Plot.group(
{ fill: "max" },
{
x: "data",
y: "citta",
fill: "livello_n",
inset: 1,
sort: {
y: "data",
reduce: ([[d]]) => d.latitude
}
}
)
)
]
})
Hope this helps.