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

如何为ggplot绘制的图表添加额外图例?

问题描述

我用ggplot绘制了一幅柱状图,想给图中柱状图上方的深橙色(darkorange3)和深蓝色(steelblue4)小型置信区间(errorbar)添加对应颜色和文字的图例。尝试过相关方案但未成功,用annotate方法还导致图表压缩。实际图表中,翻转后的x轴每个类别对应8个误差棒,且“National average”线并不总是与柱状图顶部平行。调整color和fill的manual设置、添加新geom_point等方法都没用,求可行方案。

解决方案

核心思路是把误差棒的颜色映射到变量,而非直接硬编码color参数,让ggplot自动生成对应图例。具体步骤如下:

  • 单独整理误差棒数据:将所有置信区间数据提取为独立数据框,包含分组、位置、上下限等字段,统一用一个geom_errorbar绘制,避免多次调用。
  • 在aes中映射color:让误差棒颜色与评估阶段关联,同时指定对应颜色值。
  • 调整图例顺序与样式:确保新颜色图例和原有填充图例区分开,显示顺序符合需求。

修改后的完整代码

library(ggplot2)
library(dplyr)

# 生成示例数据
plot_data <- expand.grid(
    Arviointi = c("First Assessment", "Second Assessment"),
    Mittari = c("happy_share", "lonely_share", "self_satisfaction_share", "enjoyment_share")
)
plot_data <- plot_data %>%
    mutate(value = runif(n(), 0.15, 0.85))

# 自定义标签和回答选项
custom_labels <- c("statement1", "statement2", "question3?", "question4?")
ss <- data.frame(
    Mittari = unique(plot_data$Mittari),
    vastaukset = c("Agree/Strongly agree", "Yes", "Yes", "Often/Very often")
)

plot_data <- plot_data %>%
    left_join(ss, by = "Mittari") %>%
    mutate(facet = case_when(
        Mittari %in% c("happy_share", "lonely_share") ~ "Based on Teacher Assessments",
        Mittari %in% c("enjoyment_share", "self_satisfaction_share") ~ "Based on Child Self-Assessments"
    ))

# 单独整理误差棒数据(示例为happy_share,可扩展到所有Mittari)
error_data <- plot_data %>%
    filter(Mittari == "happy_share") %>%
    mutate(
        ymin = case_when(
            Arviointi == "First Assessment" ~ value - 0.05,
            Arviointi == "Second Assessment" ~ value - 0.08
        ),
        ymax = case_when(
            Arviointi == "First Assessment" ~ value + 0.09,
            Arviointi == "Second Assessment" ~ value + 0.04
        ),
        x_nudge = case_when(
            Arviointi == "First Assessment" ~ 0.1125,
            Arviointi == "Second Assessment" ~ -0.1125
        )
    )

# 绘制图表
ggplot(plot_data, aes(x = Mittari, y = value, fill = Arviointi)) +
    geom_col(position = position_dodge2(reverse = TRUE), width = 0.45, alpha = 0.85) +
    geom_vline(aes(xintercept = 0, color = "National Average")) +
    geom_text(aes(group = Mittari, y = 0.35, label = vastaukset), size = 3.4, hjust = 0.5, vjust = -2.1, colour = "grey8") +
    # 统一绘制误差棒,映射color到Arviointi
    geom_errorbar(
        data = error_data,
        aes(x = Mittari, ymin = ymin, ymax = ymax, color = Arviointi),
        position = position_nudge(x = error_data$x_nudge),
        width = 0,
        size = 1.5
    ) +
    geom_errorbar(data = plot_data, aes(x = Mittari, ymin = value, ymax = value, group = Arviointi, width = 0.45), position = position_dodge2(reverse = TRUE)) +
    # 同时设置fill和color的手动颜色值
    scale_fill_manual(
        values = c("First Assessment" = "steelblue", "Second Assessment" = "darkorange"),
        name = "Assessment"
    ) +
    scale_color_manual(
        values = c(
            "First Assessment" = "steelblue4",
            "Second Assessment" = "darkorange3",
            "National Average" = "black"
        ),
        name = "Legend"
    ) +
    facet_grid(facet ~., scales = "free_y", space = "free_y", switch = "y") +
    theme_minimal(base_family = "Arial") +
    coord_flip() +
    scale_y_continuous(
        labels = scales::percent_format(scale = 100),
        breaks = seq(0, 1, by = 0.1),
        minor_breaks = NULL,
        limits = c(0, 1)
    ) +
    scale_x_discrete(breaks = c("happy_share", "lonely_share", "self_satisfaction_share", "enjoyment_share"), labels = custom_labels) +
    labs(y = NULL, x = NULL) +
    # 调整图例顺序和样式
    guides(
        fill = guide_legend(order = 1, title = "Assessment"),
        color = guide_legend(order = 2, title = "Confidence Interval & National Average")
    ) +
    theme(
        legend.text = element_text(size = 10.5),
        legend.spacing.y = unit(-0.1, "cm"),
        panel.spacing = unit(3, "lines"),
        strip.text.y.left = element_blank()
    )

补充说明

  • 若要给所有Mittari添加误差棒,只需扩展error_data的筛选条件,补充每个类别的ymin、ymax和x_nudge规则。
  • 颜色映射到变量后,ggplot自动生成图例,无需手动添加annotate或额外geom元素,避免图表压缩问题。
  • 通过scale_color_manual可统一控制误差棒和“National Average”线的颜色,同时在图例中展示。

内容的提问来源于stack exchange,提问作者Billyboy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 13:34:54