'Reorder plot legend categories in a terra SpatVector map

Is there a way to have the plot legend categories in a specific order with a SpatVector map of package terra? Example:

library(terra)
v <- vect(system.file("ex/lux.shp", package="terra"))
head(v)
plot(v, "NAME_1")

enter image description here

How can we get "Luxembourg" to appear first in the legend, and also the remaining categories in a user-specified order? We've tried converting the "NAME_1" column to factor, but it's still interpreted as character.



Solution 1:[1]

You can use the argument sort=FALSE. In that case, the legend will be in the same order as what is returned by unique("fieldname")

Example data

library(terra)
v <- vect(system.file("ex/lux.shp", package="terra"))

If we wanted to map "NAME_1" alphabetically, except with "Luxembourg" on top, you could do

# make sure names are sorted 
v <- v[order(v$NAME_1), ]
# put Luxembourg on top
vv <- rbind(v[v$NAME_1 == "Luxembourg", ], v[v$NAME_1 != "Luxembourg", ])

plot(vv, "NAME_1", sort=FALSE)

enter image description here


terra version 1.5.38 (currently the development version) now has these two additional options:

Sort in decreasing order

plot(v, "NAME_2", decreasing=TRUE)

enter image description here

Sort in a specified order (or random, as in this example)

set.seed(66)
u <- unique(v$NAME_2) |> sample()
plot(v, "NAME_2", sort=u)

enter image description here

Solution 2:[2]

I have a bit tricky solution. You can manually set a legend in your plot using the base R legend function. You can use the following code:

library(terra)
v <- vect(system.file("ex/lux.shp", package="terra"))
head(v)
plot(v, "NAME_1")
legend("topright", legend = c("Luxembourg", "Grevenmacher", "Diekrich"), fill = c("green", "blue", "deeppink"), bty = "n")

Output: enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Quinten