在[用 R 來畫地形圖——以新竹縣市為例](/4qekUVBEQdmfR4mvcs--og)當中,使用 `tmap` 套件來視覺化新竹縣市的分層設色地形圖。如果想要在旁邊加入一張小地圖,呈現大新竹地區在台灣的位置應跟怎麼做呢?
之前有提過,`tmap` 套件源於 `grid` 套件。因此可以用 `grid` 中的 `viewport()` 功能(類似 `ggplot2` 中的 `annotation_custom()` 功能),把已經畫好的小地圖,依照指定的視區(就是插圖的大小與位置)畫到主圖上。
先畫一個主圖:
```{R}=
colss <- RColorBrewer::brewer.pal(n = 10, name = "RdYlGn")
colss1 <- c("#00341b", rev(colss), "blueviolet")
HC_map_base <- tm_shape(HC) +
tm_borders(lwd = 2) + tm_graticules(n.x = 4, alpha = 0.1, labels.size = 1) +
tm_shape(hill) +
tm_raster(palette = gray(0:10 / 10), n = 100, legend.show = FALSE, alpha = 0.25) +
tm_shape(coop) +
tm_raster(alpha = 0.7, palette = colss1, n = 9, style = "fixed",
breaks = c(-5, 0, 100, 500, 1000, 1500, 2000, 2500, 3000, 3600),
legend.show = T, title = "Elevation(m)") +
tm_scale_bar(breaks = c(0, 10, 20), text.size = 0.9, text.color = "black", color.dark = "black",
position = c(.675, 0.005), lwd = 1, color.light= "white")+
tm_compass(type = "8star", position=c(.84, .36), size = 6, text.color = "black")+
tm_layout( bg.color = "white",
legend.title.size = 1.2,
legend.position = c(.83, .08) ,
legend.text.size = 0.9,
fontface = "bold",
legend.format = c(text.align = "right", text.separator = "-"),
inner.margins = c(.1,.1,.1,.22),
frame = TRUE, frame.lwd = 5) +
tm_credits("Elevation Map \n of Hsinchu", position = c(.58, .82), col = "black",
fontface = "bold", size = 2.4, align = "right", fontfamily = "serif")
```
接著畫個小地圖,就可以把兩張圖疊起來了:
```{R}=
smap <- tm_graticules(n.x = 3, n.y = 4, alpha = 0.1, labels.show = F) +
tm_shape(border, xlim = c(119.1, 122.3), ylim = c(21.75, 25.5)) +
tm_borders(lwd = 1) + tm_fill(col = "white") +
tm_shape(HC) +
tm_borders(lwd = 2) + tm_fill(col = "grey40") +
tm_layout(frame.double.line = T, frame.lwd = 0.8)
library(grid)
HC_map_base
map_combin = print(smap, vp = viewport(0.28, 0.2, width = 0.2, height = 0.3))
```
如果 `viewport()` 的參數沒有問題,想要把圖輸出儲存,可以透過 `tmap_save()` 中的 `insets_tm` 參數指定要插入的小地圖、`insets_vp` 參數指定視區(viewport)大小與位置,最後就可以存檔了:
```{R}=
showtext::showtext_opts(dpi = 200)
vip_map <- viewport(0.22, 0.2, width = 0.2, height = 0.3)
tmap_mode("plot")
tmap_save(HC_map_BS, filename = paste0("HCmap_", format(Sys.time(), "%y%m%d.%H%M%S"),".png"),
width = 9, height = 7.5, dpi = 200,
insets_tm = smap, insets_vp = vip_map)
```
小地圖內要再加指北針、比例尺也是可以的。
最後,我習慣把檔名加個時間戳記,這樣就算更改繪圖參數反覆執行,也不用花時間手動調整檔名。
最後輸出的圖如下:

有關 `viewport()` 的詳細說明與用法,可以參考 [Working with grid Viewports](https://stat.ethz.ch/R-manual/R-devel/library/grid/doc/viewports.pdf)。
### 延伸閱讀
1. [An Introduction to R Graphics](https://www.stat.auckland.ac.nz/~paul/RGraphics/chapter1.pdf)
2. [Building Data Visualization Tools: Customise `ggplot2` output with `grid`
](https://pparacch.github.io/2017/09/25/plotting_in_R_ggplot2_part_5.html)
3. Exploratory Data Analysis with R: [Graphics Devices](https://bookdown.org/rdpeng/exdata/)
4. [Presentation: Plotting Systems in R](https://www.slideshare.net/IlyaZhbannikov/presentation-plotting-systems-in-r)
5. [R 绘图系统 grid🎈](https://www.jianshu.com/p/83cdf8cecb13)
6. 台北大學林建甫老師 R 課程講義[第 6 章: 常用的 R 繪圖程式](https://web.ntpu.edu.tw/~cflin/Teach/R/R06EN06Graphics.pdf)
<span style="font-size:30px">🐕🦺</span><font color="dcdcdc">2024.01.09</font>