将ggplot2地图旋转到任意角度

类似于ggplot2:如何以特定角度旋转图形?,但我不希望图像/正方形旋转,我希望在框架内旋转数据。

例如,如果我从这个开始:

library(ggplot2)
usa <- maps::map('usa', plot=FALSE)

ggplot(as.data.frame(usa[c("x","y")]), aes(x,y)) +
  coord_quickmap() +
  geom_path()

我希望能够生成这个:

  • 旋转需要保留空间数据的纵横比
  • 我需要支持任意旋转,不受 90 度跳跃的限制
  • 我想是否可以保留实际的网格(以保留其中的默认行为ggplot2),但如果不能,我可以手动生成它们
  • 我希望通用图的封闭矩形保持不变,包括(此处未显示)标题和副标题
  • 如果坐标系不变,我会喜欢它,这意味着我可以添加其他图层,这些图层随后会自动欣赏旋转。@qdread 的回答给出了替代方案,其中单个函数可以计算旋转(尽管我不知道如何使用空间数据在数学上做到这一点)
  • 请忽略:
    • 左上角的网格问题,我的photoshopping不完整
    • x 轴标签,数字错误(y 轴很好)(可以删除,不需要)

我想知道这是否可以通过CRS/projections来完成,但我对它们不够聪明,无法正式/正确地使用它。

回答

edit2:
使用斜墨卡托投影旋转地图:

#crs with 45degree shift using +gamma
# lat_0 and lonc approximate centroid of US
crs_string = +proj=omerc +lat_0=36.934 +lonc=-90.849 +alpha=0 +k_0=.7 +datum=WGS84 +units=m +no_defs +gamma=45"

# states data & libraries in code chunk below
ggplot(states) +
    geom_sf() +
    geom_sf(data = x, color = 'red') +
    coord_sf(crs = crs_string, 
             xlim = c(-3172628,2201692),    #wide limits chosen for animation
             ylim = c(-1951676,2601638)) +  # set as needed
    theme_bw() +
    theme(axis.text = element_blank()) 

伽马动画从 0:360 开始,以 10 度为增量,alpha 常数为 0。伪影来自 gif 压缩,实际图看起来像上面标记为 45 的图。

较早的答案:我认为您可以通过将投影更改为 Lambert 方位角相等面积并+lon_0=x在投影字符串中进行调整,通过从不同的角度“看”地球来“旋转”绘图(包括经纬网)。

这应该可以满足您的大部分目标,但我不知道如何获得精确的度数旋转。

下面我states_sf在绘图之前手动转换了sf 对象。通过对数据使用 crs 4326 并添加+ coord_sf(crs = "+proj=laea +x_0=0 +y_0=0 +lon_0=-140 +lat_0=40")ggplot() +调用的末尾,可能更容易转换绘图(以及所有正在绘制的 sf 数据)。

#crs with 45degree shift using +gamma
# lat_0 and lonc approximate centroid of US
crs_string = +proj=omerc +lat_0=36.934 +lonc=-90.849 +alpha=0 +k_0=.7 +datum=WGS84 +units=m +no_defs +gamma=45"

# states data & libraries in code chunk below
ggplot(states) +
    geom_sf() +
    geom_sf(data = x, color = 'red') +
    coord_sf(crs = crs_string, 
             xlim = c(-3172628,2201692),    #wide limits chosen for animation
             ylim = c(-1951676,2601638)) +  # set as needed
    theme_bw() +
    theme(axis.text = element_blank()) 

library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(urbnmapr)
library(tidyverse)

# get sf of the us, remove AK & HI, 
#  transform to crs 4326 (lat & lon)
  states_sf <- get_urbn_map("states", sf = TRUE) %>%
    filter(!state_abbv %in% c('AK', 'HI')) %>%
    st_transform(4326)

  #centroid of us to 'look' at the US from directly above the center
  us_centroid <- st_union(states_sf) %>% st_centroid() %>% st_transform(4326)

  st_coordinates(us_centroid)
#>           X        Y
#> 1 -99.38208 39.39364
  
# Plots, changing the +lon_0=xxx of the projection
  p1 <- states_sf %>% 
  st_transform("+proj=laea +x_0=0 +y_0=0 +lon_0=-99.382 +lat_0=39.394") %>%
  ggplot(aes()) +
  geom_sf(fill = "black", color = "#ffffff") +
    ggtitle('US from above its centroid 39.3N 99.4W')

  p2 <- states_sf %>% 
    st_transform("+proj=laea +x_0=0 +y_0=0 +lon_0=-70 +lat_0=40") %>%
    ggplot(aes()) +
    geom_sf(fill = "black", color = "#ffffff") +
    ggtitle('US from 40N 70W')
  
  p3 <- states_sf %>% 
    st_transform("+proj=laea +x_0=0 +y_0=0 +lon_0=-50 +lat_0=40") %>%
    ggplot(aes()) +
    geom_sf(fill = "black", color = "#ffffff") +
    ggtitle('US from 40N 50W')
  
  p4 <- states_sf %>% 
    st_transform("+proj=laea +x_0=0 +y_0=0 +lon_0=-30 +lat_0=40") %>%
    ggplot(aes()) +
    geom_sf(fill = "black", color = "#ffffff") +
    ggtitle('US from 40N 30W')
  
  p5 <- states_sf %>% 
    st_transform("+proj=laea +x_0=0 +y_0=0 +lon_0=-10 +lat_0=40") %>%
    ggplot(aes()) +
    geom_sf(fill = "black", color = "#ffffff") +
    ggtitle('US from 40N 10W')
  
  p6 <- states_sf %>% 
    st_transform("+proj=laea +x_0=0 +y_0=0 +lon_0=-140 +lat_0=40") %>%
    ggplot(aes()) +
    geom_sf(fill = "black", color = "#ffffff") +
    ggtitle('US from 40N 140W')
  
 p1
 p3
 p5

由reprex 包(v0.3.0)于 2021 年 3 月 31 日创建

编辑:

使用投影时,您似乎可以通过 alpha 和 gamma 的组合获得任何角度"+proj=omerc +lonc=-90 +lat_0=40 +gamma=0 +alpha=0"。我不知道它们到底是如何关联的(与方位角有关),但这应该有助于将其可视化:

# Basic template for rotating, keeping US map centered.
#  adjust alpha and gamma by trial & error
crs <- "+proj=omerc +lonc=90 +lat_0=40 +gamma=90 +alpha=0"
 
 states_sf %>% 
   ggplot() + 
   geom_sf(fill = 'green') +
   coord_sf(crs = crs)

可以在此处找到更广泛的 alpha 和 gamma 动画。


以上是将ggplot2地图旋转到任意角度的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>