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

如何在非连续横坐标下将两个同横坐标变量分开绘制?

问题描述

需要将拥有相同横坐标的两个变量(P_av_arros 和 FTSW_apres_arros)绘制在同一张图中,要求同一横坐标位置上的两个变量分开显示,同时保持横坐标的连贯性。现有针对日期型横坐标的代码,但当前需要适配非连续数值型横坐标的场景。

原始数据

df<-structure(list(Bloc = c(7, 7, 8, 8, 5, 5, 7, 7, 8, 8, 5, 5, 7, 
                            7, 8, 8, 5, 5, 7, 7, 8, 8, 5, 5), Pos_heliaphen = c("W16", "W17", 
                                                                                "W36", "W37", "X02", "X03", "W16", "W17", "W36", "W37", "X02", 
                                                                                "X03", "W16", "W17", "W36", "W37", "X02", "X03", "W16", "W17", 
                                                                                "W36", "W37", "X02", "X03"), traitement = c("WS", "WW", "WW", 
                                                                                                                            "WS", "WS", "WW", "WS", "WW", "WW", "WS", "WS", "WW", "WS", "WW", 
                                                                                                                            "WW", "WS", "WS", "WW", "WS", "WW", "WW", "WS", "WS", "WW"), 
                   Variete = c("Blancas", "Blancas", "Blancas", "Blancas", "Blancas", 
                               "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", 
                               "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", 
                               "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", "Blancas", 
                               "Blancas"), Date_obs = c("D1_27/05/2021", "D1_27/05/2021", 
                                                        "D1_27/05/2021", "D1_27/05/2021", "D1_27/05/2021", "D1_27/05/2021", 
                                                        "D2_28/05/2021", "D2_28/05/2021", "D2_28/05/2021", "D2_28/05/2021", 
                                                        "D2_28/05/2021", "D2_28/05/2021", "D3_29/05/2021", "D3_29/05/2021", 
                                                        "D3_29/05/2021", "D3_29/05/2021", "D3_29/05/2021", "D3_29/05/2021", 
                                                        "D4_30/05/2021", "D4_30/05/2021", "D4_30/05/2021", "D4_30/05/2021", 
                                                        "D4_30/05/2021", "D4_30/05/2021"), P_av_arros = c(0.51, 0.53, 
                                                                                                          0.55, 0.57, 0.59, 0.61, 0.63, 0.65, 0.67, 0.69, 0.71, 0.73, 
                                                                                                          0.75, 0.77, 0.79, 0.81, 0.83, 0.85, 0.87, 0.89, 0.91, 0.93, 
                                                                                                          0.95, 0.97), FTSW_apres_arros = c(0.91, 0.92, 0.93, 0.94, 
                                                                                                                                            0.95, 0.96, 0.97, 0.98, 0.99, 1, 1.01, 1.02, 1.03, 1.04, 
                                                                                                                                            1.05, 1.06, 1.07, 1.08, 1.09, 1.1, 1.11, 1.12, 1.13, 1.14
                                                                                                          )), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
                                                                                                                                                                      -24L))

现有日期型横坐标代码

library(ggplot2)
library(dplyr)

labels <- df %>% 
  select(Bloc, Pos_heliaphen) %>% 
  distinct(Bloc, Pos_heliaphen) %>% 
  group_by(Bloc) %>% 
  summarise(Pos_heliaphen = paste(Pos_heliaphen, collapse = "-")) %>% 
  tibble::deframe()

df %>%
  mutate(Date_obs = as.POSIXct(lubridate::dmy(Date_obs))) %>%
  tidyr::pivot_longer(6:7) %>%
  mutate(Date_obs = if_else(name == "FTSW_apres_arros", 
                            Date_obs + 43200, Date_obs)) %>%
  ggplot(aes(Date_obs, value, colour = factor(Bloc), shape = traitement, 
             linetype = traitement, group = interaction(Bloc, traitement))) +
  geom_point() +
  geom_line() +
  scale_color_discrete(labels = labels, guide = guide_legend(order = 1)) +
  scale_x_datetime(date_labels = "%d/%m/%Y", date_breaks = "day") +
  labs(y = expression(paste("FTSW"))) +
  theme(legend.position = "bottom", 
        axis.text.x = element_text(angle = 90, hjust = 1))

解决方案

针对非连续数值型横坐标场景,核心思路是给其中一个变量的横坐标添加微小偏移量实现分离,同时手动设置刻度标签保持连贯性。

调整后的代码

library(ggplot2)
library(dplyr)
library(tidyr)

# 生成Bloc的标签
labels <- df %>% 
  select(Bloc, Pos_heliaphen) %>% 
  distinct(Bloc, Pos_heliaphen) %>% 
  group_by(Bloc) %>% 
  summarise(Pos_heliaphen = paste(Pos_heliaphen, collapse = "-")) %>% 
  tibble::deframe()

# 数据处理:将日期转换为数值分组,添加偏移量
df_processed <- df %>%
  # 提取Date_obs中的数字作为基础横坐标
  mutate(x_num = as.numeric(sub("D(\\d+)_.*", "\\1", Date_obs))) %>%
  pivot_longer(cols = c(P_av_arros, FTSW_apres_arros), names_to = "variable") %>%
  # 给两个变量的横坐标添加对称偏移,实现同组分离
  mutate(x_shifted = if_else(variable == "FTSW_apres_arros", 
                             x_num + 0.2, x_num - 0.2))

# 绘图
ggplot(df_processed, aes(x_shifted, value, colour = factor(Bloc), 
                         shape = traitement, linetype = traitement, 
                         group = interaction(Bloc, traitement, variable))) +
  geom_point(size = 3) +
  geom_line() +
  # 还原横坐标刻度和原始日期标签
  scale_x_continuous(
    breaks = unique(df_processed$x_num),
    labels = unique(df_processed$Date_obs) %>% sub("_.*", "", .),
    expand = c(0.05, 0.05)
  ) +
  scale_color_discrete(labels = labels, guide = guide_legend(order = 1)) +
  labs(
    x = "观测日期",
    y = expression(paste("FTSW")),
    colour = "区块",
    shape = "处理方式",
    linetype = "处理方式"
  ) +
  theme(
    legend.position = "bottom",
    axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5)
  )

关键调整说明

  • 数值化横坐标:将Date_obs转换为数值分组(如D1对应1、D2对应2),作为基础坐标基准。
  • 偏移分离:给FTSW_apres_arros的横坐标加0.2,P_av_arros减0.2,实现同日期下两个变量的左右分离(偏移量可根据图表宽度调整)。
  • 刻度还原:通过scale_x_continuous手动设置刻度位置为原始数值分组,标签显示为D1/D2等,保持横坐标的视觉连贯性。
  • 分组优化:group参数加入variable,确保每个变量的线条独立绘制,避免跨变量连线。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:36:23