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

调整ggplot折线图Y轴,可视化差异悬殊的age_group计数

解决分组计数差异过大的折线图展示问题

现有一个包含age_group(取值1-5)的data.table,共801,921条观测值。需要用ggplot绘制折线图,以age_group为X轴,各分组的总计数为Y轴。其中age_group1的观测值达274,000条,而age_group5仅7条。当前设置Y轴范围0-280000时,3、4、5组几乎无法被观察到。已考虑拆分1、2组单独展示,或是将Y轴适配3、4、5组的范围(0-350),在图上方标记1、2组的计数点并用虚线连接至折线图,现寻求其他可行解决方案。

现有代码:

ggplot(data = df1[type == "WORK"], aes(x = age_group)) +
  geom_line(stat = "bin", binwidth = 0.5, color = "lightblue") +
  labs(x = "age", y = "count") +
  scale_x_continuous(breaks = 1:5) +
  scale_y_continuous(limits = c(0, 274150), breaks = seq(0, 274150, by = 50000)) +
  theme_minimal()

可行解决方案

1. 对数转换Y轴

通过对数转换压缩大数值的范围,同时保留小分组的差异,搭配实际计数标签让读者明确数值。

代码示例:

ggplot(data = df1[type == "WORK"], aes(x = age_group)) +
  geom_line(stat = "bin", binwidth = 0.5, color = "lightblue") +
  geom_text(stat = "bin", binwidth = 0.5, aes(label = ..count..), vjust = -0.5) +
  labs(x = "age", y = "count (log10 scale)") +
  scale_x_continuous(breaks = 1:5) +
  scale_y_log10(breaks = c(10, 100, 1000, 10000, 100000, 274000)) +
  annotation_logticks(sides = "l") +
  theme_minimal()

2. 双Y轴展示

左侧Y轴对应1、2组的大计数,右侧Y轴对应3、4、5组的小计数,用不同颜色区分折线,避免混淆。

代码示例:

# 预计算各分组计数
count_df <- df1[type == "WORK"][, .N, by = age_group]

ggplot(count_df) +
  geom_line(aes(x = age_group, y = N, color = "Group 1-2"), size = 1) +
  geom_line(aes(x = age_group, y = N * (274150 / 350), color = "Group 3-5"), size = 1) +
  geom_text(aes(x = age_group, y = N, label = N), vjust = -0.5, color = "darkblue") +
  geom_text(aes(x = age_group, y = N * (274150 / 350), label = N), vjust = 1.5, color = "darkred") +
  labs(x = "age", y = "Count (Group 1-2)", color = "Group") +
  scale_x_continuous(breaks = 1:5) +
  scale_y_continuous(
    limits = c(0, 274150),
    breaks = seq(0, 274150, by = 50000),
    sec.axis = sec_axis(~ . / (274150 / 350), name = "Count (Group 3-5)", breaks = seq(0, 350, by = 50))
  ) +
  scale_color_manual(values = c("Group 1-2" = "lightblue", "Group 3-5" = "salmon")) +
  theme_minimal()

3. 分面拆分展示

将1、2组和3、4、5组拆分为两个子图,用分面布局保留各自的细节,同时能整体对比。

代码示例:

# 给分组添加规模标签
count_df <- df1[type == "WORK"][, .N, by = age_group][, size_group := ifelse(age_group %in% 1:2, "Large Groups", "Small Groups")]

ggplot(count_df, aes(x = age_group, y = N)) +
  geom_line(stat = "identity", color = "lightblue") +
  geom_text(aes(label = N), vjust = -0.5) +
  labs(x = "age", y = "count") +
  scale_x_continuous(breaks = 1:5) +
  facet_wrap(~size_group, scales = "free_y") +
  theme_minimal()

4. 主图+局部放大inset

保持原Y轴范围,用加粗、异色折线突出小分组,同时在图内嵌入小分组的放大子图,兼顾整体和细节。

代码示例:

library(grid)

# 主图
p_main <- ggplot(data = df1[type == "WORK"], aes(x = age_group)) +
  geom_line(stat = "bin", binwidth = 0.5, color = "lightblue") +
  geom_line(data = df1[type == "WORK" & age_group %in% 3:5], stat = "bin", binwidth = 0.5, color = "red", size = 1.2) +
  geom_text(stat = "bin", binwidth = 0.5, aes(label = ..count..), vjust = -0.5) +
  labs(x = "age", y = "count") +
  scale_x_continuous(breaks = 1:5) +
  scale_y_continuous(limits = c(0, 274150), breaks = seq(0, 274150, by = 50000)) +
  theme_minimal() +
  theme(plot.margin = unit(c(1, 1, 1, 1), "cm"))

# 小分组放大图
p_inset <- ggplot(data = df1[type == "WORK" & age_group %in% 3:5], aes(x = age_group)) +
  geom_line(stat = "bin", binwidth = 0.5, color = "red") +
  geom_text(stat = "bin", binwidth = 0.5, aes(label = ..count..), vjust = -0.5) +
  labs(x = "", y = "") +
  scale_x_continuous(breaks = 3:5) +
  scale_y_continuous(limits = c(0, 350)) +
  theme_minimal() +
  theme(axis.text = element_text(size = 8), plot.background = element_rect(fill = "white", color = "black"))

# 组合展示
vp <- viewport(width = 0.3, height = 0.3, x = 0.75, y = 0.25)
print(p_main)
print(p_inset, vp = vp)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 09:17:16