ggplot2绘制SPI值时geom_bar缺失值空白的解决方法
解决ggplot2绘制SPI图表出现缺失值空白的问题
可能原因
图表中的空白区域通常是因为数据中存在SPI_rrP为NA的行,或者x轴变量tperiod作为连续数值时存在时间间隔(比如缺失部分月份的记录),导致ggplot在对应位置留白。
解决方案
1. 过滤数据中的缺失值
如果数据中存在SPI_rrP为NA的行,直接过滤掉这些行即可消除空白。可以用基础R或dplyr实现:
基础R写法:
# 先过滤缺失值 df_clean <- df[!is.na(df$SPI_rrP), ] # 绘图 ggplot(df_clean)+ geom_bar(aes(x=tperiod, y=SPI_rrP, fill=sign), stat = "identity")+ scale_fill_manual(values=c("pos"="darkblue","neg"="red"))+ scale_y_continuous(limits=c(-4,4), breaks = seq(-4, 4, 0.5))+ scale_x_continuous(expand=c(0,0), breaks=seq(1971,2020,4))+ labs(y="Plaisance RR Station (SPI-12)", x="Month/Year")+ theme(axis.title = element_text(face="bold.italic", size=8), axis.title.y =element_text(face="bold.italic", size=8), axis.text.x = element_text(size=8,color = "#000000",hjust=0.6), axis.text.y = element_text(size=8, color="#000000"), axis.line = element_line(size=0.2,color="#000000"), plot.title = element_text(vjust=-10,hjust=0.01,size=10), legend.position = "none")
dplyr写法:
library(dplyr) ggplot(df %>% filter(!is.na(SPI_rrP)))+ geom_bar(aes(x=tperiod, y=SPI_rrP, fill=sign), stat = "identity")+ # 后续代码与原代码一致
2. 将x轴变量转为离散因子
如果数据中确实存在时间间隔(比如缺失部分月份),但希望柱子紧密排列不留空白,可以将tperiod转为离散因子,让每个存在的时间点作为独立类别:
ggplot(df)+ geom_bar(aes(x=factor(tperiod), y=SPI_rrP, fill=sign), stat = "identity")+ scale_fill_manual(values=c("pos"="darkblue","neg"="red"))+ scale_y_continuous(limits=c(-4,4), breaks = seq(-4, 4, 0.5))+ # 调整x轴刻度,只显示每4年的标记 scale_x_discrete(breaks = factor(seq(1971,2020,4)), labels = seq(1971,2020,4))+ labs(y="Plaisance RR Station (SPI-12)", x="Month/Year")+ theme(axis.title = element_text(face="bold.italic", size=8), axis.title.y =element_text(face="bold.italic", size=8), axis.text.x = element_text(size=8,color = "#000000",hjust=0.6), axis.text.y = element_text(size=8, color="#000000"), axis.line = element_line(size=0.2,color="#000000"), plot.title = element_text(vjust=-10,hjust=0.01,size=10), legend.position = "none")
3. 将时间转为Date格式优化连续轴显示
如果tperiod是年份+月份的数值(比如1971.01代表1971年1月),可以将其转为Date类型,让ggplot更好地处理时间序列,避免不必要的空白:
# 先将tperiod转为Date格式 df$tperiod_date <- as.Date(paste0(floor(df$tperiod), "-", round((df$tperiod - floor(df$tperiod))*12), "-01")) # 绘图 ggplot(df %>% filter(!is.na(SPI_rrP)))+ geom_bar(aes(x=tperiod_date, y=SPI_rrP, fill=sign), stat = "identity")+ scale_fill_manual(values=c("pos"="darkblue","neg"="red"))+ scale_y_continuous(limits=c(-4,4), breaks = seq(-4, 4, 0.5))+ scale_x_date(breaks = seq(as.Date("1971-01-01"), as.Date("2020-01-01"), by="4 years"), labels = function(x) format(x, "%Y"))+ labs(y="Plaisance RR Station (SPI-12)", x="Month/Year")+ theme(axis.title = element_text(face="bold.italic", size=8), axis.title.y =element_text(face="bold.italic", size=8), axis.text.x = element_text(size=8,color = "#000000",hjust=0.6), axis.text.y = element_text(size=8, color="#000000"), axis.line = element_line(size=0.2,color="#000000"), plot.title = element_text(vjust=-10,hjust=0.01,size=10), legend.position = "none")
内容的提问来源于stack exchange,提问作者user15556454
相关产品推荐
相关产品推荐

