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

栅格化ggplot后raster对象不符合预期,问题出在哪?

ggplot栅格化问题:生成的raster对象无法准确还原箭头图形

我想知道是否可以将ggplot栅格化,使生成的raster对象能够准确表示该ggplot。我已创建了一个包含风向箭头的ggplot对象p,但将其转换为raster对象后重新绘制,结果不符合预期。我预期得到的raster对象仅包含0和1两个值,且能在经纬度坐标系下正确呈现箭头,但实际结果不符,请问哪里操作出错了?

原代码(存在错误)

# 包名拼写错误:ratser → raster;ggplot → ggplot2
library(ratser)
library(ggplot)

p <- ggplot(wind_data, aes(x = lon, y = lat)) +
  geom_segment(aes(xend = lon + 0.1, yend = lat + 0.1),
               arrow = arrow(length = unit(0.1, "cm")), size = 0.25)   

p <- p + theme_void() + 
  coord_cartesian(xlim = c(3.604383, 14.60482), ylim = c(47.07157 ,54.73807 )) + 
  theme(panel.border = element_blank(), 
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(), 
        axis.line = element_line(colour = "black") )

ggsave(plot=p, "my_ggplot.tiff", device = "tiff")
raster <- raster::raster("my_ggplot.tiff") # OR stack("my_ggplot.tiff") for colored images
lat_long <- ggplot_build(p)$layout$panel_params[[1]][c("x.range","y.range")]

extent(raster) <- c(lat_long$x.range,lat_long$y.range)
projection(raster) <- CRS("+proj=longlat +datum=WGS84")

附wind_data数据框

wind_data <- structure(list(lon = c(8.87312091729266, 8.71871388830953, 10.5679127453358, 
10.7216122406487, 10.4141464047873, 10.5679127453358, 10.1064188710028, 
11.3357135330171, 11.4890576651767, 11.1822955254471), lat = c(54.6482360923283, 
54.5584019137964, 54.2888913181823, 54.2888913181823, 54.1990517614177, 
54.1990517614177, 54.0193686018903, 53.6599860593553, 53.6599860593553, 
53.5701370357575), dd = c(241, 238, 247, 240, 240, 246, 247, 
246, 245, 247)), class = "data.frame", row.names = c(NA, -10L
))

问题分析与修正方案

核心错误点

  1. 包名拼写错误:ratser应为raster,ggplot应为ggplot2,错误的包名会导致代码无法正常运行。
  2. 坐标匹配错位:直接将ggplot的x/y范围赋值给raster的extent会导致图形拉伸或偏移,因为ggsave保存的图片像素宽高比与地理坐标范围比例不匹配。
  3. 未生成二值图像:默认保存的tiff是灰度/彩色格式,无法直接得到仅含0和1的raster对象。

修正后的代码

library(raster)
library(ggplot2)

# 生成带风向箭头的ggplot对象
p <- ggplot(wind_data, aes(x = lon, y = lat)) +
  geom_segment(aes(xend = lon + 0.1, yend = lat + 0.1),
               arrow = arrow(length = unit(0.1, "cm")), size = 0.25, color = "black") +
  theme_void() + 
  coord_cartesian(xlim = c(3.604383, 14.60482), ylim = c(47.07157 ,54.73807 )) + 
  theme(panel.border = element_blank(), 
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(), 
        axis.line = element_line(colour = "black"),
        plot.background = element_rect(fill = "white")) # 设置白色背景方便二值转换

# 获取ggplot的地理坐标范围与宽高比
plot_params <- ggplot_build(p)$layout$panel_params[[1]]
x_range <- plot_params$x.range
y_range <- plot_params$y.range
aspect_ratio <- diff(x_range)/diff(y_range)

# 保存为匹配宽高比的高分辨率tiff
ggsave(plot = p, 
       filename = "my_ggplot_binary.tiff", 
       device = "tiff",
       width = 10, 
       height = 10/aspect_ratio, # 匹配地理坐标的宽高比
       dpi = 300, # 高分辨率保证箭头细节
       bg = "white")

# 读取图片并转换为二值raster
r <- raster("my_ggplot_binary.tiff")
# 将灰度值转换为0(白色背景)和1(黑色箭头)
r <- calc(r, function(x) ifelse(x < 255, 1, 0))

# 设置正确的地理范围与投影
extent(r) <- c(x_range, y_range)
projection(r) <- CRS("+proj=longlat +datum=WGS84")

# 查看结果
plot(r)

关键说明

  • 宽高比匹配:通过计算地理坐标的宽高比,设置图片的保存尺寸,避免图形拉伸变形。
  • 二值转换:利用calc函数将灰度图像转换为仅含0和1的二值raster,符合预期需求。
  • 高分辨率保存:设置dpi=300确保箭头细节不会丢失,栅格化后箭头轮廓清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:00:58