You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:32:07