You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

geom_tile数据在180°中心Robinson投影地图中无法显示求助

问题:添加自定义180°中心Robinson投影后geom_tile颜色消失

我尝试用geom_tile()基于数据中的label变量绘制带不同颜色的地图,初始代码可正常显示颜色效果:

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

T_Fe_0.6 <- read.csv("T_Fe_0.6.csv")
ggplot()+
  geom_tile(data = T_Fe_0.6,aes(x = longitude,y = latitude,fill = as.factor(label)))

显示正确颜色的世界地图

但添加自定义180°中心Robinson投影的美学图层后,颜色消失,此问题与投影相关,相关代码如下:

world <- ne_countries(scale = "medium", returnclass = "sf")

world <- world |> 
  st_break_antimeridian(lon_0 = 180) |> 
  st_transform(crs = "+proj=robin +lon_0=180 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")

lats <- seq(-90, 90, by = 1)
lons_left <- rep(-0.001, length(lats))
lons_right <- rep(360.001, length(lats))

border_coords <- rbind(
  cbind(lons_right, lats),
  cbind(rev(lons_left), rev(lats))
)
border_coords <- rbind(border_coords, border_coords[1, ])

border <- suppressWarnings(
  st_polygon(list(border_coords)) |>
    st_sfc(crs = 4326) |>
    st_segmentize(100000) |>
    st_transform("+proj=robin +lon_0=180 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
)

grat <- st_graticule(x = c(0,-90,360,90),crs = 4326, lon = c(60,120,180,240,300),
                     lat = seq(-90,90,by = 30)) |> 
  filter(plot12 == "TRUE")

# lon
labels_x_init <- grat |> 
  filter(type == "E") |> 
  mutate(lab = ifelse(degree > 180,paste0(360-degree,"°W"),
                      paste0(degree, "°E")))
labels_x <- st_as_sf(st_drop_geometry(labels_x_init), lwgeom::st_startpoint(labels_x_init))

# lat
labels_y_init <- grat |> 
  filter(type == "N") |> 
  mutate(lab = ifelse(degree == 0, "0°",
                      ifelse(degree > 0, paste0(degree, "°N"),
                             paste0(-degree, "°S"))))

labels_y <- st_as_sf(st_drop_geometry(labels_y_init), lwgeom::st_startpoint(labels_y_init))

ggplot()+
  geom_tile(data = T_Fe_0.6,aes(x = longitude,y = latitude,fill = as.factor(label)))+ 
  geom_sf(data = world, fill = "lightgrey", color = "lightgrey")+
  geom_sf_text(data = labels_x, aes(label = lab), nudge_y = -0.7e6, size = 8)+
  geom_sf_text(data = labels_y, aes(label = lab), nudge_x = -1.5e6, size = 8)+
  geom_sf(data = grat, color = "lightgrey", linewidth = 0.3)+
  geom_sf(data = border, fill = NA, color = "black", linewidth = 1) +
  theme_void()

180°中心Robinson投影世界地图未显示数据颜色


解决方法

核心原因

geom_tile使用的是原始WGS84经纬度坐标(EPSG:4326),而其他sf图层已转换为Robinson投影的米制坐标,两者坐标系不匹配,导致tile被绘制到了画布外的错误位置,所以看不到颜色。

修改后的完整代码

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

# 读取数据并转换为sf对象,指定原始CRS为EPSG:4326
T_Fe_0.6 <- read.csv("T_Fe_0.6.csv") |>
  st_as_sf(coords = c("longitude", "latitude"), crs = 4326) |>
  # 转换到目标Robinson投影
  st_transform(crs = "+proj=robin +lon_0=180 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")

world <- ne_countries(scale = "medium", returnclass = "sf")

world <- world |> 
  st_break_antimeridian(lon_0 = 180) |> 
  st_transform(crs = "+proj=robin +lon_0=180 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")

lats <- seq(-90, 90, by = 1)
lons_left <- rep(-0.001, length(lats))
lons_right <- rep(360.001, length(lats))

border_coords <- rbind(
  cbind(lons_right, lats),
  cbind(rev(lons_left), rev(lats))
)
border_coords <- rbind(border_coords, border_coords[1, ])

border <- suppressWarnings(
  st_polygon(list(border_coords)) |>
    st_sfc(crs = 4326) |>
    st_segmentize(100000) |>
    st_transform("+proj=robin +lon_0=180 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
)

grat <- st_graticule(x = c(0,-90,360,90),crs = 4326, lon = c(60,120,180,240,300),
                     lat = seq(-90,90,by = 30)) |> 
  filter(plot12 == "TRUE") |>
  st_transform(crs = "+proj=robin +lon_0=180 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")

# lon
labels_x_init <- grat |> 
  filter(type == "E") |> 
  mutate(lab = ifelse(degree > 180,paste0(360-degree,"°W"),
                      paste0(degree, "°E")))
labels_x <- st_as_sf(st_drop_geometry(labels_x_init), lwgeom::st_startpoint(labels_x_init))

# lat
labels_y_init <- grat |> 
  filter(type == "N") |> 
  mutate(lab = ifelse(degree == 0, "0°",
                      ifelse(degree > 0, paste0(degree, "°N"),
                             paste0(-degree, "°S"))))

labels_y <- st_as_sf(st_drop_geometry(labels_y_init), lwgeom::st_startpoint(labels_y_init))

ggplot()+
  # 使用geom_sf替代geom_tile,sf对象自动匹配坐标系
  geom_sf(data = T_Fe_0.6, aes(fill = as.factor(label)))+ 
  geom_sf(data = world, fill = "lightgrey", color = "lightgrey")+
  geom_sf_text(data = labels_x, aes(label = lab), nudge_y = -0.7e6, size = 8)+
  geom_sf_text(data = labels_y, aes(label = lab), nudge_x = -1.5e6, size = 8)+
  geom_sf(data = grat, color = "lightgrey", linewidth = 0.3)+
  geom_sf(data = border, fill = NA, color = "black", linewidth = 1) +
  theme_void()

关键修改点

  1. 将CSV数据转为sf对象,明确指定原始坐标系为EPSG:4326
  2. 将数据转换到与其他图层一致的Robinson投影
  3. 用geom_sf()替代geom_tile(),sf对象会自动适配当前图层的坐标系,避免坐标不匹配问题

内容的提问来源于stack exchange,提问作者Jiale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 16:37:28