ggplot绘图技术问题:无法同时实现条形位置对齐与自定义配色
解决方案
问题1:实现样本条形在x轴汇合且配色正确
通过在aes中添加group = Sample,让position_dodge()按样本分组,同一样本的地上/地下条形会在x轴同一位置上下对齐,不同样本的条形在处理组内左右错开。同时保留fill = FillGroup维持自定义配色方案,确保每个样本的地上、地下部分颜色区分正确。
问题2:y轴负数值显示为正整数
自定义y轴标签函数,对所有y值取绝对值后取整,用round(abs(y))即可同时实现数值取整和负数值正显示,避免长小数问题。
修改后的完整代码
# Load libraries library(ggplot2) library(dplyr) library(scales) # Sample data with 2 samples and 3 treatments data <- data.frame( Sample = rep(c("Sample1", "Sample2"), each = 3), Treatment = rep(c("Treatment1", "Treatment2", "Treatment3"), times = 2), ShootLength = c(10, 12, 11, 9, 13, 14), RootLength = c(7, 6, 8, 6, 7, 9) ) # Add random variation to simulate repeated measurements set.seed(123) data_long <- data.frame( Sample = rep(data$Sample, each = 6), Treatment = rep(data$Treatment, each = 6), Type = rep(c("ShootLength", "RootLength"), times = 18), Length = c( rnorm(18, mean = rep(data$ShootLength, each = 3), sd = 1), rnorm(18, mean = rep(data$RootLength, each = 3), sd = 1) ) ) # Summarize data for mean and standard deviation data_summary <- data_long %>% group_by(Sample, Treatment, Type) %>% summarise( Mean = mean(Length), SD = sd(Length), .groups = "drop" ) # Mutate so RootLength is negative to appear below x axis data_summary <- data_summary %>% mutate( StackedOffset = ifelse(Type == "RootLength", -Mean, Mean), # Adjust for below-ground SD_Pos = SD, # Standard deviation remains positive FillGroup = paste(Sample, Type, sep = "_") # New variable for combined colors ) # Plot ggplot(data_summary, aes(x = Treatment, y = StackedOffset, fill = FillGroup, group = Sample)) + geom_bar(stat = "identity", position = position_dodge(width = 0.5), width = 0.4, color = "black") + geom_errorbar( aes( ymin = StackedOffset - SD_Pos, ymax = StackedOffset + SD_Pos ), position = position_dodge(width = 0.5), width = 0.2, color = "black" ) + scale_y_continuous( name = "Shoot Length (Above Ground)", breaks = seq(-max(data_summary$Mean + data_summary$SD), max(data_summary$Mean + data_summary$SD), by = 1), labels = function(y) round(abs(y)), # 自定义标签:取绝对值后取整 sec.axis = sec_axis(~ ., name = "Root Length (Below Ground)", labels = function(y) round(abs(y))) ) + scale_fill_manual( values = c( "Sample1_ShootLength" = "red", # Sample1 above ground "Sample1_RootLength" = "blue", # Sample1 below ground "Sample2_ShootLength" = "darkred", # Sample2 above ground "Sample2_RootLength" = "darkblue" # Sample2 below ground ) ) + theme_minimal() + theme( axis.text.x = element_text(angle = 45, hjust = 1), panel.grid.major.y = element_line(color = "gray", size = 0.5), panel.grid.major.x = element_blank() ) + labs( x = "Treatment", y = "Length", fill = "Sample & Type", title = "Shoot and Root Lengths by Treatment and Sample" )
内容的提问来源于stack exchange,提问作者JessF
相关产品推荐
相关产品推荐

