如何纵向合并3个base R柱状图?cowplot报错求助
解决base R柱状图合并的报错问题
你遇到的警告Cannot convert object of class matrixarray into a grob,原因是**barplot()函数返回的不是绘图对象,而是柱子中心位置的坐标矩阵**,而cowplot::plot_grid()需要传入图形对象(grob),因此无法识别。
以下是两种可行的解决方案:
方案一:保留base R绘图,捕获图形对象再合并
每次调用barplot()绘制完成后,用recordPlot()捕获当前的绘图对象,再传给plot_grid():
# 读取第一个数据并绘图,捕获图形对象 k <- readr::read.csv("maxcor_r_p.csv", TRUE, ",") cols <- c("azure3", "#003f5c")[(k$p < 0.05) + 1] barplot( k$r, names.arg = k$parameter, ylab = "Correlation coefficient", col = cols, main = expression("T"[max]), las = 2 ) maxi_plot <- recordPlot() # 保存当前绘图 # 第二个图 l <- readr::read.csv("meancor_r_p.csv", TRUE, ",") cols <- c("azure3", "#27e52a")[(l$p < 0.05) + 1] barplot( l$r, names.arg = l$parameter, ylab = "Correlation coefficient", col = cols, main = expression("T"[mean]), las = 2 ) meany_plot <- recordPlot() # 第三个图 m <- readr::read.csv("precipcor_r_p.csv", TRUE, ",") cols <- c("azure3", "#27bac6")[(m$p < 0.05) + 1] barplot( m$r, names.arg = m$parameter, ylab = "Correlation coefficient", col = cols, main = expression("Precipitation"), las = 2 ) preci_plot <- recordPlot() # 纵向合并三个图形 cowplot::plot_grid( maxi_plot, meany_plot, preci_plot, ncol = 1, align = "v", axis = "lr" )
方案二:用ggplot2重写代码(更简洁易维护)
以下代码完全对应你原来的需求,且后续调整更灵活:
library(tidyverse) # 合并三个数据集,添加分组标识 df <- bind_rows( read_csv("maxcor_r_p.csv") %>% mutate(group = "T_max"), read_csv("meancor_r_p.csv") %>% mutate(group = "T_mean"), read_csv("precipcor_r_p.csv") %>% mutate(group = "Precipitation") ) %>% mutate( # 按p值和分组设置填充颜色 fill_color = case_when( group == "T_max" & p < 0.05 ~ "#003f5c", group == "T_max" & p >= 0.05 ~ "azure3", group == "T_mean" & p < 0.05 ~ "#27e52a", group == "T_mean" & p >= 0.05 ~ "azure3", group == "Precipitation" & p < 0.05 ~ "#27bac6", group == "Precipitation" & p >= 0.05 ~ "azure3" ) ) # 绘制纵向排列的柱状图 ggplot(df, aes(x = parameter, y = r, fill = fill_color)) + geom_col() + scale_fill_identity() + # 使用自定义颜色,不生成图例 facet_wrap(~group, ncol = 1) + # 纵向分面展示三个图 labs(y = "Correlation coefficient") + theme_bw() + theme( axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5), # 旋转x轴标签 strip.text = element_text(face = "bold") # 设置分面标题样式 )
两种方案对比
- 方案一:完全保留base R的绘图风格,无需学习新语法,适合快速修改现有代码。
- 方案二:代码更简洁,ggplot2的图形元素(颜色、标签、布局)调整更灵活,适合长期维护或后续需要修改图形样式的场景。
内容的提问来源于stack exchange,提问作者doggyZ
相关产品推荐
相关产品推荐

