ggsn包north/scalebar调用疑问:子区域与父区域地图能否混用?
嘿,这个问题问得特别实用!咱们直接说结论再加细节解释:只要你的两张地图(父区域和子区域)属于同一个地理坐标系(CRS),不管用north(tidy(m1))还是north(tidy(m2)),或者scalebar的两种调用方式,结果都是完全没问题的,你的判断是对的——因为它们属于同一区域,坐标系一致,ggsn的这两个函数核心依赖的就是坐标系和地理范围信息,父子地图在这两点上是兼容的。
具体原因拆解:
指北针(north函数)
north函数的核心作用是根据输入数据的坐标系确定正北方向(地理坐标系对应真北,投影坐标系对应投影后的正北),然后自动(或手动指定)在图上合适位置绘制指北针。
只要m1和m2的CRS相同,正北方向是完全一致的;同时函数会根据当前绘图的可视范围调整指北针的相对位置,所以不管用父区域还是子区域的tidy对象,最终指北针的方向和位置都是适配当前子区域地图的。比例尺(scalebar函数)
scalebar是根据输入数据的坐标系单位(比如米、千米)来计算比例尺的实际长度和刻度标注的。
同一区域的父子地图必然共享CRS,单位完全一致,所以不管用父还是子区域的tidy对象,计算出的比例尺都符合当前地图的实际距离。唯一需要注意的是,如果手动指定了比例尺位置,要确保它落在子区域地图的可视范围内(默认情况下函数会自动选合适位置)。
示例代码验证
用你提到的tigris包举个实际例子:
library(tigris) library(ggplot2) library(ggsn) library(broom) library(sf) # 下载父区域(德克萨斯州所有县)和子区域(哈里斯县) m1 <- counties(state = "TX", cb = TRUE) m2 <- subset(m1, NAME == "Harris") # 转换为tidy格式 tidy_m1 <- tidy(m1) tidy_m2 <- tidy(m2) # 用父区域tidy对象加指北针和比例尺的子区域地图 ggplot() + geom_polygon(data = tidy_m2, aes(x = long, y = lat, group = group), fill = "#e6f2ff", color = "white") + coord_sf(crs = st_crs(m1)) + # 强制统一坐标系 north(tidy_m1, symbol = 1) + # 用父区域对象 scalebar(tidy_m1, dist = 50, dist_unit = "km", transform = TRUE, model = "WGS84") # 用子区域tidy对象的版本,效果完全一致 ggplot() + geom_polygon(data = tidy_m2, aes(x = long, y = lat, group = group), fill = "#e6f2ff", color = "white") + coord_sf(crs = st_crs(m1)) + north(tidy_m2, symbol = 1) + scalebar(tidy_m2, dist = 50, dist_unit = "km", transform = TRUE, model = "WGS84")
关键注意事项
一定要保证两张地图的坐标系(CRS)完全一致,如果其中一张做过坐标系转换,就不能混用了,必须使用和当前绘图CRS匹配的tidy对象。
内容的提问来源于stack exchange,提问作者user2338823

