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

在ggplot中为线条分配第二Y轴的堆叠分组柱状图问题求助

解决堆叠分组柱状图+第二Y轴线条的显示问题

你的代码里有几个关键问题导致线条无法正确关联第二Y轴并显示,我帮你调整了代码并拆解了核心修改点:

问题根源

  1. 你的XAXIS是离散字符串类型,用geom_line时必须指定group参数,否则ggplot不知道哪些点属于同一条线,无法完成连线。
  2. 第二Y轴设置的缩放规则是~./40,意味着右侧轴数值是左侧轴的1/40,但线条的原始值(0.4-0.8)直接放在左侧轴的刻度范围里太小,需要反向放大(乘以40)才能匹配左侧轴刻度,同时让右侧轴显示原始比例值。
  3. 你之前过滤了CATEGORY2 == "XXX_PY",导致只有PY的线条数据,如果需要同时展示TY和PY的线条,这个过滤需要移除。

修改后的完整代码

library(tidyverse)
library(magrittr)

# 原始数据
df <- data.frame(
 DATE = c("2019-01-01", "2019-01-08", "2019-01-15")
 , XXX_TY_T = c(20, 30, 25)
 , XXX_TY_C = c(10, 5, 15)
 , XXX_PY_T = c(15, 20, 20)
 , XXX_PY_C = c(20, 20, 15)
 , YYYY_TY_TD = c(0.7, 0.8, 0.75)
 , YYYY_PY_TD = c(0.4, 0.7, 0.6)
)

# 整理长格式数据:用case_when更清晰地分类CATEGORY2
df_long <- df %>% 
  gather(CATEGORY, VALUE, XXX_TY_T:YYYY_PY_TD) %>%
  mutate(
    CATEGORY2 = case_when(
      str_detect(CATEGORY, "XXX_TY") ~ "XXX_TY",
      str_detect(CATEGORY, "XXX_PY") ~ "XXX_PY",
      TRUE ~ NA_character_
    ),
    XAXIS = paste0(DATE, " | ", CATEGORY2)
  )

# 柱状图数据:过滤掉线条相关的类别
df_long_bar <- df_long %>% 
  filter(!(CATEGORY %in% c("YYYY_TY_TD", "YYYY_PY_TD")))

# 线条数据:移除XXX_PY的过滤,保留CATEGORY用于分组
df_long_line <- df_long %>% 
  filter(CATEGORY %in% c("YYYY_TY_TD", "YYYY_PY_TD")) %>%
  rename(LINE = VALUE) %>%
  mutate(
    CATEGORY2 = ifelse(CATEGORY == "YYYY_TY_TD", "XXX_TY", "XXX_PY"),
    XAXIS = paste0(DATE, " | ", CATEGORY2)
  ) %>%
  select(XAXIS, CATEGORY, LINE)

# 合并柱状图和线条数据
df_long_plot <- left_join(df_long_bar, df_long_line, by = c("XAXIS"))

# 绘图:核心调整线条的y值转换和分组
ggplot(df_long_plot) +
  geom_bar(aes(x = XAXIS, y = VALUE, fill = CATEGORY), stat = "identity", position = "stack") +
  # 关键:指定group,同时将LINE乘以40匹配左侧Y轴刻度
  geom_line(aes(x = XAXIS, y = LINE * 40, group = CATEGORY, color = CATEGORY), stat = "identity", size = 1) +
  # 设置双Y轴的标签和转换关系
  scale_y_continuous(
    name = "柱状图数值",
    sec.axis = sec_axis(~./40, name = "线条比例数值")
  ) +
  # 给线条设置区分颜色
  scale_color_manual(values = c("YYYY_TY_TD" = "#e74c3c", "YYYY_PY_TD" = "#3498db")) +
  # 旋转x轴标签避免重叠
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

关键调整说明

  • 线条分组:通过group = CATEGORY让ggplot识别出两条独立的线条(TY和PY),解决离散x轴无法连线的问题。
  • Y轴数值转换:LINE * 40把线条的原始比例值放大到左侧Y轴的数值范围,配合sec_axis(~./40)让右侧轴显示原始的比例值(比如0.7*40=28,对应右侧轴的0.7)。
  • 数据范围:移除了线条数据的PY过滤,如果你只需要显示PY的线条,重新加上filter(CATEGORY2 == "XXX_PY")即可,但记得保留group参数和数值转换。
  • 美化优化:添加了轴标签、线条颜色区分,旋转x轴标签提升可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:49:20