I would like to know:
a) what determines in which order elements are rendered in a ggplot2 plot?
b) how can I influence this plot order of elements according to a variable or gradient colour scale?
Context: I want to visualise a continuous variable of road network data (such as e.g. traffic flows). It is important that lines with high values are plotted last (so that they appear on top of lines with lower values) in order to make the plot legible. At present, the default seems to plot lines in random order.
Below is an example using road length as a variable, the expected output would plot road lines in order of their value, i.e., first grey lines, then red-grey lines, then darker red lines, and so forth.
Example data:
library(GISTools)
library(sf)
library(ggplot2)
data(newhaven)
ggplot()
geom_sf(data = st_as_sf(roads, "lines"), aes(col = LENGTH))
scale_colour_gradient(low = "grey", high = "red")
Here is a zoom in that illustrates quite well what the issue is: the grey road is covering the red road. However, what I would like to acchieve is that red road is plotted last (since it has a bigger length value).
ggplot()
geom_sf(data = st_as_sf(roads, "lines"), aes(col = LENGTH, size = 3))
scale_colour_gradient(low = "grey", high = "red")
coord_sf(xlim = c(557000, 560000), ylim = c(178000, 180000))
annotate(geom = "curve", x = 558000, y = 178500, xend = 558850, yend = 179150, curvature = -.3, arrow = arrow(length = unit(3, "mm")))
CodePudding user response:
In general, ggplot plots the elements additively (ie "on top") in order of appearance in the source data. So if we sort by ascending LENGTH, then the longest roads should print last.
library(dplyr)
ggplot()
geom_sf(data = st_as_sf(roads, "lines") %>% arrange(LENGTH),
aes(col = LENGTH, size = 3))
scale_colour_gradient(low = "grey", high = "red")
coord_sf(xlim = c(557000, 560000), ylim = c(178000, 180000))
annotate(geom = "curve", x = 558000, y = 178500, xend = 558850, yend = 179150, curvature = -.3, arrow = arrow(length = unit(3, "mm")))