栅格化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 ))
问题分析与修正方案
核心错误点
- 包名拼写错误:
ratser应为raster,ggplot应为ggplot2,错误的包名会导致代码无法正常运行。 - 坐标匹配错位:直接将ggplot的x/y范围赋值给raster的extent会导致图形拉伸或偏移,因为ggsave保存的图片像素宽高比与地理坐标范围比例不匹配。
- 未生成二值图像:默认保存的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
相关产品推荐
相关产品推荐

