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

ggplot绘制同X轴双变量pH图:统一点尺寸、区分颜色及添加图例

ggplot pH时序图:统一点尺寸、添加时段图例的解决方案

问题描述

我要绘制以Date为X轴、pH值为Y轴的时序图,区分上午(AM)和下午(PM)的测量值,数据框包含Moy_pHAM(AM均值)、Ecart_type_pHAM(AM标准差)、Moy_pHPM(PM均值)、Ecart_type_pHPM(PM标准差)四列。原代码如下:

pH1 <- ggplot(para_list_floc) +
  aes(x = Date, y = Moy_pHAM) +
  geom_point(size=3, color="blue") +
  geom_errorbar(aes(ymin =Moy_pHAM-Ecart_type_pHAM, ymax=Moy_pHAM +Ecart_type_pHAM),position=position_dodge(0.05), color="blue") +
  geom_point(aes(x=Date, y=Moy_pHPM,size=3, color="red",)) +
  geom_errorbar(aes(ymin =Moy_pHPM-Ecart_type_pHPM, ymax=Moy_pHPM +Ecart_type_pHPM),position=position_dodge(0.05), color="red") +
  ggtitle("Suivi du pH pendant la phase test") +
  theme(plot.title = element_text(size=10,hjust = 0.5,face="bold")) +
  ylab("Moy du pH/bac") + 
  labs(x = "Temps (en jour)") + 
  theme(axis.text.x = element_text(angle=90))

遇到两个问题:

  • 如何让AM和PM的点保持相同尺寸但颜色不同?
  • 如何为两类数据添加对应的图例?

数据示例:

para_list_floc <- structure(list(Date = structure(8:14, .Label = c("Jour 01", "Jour 02",
"Jour 03", "Jour 04", "Jour 05", "Jour 06", "Jour 07", "Jour 08",
"Jour 09", "Jour 10", "Jour 11", "Jour 12", "Jour 13", "Jour 14",
"Jour 15", "Jour 16", "Jour 17", "Jour 18", "Jour 19", "Jour 20",
"Jour 21", "Jour 22", "Jour 23", "Jour 24", "Jour 25", "Jour 26",
"Jour 27", "Jour 28", "Jour 29"), class = "factor"), Moy_tpAM = c(25.9428571428571,
25.8142857142857, 25.6571428571429, 25.9, 25.9, 25.9333333333333,
25.8047619047619), Ecart_type_tpAM = c(0.120712172424444, 0.101418510567422,
0.116496474502143, 0.104880884817015, 0.0999999999999998, 0.115470053837925,
0.139557122627942), Moy_tpPM = c(NaN, NaN, 26.1190476190476,
26.3285714285714, 26.3333333333333, 26.2761904761905, 26.1095238095238
), Ecart_type_tpPM = c(NA, NA, 0.132736760616823, 0.118923745075814,
0.119721899973786, 0.157812426331902, 0.175797502555531), Moy_pHAM = c(7.7452380952381,
7.58952380952381, 7.75904761904762, 7.69047619047619, 7.74190476190476,
7.70904761904762, 7.76333333333333), Ecart_type_pHAM = c(0.0705421184555048,
0.0633621488332104, 0.0659473094147715, 0.0644574425862669, 0.076001253122501,
0.0599920629670926, 0.0486141268905791), Moy_pHPM = c(NaN, NaN,
7.69285714285714, 7.75285714285714, 7.79380952380952, 7.78142857142857,
7.85666666666667), Ecart_type_pHPM = c(NA, NA, 0.0590883116312234,
0.0551491484197949, 0.0634410112211486, 0.0467210567395167, 0.0531350480693614
), Moy_Oxy = c(5.11714285714286, 5.21380952380952, 5.79380952380952,
5.68666666666667, 5.76571428571429, 5.65428571428571, NaN), Ecart_type_Oxy = c(0.181635427633016,
0.122901431662784, 0.176818443338815, 0.144890763450723, 0.161200850759896,
0.164971859072129, NA), Moy_MES = c(NaN, NaN, 4.47619047619048,
6.66666666666667, 5.45238095238095, 11, 6.14285714285714), Ecart_type_MES = c(NA,
NA, 3.18777426457784, 2.42212028327799, 2.68283787203384, 1.4142135623731,
2.28113380330296), y = c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
TRUE)), row.names = c(NA, 7L), class = "data.frame")

解决方案

核心思路:数据重塑 + 美学映射

原代码的问题在于直接给color赋值固定值,没有将其映射到分类变量,因此无法生成图例;同时size写在aes()内会被当作变量映射,可能导致尺寸异常。解决方法是先把宽格式数据转成长格式,再通过ggplot的美学映射实现统一尺寸和自动图例。

步骤1:加载工具包并重塑数据

用tidyr::pivot_longer将AM和PM的均值、标准差列合并,生成时段(AM/PM)、pH均值、pH标准差三列:

library(tidyr)
library(ggplot2)

# 重塑数据:提取pH相关的均值和标准差列
pH_data <- para_list_floc %>%
  select(Date, starts_with("Moy_pH"), starts_with("Ecart_type_pH")) %>%
  pivot_longer(
    cols = -Date,
    names_to = c(".value", "时段"),
    names_pattern = "(Moy_pH|Ecart_type_pH)(AM|PM)"
  ) %>%
  rename(pH均值 = Moy_pH, pH标准差 = Ecart_type_pH)

步骤2:绘制图表

通过将color映射到时段变量,统一设置size,同时让误差条和点共享颜色映射,自动生成图例:

ggplot(pH_data, aes(x = Date, y = pH均值, color = 时段)) +
  geom_point(size = 3) +  # 统一设置点尺寸,颜色由时段映射
  geom_errorbar(
    aes(ymin = pH均值 - pH标准差, ymax = pH均值 + pH标准差),
    position = position_dodge(width = 0.3),  # 调整误差条间距避免重叠
    width = 0.2
  ) +
  # 自定义颜色对应AM/PM
  scale_color_manual(values = c("AM" = "blue", "PM" = "red")) +
  # 图表标题与标签设置
  ggtitle("Suivi du pH pendant la phase test") +
  theme(plot.title = element_text(size = 10, hjust = 0.5, face = "bold")) +
  ylab("Moy du pH/bac") + 
  labs(x = "Temps (en jour)", color = "测量时段") +  # 修改图例标题
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))  # 优化X轴标签对齐

关键说明

  • 数据重塑后,ggplot可以一次性处理AM和PM的数据,无需重复调用geom_point和geom_errorbar
  • color = 时段放在全局aes()中,让点和误差条共享颜色映射,自动生成统一图例
  • position_dodge(width = 0.3)可以让同一日期的AM/PM点和误差条错开,避免重叠
  • scale_color_manual可以自定义时段对应的颜色,确保符合需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:27:23