如何在ggplot2的coord_sf()中正确显示160-180°E经度轴刻度?
问题描述
使用ggplot2和sf绘制包含外岛的新西兰地图时遇到以下问题:
- 即使设置
xlim = c(160, 180),x轴仍无法延伸至180°E; - 使用
scale_x_continuous()时,y轴标签完全失效; - 有时x轴标签会垂直重复。
期望实现:
- x轴清晰显示160、165、170、175、180刻度;
- y轴标签正常显示纬度;
- 无刻度断裂等异常。
解决方案(适配ggplot2 ≥3.5.0)
核心思路是避免混用笛卡尔坐标的scale函数与sf地理坐标,直接利用coord_sf()的原生参数控制刻度范围与显示,同时通过显式的经纬网标注确保刻度准确。
关键修改点
- 移除
scale_x_continuous():该函数针对笛卡尔坐标,与sf的地理坐标系不兼容,会破坏y轴显示; - 在
coord_sf()中通过breaks参数直接指定经纬刻度; - 用
annotation_graticule()显式绘制经纬网,确保刻度范围强制生效; - 保留
expand=FALSE严格限制坐标范围,避免自动缩放截断180°E。
修改后的完整代码
library(sf) library(ggplot2) # 关闭S2处理避免几何问题 sf_use_s2(FALSE) # 加载新西兰海岸线数据(替换为你的文件路径) nz_islands <- st_read("Shapefiles/nz-coastlines-and-islands-topo-150k.shp", quiet = TRUE) # 惠灵顿坐标 wellington <- data.frame( lon = 174.7772, lat = -41.2889 ) |> st_as_sf(coords = c("lon", "lat"), crs = 4326) # 最终绘图代码 ggplot() + # 绘制新西兰岛屿 geom_sf(data = nz_islands, fill = "#708090", color = "black") + # 标记惠灵顿 geom_sf(data = wellington, shape = 21, color = "blue", fill = NA, size = 3) + # 显式绘制经纬网,指定刻度间隔 annotation_graticule( xbreaks = seq(160, 180, 5), ybreaks = seq(-53, -29, 4), # 可根据需求调整纬度刻度间隔 color = "gray50", linewidth = 0.2 ) + # 设置坐标范围与投影,强制使用指定刻度 coord_sf( xlim = c(160, 180), ylim = c(-53, -29), expand = FALSE, crs = st_crs(4326), # ggplot2 3.5.0+支持:直接指定轴刻度 breaks = list( x = seq(160, 180, 5), y = seq(-53, -29, 4) ) ) + theme_minimal() + theme( axis.text.x = element_text(size = 8, color = "gray30"), axis.text.y = element_text(size = 8, color = "gray30"), axis.ticks = element_line(color = "gray50"), # 避免经纬网标签重复 panel.grid = element_blank() )
额外说明
- 如果仍存在x轴未到180°E的情况,可添加一个极窄的虚拟多边形覆盖180°E范围(比虚拟点更稳定):
# 添加覆盖180°E的虚拟多边形 dummy_poly <- st_polygon(list(rbind( c(180, -53), c(180, -29), c(180.0001, -29), c(180.0001, -53), c(180, -53) ))) |> st_sfc(crs = st_crs(nz_islands)) |> st_sf() # 在绘图时添加geom_sf(data = dummy_poly, alpha = 0)
annotation_graticule()和coord_sf(breaks)配合使用,确保刻度显示一致,避免重复标签问题。
内容的提问来源于stack exchange,提问作者Angela Russell
相关产品推荐
相关产品推荐

