如何用ggplot2为不同区域和粒径的箱线图设置颜色与图案?
问题描述
我拥有墨西哥湾5个区域的两类浮游植物('WSW'和'<20 µm')叶绿素a生物量数据,希望绘制箱线图实现以下效果:
- 每个区域使用指定颜色填充箱线图
- 通过图案区分不同粒径类
但当前代码未达到预期效果,尝试将fill替换为region也无效。
原代码
patterns <- c('<20 µm' = 'crosshatch', 'WSW' = 'none') region_colors <- c('WFS' = 'darkgreen', 'TLS' = 'cyan3', 'EMS' = 'orangered2', 'CB' = 'yellow3', 'YC/FS' = 'plum2') surf.box.fig <- ggplot(surf_box, aes(x=region, y = Chla, fill = Size)) + geom_boxplot() + scale_pattern_fill_manual(values = region_colors) + scale_pattern_manual(values = patterns) + theme(panel.background = element_blank(), legend.position = 'top', axis.line.x = element_line(color="black", size = 1), axis.line.y = element_line(color="black", size = 1), plot.title = element_text(margin = margin(t = 0, r = 0, b = 0, l = 0), hjust = 0.5, size = 15, face = 'bold'), legend.key=element_blank(), legend.title = element_text(margin = margin(t = 0, r = 0, b = 0, l = 0), size=10, face = "bold")) + labs(x=expression(bold(paste("Regions of the Gulf of Mexico"))), y=expression(bold(paste("Chl-",bolditalic ("a"), " biomass (µg L"^'-1',')')), title = expression(bold(paste("Surface Chl-", bolditalic ("a"), ' Biomass'))))
当前结果图

数据结构
structure(list(Size = c("WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "WSW", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm", "<20 µm"), Chla = c(0.0158553374250702, 0.0681835535205316, 1.69758559710116, 0.38623655064116, 0.18999889055035, 0.0475280806809533, 0.0518441820414833, 1.38653044994664, 0.811092911431239, 0.0627435113039509, 0.0600206049988672, 0.76576153727216, 0.0131834301368552, 0.0139065718743198, 0.0801018539960821, 0.0476673877342761, 0.0170883088104008, 0.0353610062847066, 0.0862740442259294, 0.54829425475163, 0.354272113611421, 0.0419050024352668, 0.14044768258058, 0.0693766746908316, 0.0539223064788303, 0.0159113633523673, 0.033895686014726, 0.592754310802978, 0.251252264220314, 0.177521351469432, 0.0574533958589567, 0.0447197172789116, 1.75919476060424, 0.789171481392557, 0.104392221393643, 0.0613148498505948, 0.646043888487357, 0.0200254634990205, 0.0165766336741892, 0.0619120579844718, 0.0324340598144779, 0.0264756363476934, 0.0276985089356931, 0.105004593301296, 0.288904529677619, 0.295226761342851, 0.0419623280199936, 0.10089302911911, 0.0580098748827292, 0.0647851594974109 ), region = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L), .Label = c("WFS", "TLS", "EMS", "CB", "YC/FS"), class = c("ordered", "factor")), depth_name = c("Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface", "Surface"), distance = c("Offshore", "Offshore", "Nearshore", "Nearshore", "Intermediate", "Offshore", "Offshore", "Nearshore", "Nearshore", "Intermediate", "Intermediate", "Nearshore", "Nearshore", "Intermediate", "Offshore", "Intermediate", "Offshore", "Offshore", "Intermediate", "Nearshore", "Nearshore", "Offshore", "Intermediate", "Offshore", "Intermediate", "Offshore", "Offshore", "Nearshore", "Nearshore", "Intermediate", "Offshore", "Offshore", "Nearshore", "Nearshore", "Intermediate", "Intermediate", "Nearshore", "Nearshore", "Intermediate", "Offshore", "Intermediate", "Offshore", "Offshore", "Intermediate", "Nearshore", "Nearshore", "Offshore", "Intermediate", "Offshore", "Intermediate")), row.names = c(NA, -50L), class = c("tbl_df", "tbl", "data.frame"))
解决方案
问题核心在于:
- 默认的
geom_boxplot()不支持图案填充,必须使用ggpattern包的geom_boxplot_pattern() - 美学映射错误:需要把
fill绑定到region来控制区域颜色,pattern绑定到Size来区分粒径类,同时要设置pattern_fill让图案可见
修正后代码
首先确保安装并加载ggpattern包:
# 安装包(首次使用) install.packages("ggpattern") # 加载包 library(ggpattern) library(ggplot2) patterns <- c('<20 µm' = 'crosshatch', 'WSW' = 'none') region_colors <- c('WFS' = 'darkgreen', 'TLS' = 'cyan3', 'EMS' = 'orangered2', 'CB' = 'yellow3', 'YC/FS' = 'plum2') surf.box.fig <- ggplot(surf_box, aes(x = region, y = Chla, fill = region, pattern = Size)) + # 使用带图案的箱线图geom geom_boxplot_pattern( pattern_fill = "black", # 图案颜色,和填充色形成对比 pattern_density = 0.1, # 图案密度,可调整 pattern_spacing = 0.05 # 图案间距,可调整 ) + # 设置区域填充颜色 scale_fill_manual(values = region_colors) + # 设置粒径类的图案 scale_pattern_manual(values = patterns) + theme( panel.background = element_blank(), legend.position = 'top', axis.line.x = element_line(color="black", size = 1), axis.line.y = element_line(color="black", size = 1), plot.title = element_text(margin = margin(t = 0, r = 0, b = 0, l = 0), hjust = 0.5, size = 15, face = 'bold'), legend.key=element_blank(), legend.title = element_text(margin = margin(t = 0, r = 0, b = 0, l = 0), size=10, face = "bold") ) + labs( x=expression(bold(paste("墨西哥湾区域"))), y=expression(bold(paste("叶绿素a生物量 (µg L"^'-1',')')), title = expression(bold(paste("表层叶绿素a生物量"))), fill = "区域", pattern = "粒径类" ) # 绘制图 print(surf.box.fig)
关键修改说明
- 替换
geom_boxplot()为geom_boxplot_pattern(),启用图案填充功能 - 调整美学映射:
fill = region控制区域颜色,pattern = Size控制粒径图案 - 添加
pattern_fill参数设置图案颜色,确保在不同填充色上都能清晰显示 - 调整
scale_fill_manual对应区域颜色,scale_pattern_manual对应粒径图案 - 优化了标签的中文显示,更直观
内容的提问来源于stack exchange,提问作者garfunkl_30
相关产品推荐
相关产品推荐

