多因子ggplot图表:如何在图例中正确实现图案样式?
解决ggplot2中Sequence图例第三个元素的显示问题
我已经完成了Practice和Focus两个参数的图例配置,但Sequence对应的第三个图例元素(标注为"practice")未按预期显示——我需要它呈现黑色填充的条纹图案。
示例数据集
df <- data.frame(Practice = factor(rep(c('A','B'), 216)), Focus = factor(rep(c("high","high","low","low"), each = 216)), Session = factor(rep(c(1:6), each=72)), Sequence = factor(rep(c('X','X','X','Y','Y','Y','Z','Z','Z'), 48)), Hand = factor(rep(c('L','R','R','L'), 108)), value = sample(0:100, 432, rep = TRUE)) %>% unite('group', c(Practice,Focus,Hand), remove=FALSE)
原绘图代码
ggplot(df, aes(x=Session, y=value, fill= Focus, pattern = Sequence)) + theme_classic() + facet_wrap(vars(group), nrow=4) + geom_boxplot_pattern(outlier.shape=NA, position='dodge', key_glyph = 'rect', aes(alpha = Practice, fill = Focus, pattern_density = Sequence, pattern_angle = Sequence), pattern = 'stripe', pattern_fill = 'white', pattern_colour = 'white', pattern_spacing = 0.02) + geom_point(size=0.25, position=position_jitterdodge(0.2), show.legend = FALSE) + scale_alpha_discrete(range = c(1,0.3)) + scale_fill_brewer(palette = "Set1") + scale_pattern_density_manual(values = c(0,0.05,0.05), labels=c('different','mirror','practice')) + scale_pattern_angle_manual(values = c(0,315,45), guide = "none") + guides(alpha = guide_legend(order=1, override.aes = list(fill='grey30', pattern='none')) ) + guides(fill = guide_legend(order=2, override.aes = list(pattern='none')) ) + guides(pattern_density = guide_legend(order=3, override.aes = list( fill='black',pattern = 'stripe', pattern_fill = 'white', pattern_colour = 'white', pattern_spacing = 0.02, pattern_density=0.05, pattern_angle=45) )) + #guides(pattern_angle = guide_legend(order=4, override.aes = list(fill='black', pattern_size=0.1)) ) + scale_y_continuous(breaks = seq(0,1500,200)) + ylab('Reaction time in ms') + geom_vline(xintercept=5.5, color = "grey", linetype="dotted" ) #+
解决方案
问题出在pattern_density图例的override.aes设置上——之前统一给所有图例条目设置了黑色填充,但实际上只需要给第三个条目(对应"practice")设置黑色,同时要确保每个条目的图案属性匹配对应Sequence水平的设置。
修改后的代码:
ggplot(df, aes(x=Session, y=value, fill= Focus, pattern = Sequence)) + theme_classic() + facet_wrap(vars(group), nrow=4) + geom_boxplot_pattern(outlier.shape=NA, position='dodge', key_glyph = 'rect', aes(alpha = Practice, fill = Focus, pattern_density = Sequence, pattern_angle = Sequence), pattern = 'stripe', pattern_fill = 'white', pattern_colour = 'white', pattern_spacing = 0.02) + geom_point(size=0.25, position=position_jitterdodge(0.2), show.legend = FALSE) + scale_alpha_discrete(range = c(1,0.3)) + scale_fill_brewer(palette = "Set1") + scale_pattern_density_manual(values = c(0,0.05,0.05), labels=c('different','mirror','practice')) + scale_pattern_angle_manual(values = c(0,315,45), guide = "none") + guides(alpha = guide_legend(order=1, override.aes = list(fill='grey30', pattern='none')) ) + guides(fill = guide_legend(order=2, override.aes = list(pattern='none')) ) + # 为每个图例条目单独指定样式 guides(pattern_density = guide_legend( order=3, override.aes = list( fill = c(scale_fill_brewer(palette = "Set1")$palette(2)[1], scale_fill_brewer(palette = "Set1")$palette(2)[1], "black"), # 前两个沿用Focus的填充色,第三个设为黑色 pattern = c("none", "stripe", "stripe"), pattern_fill = c(NA, "white", "white"), pattern_colour = c(NA, "white", "white"), pattern_density = c(0, 0.05, 0.05), pattern_angle = c(0, 315, 45) ) )) + scale_y_continuous(breaks = seq(0,100,20)) + # 匹配示例数据的value范围 ylab('Reaction time in ms') + geom_vline(xintercept=5.5, color = "grey", linetype="dotted" )
关键修改说明
- 在
pattern_density的override.aes中,为三个图例条目分别指定样式:- 前两个条目(different、mirror)沿用
scale_fill_brewer的默认填充色,保持和图表主体元素一致; - 第三个条目(practice)设置
fill='black',同时匹配对应的条纹参数(密度、角度等);
- 前两个条目(different、mirror)沿用
- 调整y轴刻度,使其匹配示例数据的
value范围(0-100),避免原代码中刻度范围过大的问题。
内容的提问来源于stack exchange,提问作者SDahm
相关产品推荐
相关产品推荐

