I need to place a fill-legend for categorical raster data, where white is used to represent ice, on a raster map on white background. I would like to use tmap. Here is a minimum working example that is similar in spirit to my current project.
library(tmap)
library(dplyr)
library(forcats)
library(stars)
data(land)
land_copy <-
land %>%
mutate(cover_simplified =
fct_other(cover_cls, keep = c("Snow/ice", "Water")))
tm_shape(land_copy) +
tm_raster(col = "cover_simplified",
palette = c("white", "lightblue", "brown")) +
tm_layout(legend.outside = TRUE)
map produced with tmap, no rectangular frame around legend key
The problem is that it is unclear that "Snow/ice" in the legend refers to a category because the key colour is invisible on a white background. For this reason, "Snow/ice" looks like a legend title rather than a legend key. I am aware that I can change the legend background with tm_layout(legend.bg.color = "gray")
, but I prefer to keep the background white. Instead I would like to draw a thin black rectangular frame around each legend key. Here is this idea implemented with ggplot2.
library(ggplot2)
ggplot() +
geom_stars(aes(x, y, fill = cover_simplified), data = land_copy) +
scale_fill_discrete(type = c("white", "lightblue", "brown")) +
coord_sf() +
theme_void() +
theme(legend.key = element_rect(color = "black"))
map produced with ggplot2 with rectangular frame around each legend key
I would prefer to work with tmap instead of ggplot2 because the actual map I want to produce is more complex than the example above, so tmap is a better tool for my task. I am posting this question because I cannot find a function argument for tm_layout()
that seems relevant for my problem. A Google search has not led me to useful information either.
Is there a way to produce the equivalent of ggplot2's theme(legend.key = element_rect(color = "black")
with tmap?
There doesn't seem to be an option for doing this directly in tmap
. However, a tmap
is drawn with grid graphics, so it is possible to capture the legend, change it, and draw it back. If you add the following lines after your code:
g <- grid::grid.grab()
leg <- grid::getGrob(g, "legend")
leg$children[[2]]$children[[2]]$children[[1]]$gp$col <- "black"
leg$children[[2]]$children[[2]]$children[[1]]$gp$lwd <- 1
grid::seekViewport("outside_legend")
grid::grid.draw(leg)
You get:
If you want to save this as a pdf, you can't use tmap_save
, since this is no longer a tmap
object. Instead, get the plot looking as you would like, then do:
g <- grid::grid.grab()
pdf("my_pdf.pdf")
grid::grid.newpage()
grid::grid.draw(g)
dev.off()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.