When I use expression() to add text formatting such as italics and subscripts to a tmap legend, I'm getting huge amounts of unnecessary white space, and I have no idea why.
Here's my reprex code;
library(tmap)
library(sf)
# dummy data
nc <- st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
# default map
map1 <- tm_shape(nc) +
tm_polygons("AREA",
title = "Area[avg] (km^2)") +
tm_layout(bg.color = "grey",
legend.frame = TRUE,
legend.bg.color = "white")
# text-formatted map
map2 <- tm_shape(nc) +
tm_polygons("AREA",
title = expression(Area[avg]~(italic(km)^2))) +
tm_layout(bg.color = "grey",
legend.frame = TRUE,
legend.bg.color = "white")
Which results in map1, showing the legend box fitting nicely around the un-formatted text, and map2, where we can see the needless white space tacked onto the right side of the legend.
I haven't been able to find many resources on this topic, but some things I've tried and their effects are:
Attempt | Result |
---|---|
tm_layout(legend.width) | doesn't allow me to override what it detects as the minimum width |
tmap fontface arguments | affect the whole legend title, rather than specific characters therein |
tm_credit() | is covered by legend, regardless of the order I place it in the code |
blank title, grid.text label | way too difficult to space correctly |
avoid ~, use space inside quotes instead | minimal effect |
use as.expression(bquote()) | extra white space remains |
remove the frame and bg color | while the legend frame isn't needed in this reprex example, it is in my actual use case |
When running your code with tmap version 4.1, I got the following warning
── tmap v3 code detected ───────────────────────────────────────────────────────────────────────────────────────────────────
[v3->v4] `tm_polygons()`: migrate the argument(s) related to the legend of the visual variable `fill` namely 'title' to
'fill.legend = tm_legend(<HERE>)'
so I followed this advice and it worked + your described problem did not appear. I used this vignette to recreate the legend position.
# install.packages("tmap") # this works for tmap version 4.1
library(tmap)
library(sf)
# dummy data
nc <- st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
# text-formatted map
tm_shape(nc) +
tm_polygons("AREA",
fill.legend = tm_legend(
title = expression(Area[avg] ~ (italic(km)^2)),
show = TRUE,
position = c("left", "bottom")
)) +
tm_layout(
bg.color = "grey",
legend.frame = TRUE,
legend.bg.color = "white"
)
If you specifically need help with your tmap version, can you please provide it?
Rolling back to version 3.3-4 I could recreate your issue and found that the legend width is tied to the legend.title.size
(Source) so one could decrease it to legend.title.size = 0.6
and this will remove the white space, but also shrink the legend title.
remotes::install_version("tmap", version = "3.3-4")
library(tmap)
library(sf)
nc <- st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
t <- tm_shape(nc) +
tm_polygons("AREA",
title = expression(Area[avg]~(italic(km)^2), parse = TRUE)) +
tm_layout(bg.color = "grey",
legend.frame = TRUE,
legend.bg.color = "white",
legend.title.size = 0.6)