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

在ggplot分面图中绘制多组重叠折线并添加图例

问题描述

我正在用ggplot创建图表,需要在每个分面中显示两条重叠折线(分别代表实际运行小时均值、计划运行小时均值),同时在右侧添加图例区分两类折线。尝试过相关方法,但因需处理的是不同列而非同一变量内的分组,未能成功解决问题。注:当前案例中两条折线近乎一致,但其他场景下差异显著,故寻求帮助。

参考数据

structure(list(month_yr = c("2022-01", "2022-01", "2022-02", 
"2022-02", "2022-03", "2022-03", "2022-04", "2022-04", "2022-05", 
"2022-05", "2022-06", "2022-06", "2022-07", "2022-07", "2022-08", 
"2022-08", "2022-09", "2022-09", "2022-10", "2022-10", "2022-11", 
"2022-11", "2022-12", "2022-12", "2023-01", "2023-01", "2023-02", 
"2023-02"), plant_name = c("plant_f", "plant_s", "plant_f", "plant_s", 
"plant_f", "plant_s", "plant_f", "plant_s", "plant_f", "plant_s", 
"plant_f", "plant_s", "plant_f", "plant_s", "plant_f", "plant_s", 
"plant_f", "plant_s", "plant_f", "plant_s", "plant_f", "plant_s", 
"plant_f", "plant_s", "plant_f", "plant_s", "plant_f", "plant_s"
), avg_run_hours = c(15.0080608695652, 16.3453608247423, 14.7394112149533, 
16.1025555555556, 14.9570175438596, 15.7327777777778, 17.0074257425743, 
16.5604901960784, 16.989010989011, 16.3021296296296, 14.8100961538462, 
15.8714516129032, 16.5552083333333, 15.3971568627451, 16.2258771929825, 
14.2616279069767, 17.2556179775281, 14.3790350877193, 16.3594903846154, 
15.5988617886179, 14.4050925925926, 15.9334920634921, 14.3455056179775, 
16.6322935779817, 16.6958762886598, 17.1025714285714, 16.046875, 
16.8408695652174), avg_sched_run_hours = c(15.0267043478261, 
16.4351340206186, 15.0025140186916, 16.2041555555556, 14.8281578947368, 
15.9119814814815, 17.1840099009901, 16.7646666666667, 17.0109340659341, 
16.4446388888889, 14.7679615384615, 16.1768790322581, 16.3242083333333, 
15.7033333333333, 16.343701754386, 14.5158139534884, 17.4342921348315, 
14.5827280701754, 16.4562692307692, 15.4149105691057, 14.2729537037037, 
16.1438253968254, 14.3073595505618, 16.7186330275229, 16.6436082474227, 
17.0332952380952, 16.3137916666667, 16.9656739130435)), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -28L), groups = structure(list(
    month_yr = c("2022-01", "2022-02", "2022-03", "2022-04", 
    "2022-05", "2022-06", "2022-07", "2022-08", "2022-09", "2022-10", 
    "2022-11", "2022-12", "2023-01", "2023-02"), .rows = structure(list(
        1:2, 3:4, 5:6, 7:8, 9:10, 11:12, 13:14, 15:16, 17:18, 
        19:20, 21:22, 23:24, 25:26, 27:28), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -14L), .drop = TRUE))

当前代码

hours_by_plant <-
    ggplot(so_run_hour_stats, aes(x=month_yr, y=avg_sched_run_hours, group=1)) + geom_point() +
    geom_line(color="red") + xlab("Month of Year") + ylab("Avg Run Hours") +
    ggtitle("Avg Plant Run Hours by Month from 01/2022 - 02/2023") + theme_classic() +
    facet_wrap(~plant_name)

hours_by_plant <- hours_by_plant + theme(plot.title = element_text(hjust = 0.5))
解决方案

核心是将数据转换为长格式,因为ggplot的分组和图例功能更适配长数据结构。使用tidyr::pivot_longer把两个小时列合并为一个数值列,同时新增一列标记数据类型(实际/计划),之后通过颜色映射实现分组折线和图例。

完整代码

library(tidyverse)

# 取消数据分组并转换为长格式
so_run_hour_stats_long <- so_run_hour_stats %>%
    ungroup() %>%
    pivot_longer(
        cols = c(avg_run_hours, avg_sched_run_hours),
        names_to = "hour_type",
        values_to = "avg_hours"
    ) %>%
    # 重命名类型标签,让图例更清晰
    mutate(hour_type = case_when(
        hour_type == "avg_run_hours" ~ "实际运行小时均值",
        hour_type == "avg_sched_run_hours" ~ "计划运行小时均值"
    ))

# 绘制图表
hours_by_plant <- ggplot(so_run_hour_stats_long, 
                         aes(x = month_yr, y = avg_hours, color = hour_type, group = hour_type)) +
    geom_point() +
    geom_line() +
    xlab("年月") +
    ylab("平均运行小时") +
    ggtitle("2022年1月-2023年2月各工厂平均运行小时趋势") +
    theme_classic() +
    facet_wrap(~plant_name) +
    # 调整标题居中,自定义颜色(可选)
    theme(plot.title = element_text(hjust = 0.5)) +
    scale_color_manual(values = c("实际运行小时均值" = "blue", "计划运行小时均值" = "red"))

# 显示图表
print(hours_by_plant)

代码说明

  1. 数据转换:pivot_longer将原数据的两个小时列整合,生成hour_type(数据类型)和avg_hours(数值)两列,让ggplot能通过hour_type进行分组。
  2. 映射设置:在aes中指定color = hour_type和group = hour_type,ggplot会自动为不同类型生成不同颜色的折线,并创建对应的图例。
  3. 自定义优化:用mutate修改类型标签为中文,scale_color_manual自定义折线颜色,提升图表可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:56:07