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

如何为Bar+Line+Ribbon图表添加合适图例并修复颜色问题

问题描述

改编代码制作包含bar、line、ribbon的ggplot2图表时遇到两个问题:

  • 所有元素(bar、line、ribbon)背景均被填充为steelblue,未显示各自对应颜色
  • 图例中所有元素均以线条表示,bar应显示为steelblue填充方块,ribbon显示为灰色填充方块,line显示为线条

原代码如下:

suppressPackageStartupMessages(library(ggplot2))

zz <- tempfile()
cat("
FECHA H_SOLAR;DIR_M;VEL_M;TEMP_M;HR;PRECIP
01/06/14 00:50:00;314.3;1.9;14.1;68.0;-99.9
01/06/14 01:50:00;322.0;1.6;13.3;68.9;-99.9
01/06/14 02:50:00;303.5;2.1;12.3;70.9;-99.9
01/06/14 03:50:00;302.4;1.6;11.6;73.1;-99.9
01/06/14 04:50:00;306.5;1.2;10.9;76.4;-99.9
01/06/14 05:50:00;317.1;0.8;12.6;71.5;-99.9
01/06/14 06:50:00;341.8;0.0;17.1;58.8;-99.9
01/06/14 07:50:00;264.6;1.2;21.8;44.9;-99.9
01/06/14 08:50:00;253.8;2.9;24.7;32.2;-99.9
01/06/14 09:50:00;254.6;3.7;26.7;27.7;-99.9
01/06/14 10:50:00;250.7;4.3;28.3;24.9;-99.9
01/06/14 11:50:00;248.5;5.3;29.1;22.6;-99.9
01/06/14 12:50:00;242.8;4.7;30.3;20.4;-99.9
01/06/14 13:50:00;260.7;4.9;31.3;17.4;-99.9
01/06/14 14:50:00;251.8;5.1;31.9;17.1;-99.9
01/06/14 15:50:00;258.1;4.6;32.4;15.3;-99.9
01/06/14 16:50:00;254.3;5.7;32.4;14.0;-99.9
01/06/14 17:50:00;252.5;4.6;32.0;14.1;-99.9
01/06/14 18:50:00;257.4;3.8;31.1;14.9;-99.9
01/06/14 19:50:00;135.8;4.2;26.0;41.2;-99.9
01/06/14 20:50:00;126.0;1.7;23.5;48.7;-99.9
01/06/14 21:50:00;302.8;0.7;21.6;53.9;-99.9
01/06/14 22:50:00;294.2;1.1;19.3;67.4;-99.9
01/06/14 23:50:00;308.5;1.0;17.5;72.4;-99.9
", file=zz)

datos=read.csv(zz, sep=";", header=TRUE, na.strings="-99.9")

datos$dia=as.POSIXct(datos[,1], format="%y/%m/%d %H:%M:%S")

par(mar = c(5, 4, 4, 4) + 0.25)

ggplot(data = datos, aes(x = dia, y = TEMP_M)) +
  geom_bar(stat = "identity", fill = "steelblue", aes(color = "agenda")) +
  geom_ribbon(aes(ymin = TEMP_M*0.5, ymax = TEMP_M*1.5, color = "limite"), data = datos, alpha = 0.25) +
  geom_line(aes(y = TEMP_M, color = "control"), data = datos) +
  labs(x = "Hour", y = "Temperature") +
  scale_colour_manual(" ", values=c(agenda = "steelblue", control = "black", 
                               limite = "gray"),
                      labels = c(agenda = "T1", 
                                 control = "T2", 
                                 limite = "Temperature interval")) + 
  scale_fill_manual(values=c("agenda"="steelblue", "control"="black", "limite"="gray"), 
                    guide="none") + 
  theme(legend.key = element_rect(fill = "white"))
解决方案

问题根源在于没有为不同图层正确区分color和fill映射,以及图例的guide设置错误。修改后的代码如下:

suppressPackageStartupMessages(library(ggplot2))

zz <- tempfile()
cat("
FECHA H_SOLAR;DIR_M;VEL_M;TEMP_M;HR;PRECIP
01/06/14 00:50:00;314.3;1.9;14.1;68.0;-99.9
01/06/14 01:50:00;322.0;1.6;13.3;68.9;-99.9
01/06/14 02:50:00;303.5;2.1;12.3;70.9;-99.9
01/06/14 03:50:00;302.4;1.6;11.6;73.1;-99.9
01/06/14 04:50:00;306.5;1.2;10.9;76.4;-99.9
01/06/14 05:50:00;317.1;0.8;12.6;71.5;-99.9
01/06/14 06:50:00;341.8;0.0;17.1;58.8;-99.9
01/06/14 07:50:00;264.6;1.2;21.8;44.9;-99.9
01/06/14 08:50:00;253.8;2.9;24.7;32.2;-99.9
01/06/14 09:50:00;254.6;3.7;26.7;27.7;-99.9
01/06/14 10:50:00;250.7;4.3;28.3;24.9;-99.9
01/06/14 11:50:00;248.5;5.3;29.1;22.6;-99.9
01/06/14 12:50:00;242.8;4.7;30.3;20.4;-99.9
01/06/14 13:50:00;260.7;4.9;31.3;17.4;-99.9
01/06/14 14:50:00;251.8;5.1;31.9;17.1;-99.9
01/06/14 15:50:00;258.1;4.6;32.4;15.3;-99.9
01/06/14 16:50:00;254.3;5.7;32.4;14.0;-99.9
01/06/14 17:50:00;252.5;4.6;32.0;14.1;-99.9
01/06/14 18:50:00;257.4;3.8;31.1;14.9;-99.9
01/06/14 19:50:00;135.8;4.2;26.0;41.2;-99.9
01/06/14 20:50:00;126.0;1.7;23.5;48.7;-99.9
01/06/14 21:50:00;302.8;0.7;21.6;53.9;-99.9
01/06/14 22:50:00;294.2;1.1;19.3;67.4;-99.9
01/06/14 23:50:00;308.5;1.0;17.5;72.4;-99.9
", file=zz)

datos=read.csv(zz, sep=";", header=TRUE, na.strings="-99.9")

datos$dia=as.POSIXct(datos[,1], format="%y/%m/%d %H:%M:%S")

# 核心修改:区分color和fill映射,设置图例guide参数
ggplot(data = datos, aes(x = dia)) +
  # 柱状图:用fill映射,color设为NA避免边框干扰
  geom_bar(aes(y = TEMP_M, fill = "agenda"), stat = "identity", color = NA) +
  # 带状区域:用fill映射,设置alpha,color设为NA
  geom_ribbon(aes(ymin = TEMP_M*0.5, ymax = TEMP_M*1.5, fill = "limite"), alpha = 0.25, color = NA) +
  # 折线图:用color映射
  geom_line(aes(y = TEMP_M, color = "control")) +
  labs(x = "Hour", y = "Temperature") +
  # 统一图例名称,分别设置fill和color的取值与标签
  scale_fill_manual(name = "", 
                    values = c(agenda = "steelblue", limite = "gray"),
                    labels = c(agenda = "T1", limite = "Temperature interval")) +
  scale_colour_manual(name = "", 
                      values = c(control = "black"),
                      labels = c(control = "T2")) +
  # 合并图例,指定每个图例项的样式
  guides(
    fill = guide_legend(override.aes = list(linetype = 0)),
    color = guide_legend(override.aes = list(fill = NA))
  ) +
  theme(legend.key = element_rect(fill = "white"))

修改说明

  1. 元素颜色问题解决:

    • 柱状图和带状区域(ribbon)使用fill映射而非color,同时将color设为NA避免不必要的边框
    • 折线图保持color映射,确保线条颜色正确
  2. 图例样式问题解决:

    • 拆分scale_fill_manual和scale_colour_manual,分别对应填充型元素和线条型元素
    • 使用guides()函数统一图例,通过override.aes强制设置图例项样式:
      • 填充型元素(bar、ribbon)设置linetype = 0,隐藏线条,只显示填充方块
      • 线条型元素(line)设置fill = NA,只显示线条

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:17:04