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()

解决方法
核心原因
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()
关键修改点
- 将CSV数据转为sf对象,明确指定原始坐标系为EPSG:4326
- 将数据转换到与其他图层一致的Robinson投影
- 用
geom_sf()替代geom_tile(),sf对象会自动适配当前图层的坐标系,避免坐标不匹配问题
内容的提问来源于stack exchange,提问作者Jiale
相关产品推荐
相关产品推荐

