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

如何在R中使用ggplot2创建双X轴周销售对比图表?

在ggplot2中实现双X轴销售额对比图表

核心思路

ggplot2不支持直接绑定两个独立X变量,需以其中一个轴(如Semana_TW)为基础,通过轴转换/手动标签映射生成第二个轴(Semana_LY),同时确保两组数据的X轴位置严格对齐。

步骤1:整理数据

确保数据包含以下字段:

  • Semana_TW:本年周数
  • Ventas_TW:本年对应周销售额(前3周为0)
  • Semana_LY:上年偏移3周的对应周数
  • Ventas_LY:上年对应周销售额

模拟你的场景构造示例数据:

sales_data <- data.frame(
  Semana_TW = 30:36,
  Ventas_TW = c(0, 0, 0, 1200, 1500, 1400, 1600),
  Semana_LY = 27:33,
  Ventas_LY = c(1100, 1300, 1250, 1220, 1480, 1350, 1550)
)

步骤2:绘制双X轴图表

线性对应场景(LY比TW偏移3周)

如果Semana_LY和Semana_TW是固定线性关系(如LY = TW - 3),用sec_axis的转换函数实现:

library(ggplot2)

ggplot(sales_data) +
  # 绘制本年销售额柱状图
  geom_col(aes(x = Semana_TW, y = Ventas_TW), fill = "#2196F3", alpha = 0.7, width = 0.4) +
  # 绘制上年销售额柱状图,错开位置避免重叠
  geom_col(aes(x = Semana_TW, y = Ventas_LY), fill = "#FF9800", alpha = 0.7, width = 0.4, position = position_nudge(x = 0.4)) +
  # 主X轴(下方:本年周数)
  scale_x_continuous(
    name = "Semana TW (本年周数)",
    breaks = sales_data$Semana_TW,
    # 次X轴(上方:上年周数),通过转换函数匹配对应关系
    sec.axis = sec_axis(
      trans = ~ . - 3,
      name = "Semana LY (上年周数)",
      breaks = sales_data$Semana_LY
    )
  ) +
  scale_y_continuous(name = "销售额") +
  labs(title = "近7周销售额对比(本年VS上年偏移3周)") +
  theme_minimal() +
  theme(
    axis.title.x.top = element_text(color = "#FF9800"),
    axis.title.x.bottom = element_text(color = "#2196F3"),
    legend.position = "top"
  ) +
  guides(fill = guide_legend(title = "销售额类型"))

自定义对应场景

如果Semana_LY和Semana_TW不是线性关系,用手动标签映射的方式实现:

# 提前定义TW到LY的对应关系
tw_to_ly <- setNames(sales_data$Semana_LY, sales_data$Semana_TW)

ggplot(sales_data) +
  geom_col(aes(x = Semana_TW, y = Ventas_TW), fill = "#2196F3", alpha = 0.7, width = 0.4) +
  geom_col(aes(x = Semana_TW, y = Ventas_LY), fill = "#FF9800", alpha = 0.7, width = 0.4, position = position_nudge(x = 0.4)) +
  scale_x_continuous(
    name = "Semana TW (本年周数)",
    breaks = sales_data$Semana_TW,
    # 次X轴手动指定标签,完全匹配自定义对应关系
    sec.axis = sec_axis(
      trans = ~ .,
      name = "Semana LY (上年周数)",
      breaks = sales_data$Semana_TW,
      labels = tw_to_ly
    )
  ) +
  scale_y_continuous(name = "销售额") +
  labs(title = "近7周销售额对比(本年VS上年偏移3周)") +
  theme_minimal() +
  theme(
    axis.title.x.top = element_text(color = "#FF9800"),
    axis.title.x.bottom = element_text(color = "#2196F3"),
    legend.position = "top"
  ) +
  guides(fill = guide_legend(title = "销售额类型"))

关键说明

  • 次X轴的核心是和主X轴的位置一一对应,不能独立映射另一组变量;
  • 用position_nudge错开两组柱状图,避免遮挡;
  • 跨年场景下(如TW第2周对应LY第51周),可调整转换函数为~ ifelse(. <=3, . -3 +52, . -3)。

内容的提问来源于stack exchange,提问作者Francisco Augusto Varela Aguir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:22:09