rr-sfterratmap

How to position the north arrow using tmap r package?


I want to position north arrow at the center of the scalebar. I am using the following code:

library(tmap)
library(terra)
library(sf)

r <- rast(system.file("ex/elev.tif", package="terra"))

states <- st_read(system.file("ex/lux.shp", package="terra"))

# make some bbox magic
bbox_new <- st_bbox(r) # current bounding box

xrange <- bbox_new$xmax - bbox_new$xmin # range of x values
yrange <- bbox_new$ymax - bbox_new$ymin # range of y values

bbox_new[1] <- bbox_new[1] - (0.05 * xrange) # xmin - left
bbox_new[3] <- bbox_new[3] + (0.05 * xrange) # xmax - right
bbox_new[2] <- bbox_new[2] - (0.05 * yrange) # ymin - bottom
bbox_new[4] <- bbox_new[4] + (0.05 * yrange) # ymax - top

bbox_new <- bbox_new %>%  # take the bounding box ...
  st_as_sfc() # ... and make it a sf polygon


tm_shape(r, bbox = bbox_new) +
  tm_raster(col.scale = tm_scale_continuous(
    values = "viridis"),  # color palette; 
    col.legend = tm_legend(title = "Legend", frame.lwd = 0,
                           position = c("LEFT", "BOTTOM"))) +
  tm_shape(states) +
  tm_borders() +
  tm_compass(position = c("RIGHT", "TOP"), size = 1, text.size = 1) +
  tm_scalebar(text.size = 1,
    breaks = c(0, 8, 16), 
    position = c("RIGHT", "TOP"))

enter image description here

As you can see from the output map, the nort arrow is at the extreme left of scalebar. How can I position the north arrow at the centre of scalebar? My expected output is

enter image description here


Solution

  • We can use tm_pos_in(..) to get closer:

    tm_shape(r, bbox = bbox_new) +
      tm_raster(col.scale = tm_scale_continuous(
        values = "viridis"),  # color palette; 
        col.legend = tm_legend(title = "Legend", frame.lwd = 0,
                               position = c("LEFT", "BOTTOM"))) +
      tm_shape(states) +
      tm_borders() +
      tm_compass(position = tm_pos_in(pos.h="right", pos.v="top", align.h="center"), size = 1, text.size = 1) +
      tm_scalebar(text.size = 1, breaks = c(0, 8, 16), position = tm_pos_in(pos.h="right", pos.v="top", align.h="center"))
    

    tmap plot with compass centered on the scalebar

    The offset nature is because of the "km" on the scalebar. Said differently, the compass is centered on the whole scalebar.

    (For the record, this is also the case if we specify a numeric pos.*= and use just.*= to try another way of nudging them around.)