r - 使用 sf 和 ggplot2 在 +/- 180 日期变更线周围绘图

标签 r ggplot2 spatial sf

我正在使用 sf 绘制一系列 shapefile 和点数据。此数据跨越 =/-180 经度的日期变更线。
sf::st_shift_longitude()处理这种情况并按预期绘制点。但是,ggplot 在分配经度刻度线时表现得很奇怪。下面的代码提供了一个示例,在日期变更线的一侧有两个点 - 注意 ggplot 为经度添加了逻辑刻度线。在第二个示例中,点跨越日期变更线。

编辑:添加了第三种情况,手动扩展了 x 限制。当这些变得足够大时,经纬网按预期绘制。但是,我只是通过对 xlim 的实验才发现“足够大”。 .

library(sf)
library(rnaturalearth)
library(ggplot2)

#get basic world map 
world = ne_coastline(scale = "medium", returnclass = "sf")

#example 1: without dateline
#minimal data- two points on one side of dateline
sites = data.frame(longitude = c(-173.9793, -177.7405), latitude = c(52.21415, 51.98994))

#convert to sf object
sites = st_as_sf(sites, coords = c("longitude", "latitude"), crs = 4326)

#plot with ggplot
ggplot()+
  geom_sf(data = world, fill = 'transparent')+
  geom_sf(data = sites)+
  #set the limits for the plot
  coord_sf(crs = 4326,
           xlim = c(min(st_coordinates(sites)[,1]) -1, max(st_coordinates(sites)[,1])+1),
           ylim = c(min(st_coordinates(sites)[,2]) -1, max(st_coordinates(sites)[,2])+1))+
  labs(title = 'data on one side of dateline only- looks good')+
  theme_bw()


#example 2: with dateline
#deal with dateline using st_shift_longitude 
world_2 = st_shift_longitude(world)

#minimal data- a point on each side of dateline
sites_2 = data.frame(longitude = c(-173.9793, 177.7405), latitude = c(52.21415, 51.98994))

#convert to sf object
sites_2 = st_as_sf(sites_2, coords = c("longitude", "latitude"), crs = 4326)
#and deal with dateline using st_shift_longitude 
sites_2 = st_shift_longitude(sites_2)

#plot with ggplot
ggplot()+
  geom_sf(data = world_2, fill = 'transparent')+
  geom_sf(data = sites_2)+
  #set the limits for the plot
  coord_sf(crs = 4326,
           xlim = c(min(st_coordinates(sites_2)[,1]) -1, max(st_coordinates(sites_2)[,1])+1),
           ylim = c(min(st_coordinates(sites_2)[,2]) -1, max(st_coordinates(sites_2)[,2])+1))+
  labs(title = 'data on both sides of dateline - grid wrong')+
  theme_bw()

#plot with manually expanded limits- graticule works
ggplot()+
  geom_sf(data = world_2, fill = 'transparent')+
  geom_sf(data = sites_2)+
  #set the limits for the plot
  coord_sf(crs = 4326,
           xlim = c(175, 195),
           ylim = c(min(st_coordinates(sites_2)[,2]) -1, max(st_coordinates(sites_2)[,2])+1))+
  labs(title = 'data on both sides of dateline - manually expand x lims')+
  theme_bw()




enter image description here
enter image description here
enter image description here

在使用 ggplot 绘图时,您是否有任何想法可以绕过日期变更线以避免出现这种行为?

谢谢!

最佳答案

我不够了解ggplot ,但我的猜测是,尽管您移动了 sf,但在内部格线仅限于 -180,180,并且事件对象 ggplot在创建轴和网格时无法识别。

我创建了一个基础示例 plot这似乎按您的预期工作。网格是用 graphics::grid() 创建的



library(sf)
#> Warning: package 'sf' was built under R version 3.5.3
#> Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
library(rnaturalearth)
#> Warning: package 'rnaturalearth' was built under R version 3.5.3

#get basic world map
world = ne_coastline(scale = "medium", returnclass = "sf")

#example 1: without dateline
#minimal data- two points on one side of dateline
sites = data.frame(
  longitude = c(-173.9793,-177.7405),
  latitude = c(52.21415, 51.98994)
)

#convert to sf object
sites = st_as_sf(sites,
                 coords = c("longitude", "latitude"),
                 crs = 4326)

#deal with dateline using st_shift_longitude
world_2 = st_shift_longitude(world)

#minimal data- a point on each side of dateline
sites_2 = data.frame(
  longitude = c(-173.9793, 177.7405),
  latitude = c(52.21415, 51.98994)
)

#convert to sf object
sites_2 = st_as_sf(sites_2,
                   coords = c("longitude", "latitude"),
                   crs = 4326)
#and deal with dateline using st_shift_longitude
sites_2 = st_shift_longitude(sites_2)

#Plot
plot(
  st_geometry(world_2),
  axes = TRUE,
  xlim = c(min(st_coordinates(sites_2)[, 1]) - 1, max(st_coordinates(sites_2)[, 1]) +
             1),
  ylim = c(min(st_coordinates(sites_2)[, 2]) - 1, max(st_coordinates(sites_2)[, 2]) +
             1)
)
grid()
plot(st_geometry(sites_2), pch = 20, add = TRUE)



创建于 2020-03-28 由 reprex package (v0.3.0)

关于r - 使用 sf 和 ggplot2 在 +/- 180 日期变更线周围绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60879460/

相关文章:

php - 距离查询

hibernate - Hibernate/spatial 的规范/谓词来过滤实体,无论它是否在半径内

sql - 收到 "DataReader.GetFieldType returned null."错误。

r - 我应该如何以及何时使用 on.exit?

r - 如何将已计算的标准误差值添加到条形图 (ggplot) 中的每个条形中?

r - 添加另一个 ggplot 到/注释 facet_wrap 图

r - 使用形状时缺少 geom_point 的绘图符号

R:为什么 mean(NA, na.rm = TRUE) 返回 NaN

r - R中的分组汇总表

r - 使用 dplyr/tidyr 在 R 中格式化/生成新表