ggplot中geom_raster绘图出现空白区域的问题排查与解决
2D插值图出现数据空白区域的原因及解决方法
问题背景
用户的数据框如下:
Hoehe 75 65 50 35 20 5 1 51.5 9.5 10.5 10.0 8.1 9.8 8.8 2 41.5 10.9 11.1 10.9 9.7 11.1 9.9 3 31.5 10.7 11.0 11.3 10.6 10.2 9.5 4 21.5 9.7 10.1 10.2 11.1 9.8 9.0 5 11.5 9.2 9.6 9.2 10.9 8.9 8.8 6 1.5 7.7 8.0 8.6 10.6 7.3 7.2
用户尝试绘制2D插值图,使用的代码如下:
library (ggplot2) data_reshape <- data %>% pivot_longer( cols = `75`:`5`, names_to = "Entfernung", values_to = "value" ) data_reshape$Entfernung = as.numeric(data_reshape$Entfernung) ggplot(data_reshape, aes(Entfernung, Hoehe)) + geom_raster(aes(fill = value), interpolate = TRUE) + coord_cartesian(ylim = c(0, 58)) + #set lower and upper limits of your y-axis scale_fill_gradient(low= "yellow", high ="red")
遇到的问题:生成的图中40cm位置存在数据空白区域。
原因分析
- 数据点间隔不均:
Entfernung的数值为75、65、50、35、20、5,其中50到35之间的间隔是15,远大于其他相邻点的10间隔(除20到5)。geom_raster依赖规则网格绘制,间隔过大的区域没有足够的数据点支撑,插值无法覆盖,就会出现空白。 - 插值能力有限:
geom_raster的interpolate=TRUE仅对相邻网格单元做简单线性插值,没法填补数据点稀疏导致的空白区域,因为该区域没有对应的原始网格单元。
解决方法
方法1:生成均匀插值网格(推荐)
使用akima包的interp函数,先把原始非均匀数据插值成均匀间隔的网格数据,再绘图:
library(ggplot2) library(tidyr) library(dplyr) library(akima) # 数据重塑步骤不变 data_reshape <- data %>% pivot_longer( cols = `75`:`5`, names_to = "Entfernung", values_to = "value" ) %>% mutate(Entfernung = as.numeric(Entfernung)) # 生成x轴间隔1、y轴间隔1的均匀插值网格 interp_result <- interp( x = data_reshape$Entfernung, y = data_reshape$Hoehe, z = data_reshape$value, xo = seq(min(data_reshape$Entfernung), max(data_reshape$Entfernung), by = 1), yo = seq(min(data_reshape$Hoehe), max(data_reshape$Hoehe), by = 1) ) # 转换为ggplot可用的数据框格式 interp_df <- as.data.frame(interp_result) %>% pivot_longer(cols = -y, names_to = "Entfernung", values_to = "value") %>% mutate(Entfernung = as.numeric(Entfernung)) %>% rename(Hoehe = y) # 绘图,处理可能的NA值 ggplot(interp_df, aes(Entfernung, Hoehe)) + geom_raster(aes(fill = value), interpolate = TRUE) + coord_cartesian(ylim = c(0, 58)) + scale_fill_gradient(low = "yellow", high = "red", na.value = "white")
方法2:改用等高线填充图
如果不需要严格的栅格图,geom_contour_filled可以更自然地展示插值结果,不会出现空白:
ggplot(data_reshape, aes(Entfernung, Hoehe, z = value)) + geom_contour_filled(bins = 20) + # bins控制填充的精度,数值越大越精细 coord_cartesian(ylim = c(0, 58)) + scale_fill_viridis_d(option = "YlOrRd") # 配色接近原需求的黄红渐变
内容的提问来源于stack exchange,提问作者Znerky
相关产品推荐
相关产品推荐

