如何将多层分组条形图最内层Strategy改为堆叠条形?
解决多层分组条形图内层Strategy堆叠问题
核心修改思路
将最内层的Strategy改为堆叠,需要先对Strategy进行堆叠,再对Size+Metric的组合进行分组并列,通过嵌套position_stack()到position_dodge2()实现,同时调整分组映射确保层级正确。
修改后的完整代码
library(ggplot2) library(ggpattern) library(tidyverse) mydata <- structure(list(Metric = structure(c(2L, 1L, 3L, 2L, 1L, 3L, 2L, 1L, 3L, 2L, 1L, 3L, 2L, 1L, 3L, 2L, 1L, 3L, 2L, 1L, 3L, 2L, 1L, 3L, 2L, 1L, 3L, 2L, 1L, 3L), levels = c("Median", "Average", "Copula"), class = "factor"), Model = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L), levels = c("Model1", "Model2", "Model3"), class = "factor"), Strategy = c("Exact", "Exact", "Exact", "Exact", "Exact", "Exact", "Exact", "Exact", "Exact", "Exact", "Exact", "Exact", "Relaxed", "Relaxed", "Relaxed", "Relaxed", "Relaxed", "Relaxed", "Relaxed", "Relaxed", "Relaxed", "Relaxed", "Relaxed", "Relaxed", "Exact", "Exact", "Exact", "Relaxed", "Relaxed", "Relaxed"), Size = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), levels = c("Model1", "Small", "Medium", "Large"), class = "factor"), Score = c(0.168041526339948, 0.5572494356893, 0.384942351374775, 0.327734317164868, 0.11144915339537, 0.604394054040313, 0.124633444240317, 0.279732553754002, 0.228201881283894, 0.0153298925142735, 0.128981558606029, 0.0933819285128266, 0.534035353455693, 0.807516399072483, 0.86791948764585, 0.829708693316206, 0.602100674761459, 0.70368835888803, 0.897488264366984, 0.29460092424415, 0.577609919011593, 0.630979274399579, 0.512015897547826, 0.505023914156482, 0.236885007470846, 0.560424553928897, 0.599731565685943, 0.910147710936144, 0.791147409472615, 0.755704769166186)), row.names = c(NA, -30L), class = c("tbl_df", "tbl", "data.frame")) # 重新排序因子 mydata$Size <- factor(mydata$Size, levels = c("Model1", "Small", "Medium", "Large")) mydata$Metric <- factor(mydata$Metric, levels = c("Median", "Average", "Copula")) mydata$Model <- factor(mydata$Model, levels = c("Model1", "Model2", "Model3")) mydata$Strategy <- factor(mydata$Strategy, levels = c("Exact", "Relaxed")) # 定义配色:为每个Size的两个Strategy设置深浅色 palette <- c( "Model1_Exact" = "darkgreen", "Model1_Relaxed" = "forestgreen", "Small_Exact" = "lightblue", "Small_Relaxed" = "skyblue", "Medium_Exact" = "blue", "Medium_Relaxed" = "royalblue", "Large_Exact" = "darkblue", "Large_Relaxed" = "navy" ) pattern_map <- c("Median" = "none", "Average" = "circle", "Copula" = "stripe") density_map <- c("Median" = 0, "Average" = 0.05, "Copula" = 0.05) angle_map <- c("Median" = 0, "Average" = 45, "Copula" = 90) # 绘制堆叠+分组的条形图 ggplot(mydata, aes( x = Model, y = Score, fill = interaction(Size, Strategy), # 用Size+Strategy组合区分堆叠部分 pattern = Metric, pattern_density = Metric, group = interaction(Size, Metric) # 确保每个Size+Metric组内堆叠Strategy )) + geom_bar_pattern( stat = "identity", # 先堆叠Strategy,再对Size+Metric组进行并列 position = position_dodge2(position_stack(), padding = 0.15, preserve = "single"), width = 1, color = "black", pattern_fill = "white", pattern_spacing = 0.05, pattern_color = "black" # 修改为黑色更清晰区分图案 ) + # 应用自定义图案、密度、角度 scale_pattern_manual(values = pattern_map) + scale_pattern_density_manual(values = density_map) + scale_pattern_angle_manual(values = angle_map) + # 应用配色 scale_fill_manual(values = palette, name = "尺寸 & 策略") + labs(x = "模型", y = "", pattern = "指标") + theme_classic() + theme( axis.text.x = element_text(hjust = 1), legend.position = "right", legend.box = "vertical", panel.border = element_rect(color = "black", fill = NA, size = 0.5) ) + guides(pattern = guide_legend(override.aes = list(fill = NA)))
关键改动说明
- 分组与堆叠逻辑:通过
group = interaction(Size, Metric)指定分组单元,让每个Size+Metric组合内的Strategy堆叠,再通过position_dodge2(position_stack(), ...)实现分组并列。 - 堆叠区分:将
fill映射为interaction(Size, Strategy),为每个尺寸的两种策略设置深浅配色,清晰区分堆叠部分。 - 图案优化:补充
scale_pattern_angle_manual应用预设的图案角度,并将pattern_color改为黑色,提升图案辨识度。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

