如何解决R中绘制双Y轴时geom_line图形不显示的问题
双Y轴柱状图+折线图显示问题解决
问题描述
使用R的ggplot2绘制双Y轴图形时,仅显示geom_bar生成的柱状图,geom_line的折线图及相关标签、平滑线均未显示,且出现警告,需要实现同时展示柱状图与折线图的双Y轴效果。
问题原因
双Y轴的次轴(sec_axis)仅负责刻度转换的显示,实际绘图数据仍基于主Y轴的范围。当前代码中次轴使用~.*15做刻度转换,但折线图的Weather数值未做反向缩放(即除以15),导致Weather数值远小于主Y轴0-8的范围,被压缩到几乎不可见。
修改方案
- 对折线图、天气数值标签、平滑线的Y值做反向缩放:将
y = Weather改为y = Weather/15,使其适配主Y轴的范围; - 调整次轴的刻度与标签,使其对应
Weather的实际数值范围; - 修正"Sep"标签的位置参数,避免偏移过大。
修改后的完整代码
odd_weather = pge[seq_len(nrow(pge)) %% 2 == 1, ] ggplot(data = pge) + # 主Y轴:Usage柱状图 geom_bar(mapping = aes(x = Date, y = Usage), width = 0.8, colour = 'steelblue3', fill = 'steelblue3', stat = "identity") + # Sep标签(调整位置适配主Y轴) geom_label(aes(x = Date, y = Usage), label = ifelse(Date == as.Date("2021-09-01"), "Sep", NA), hjust = 0.3, vjust = -1, size = 3) + # 折线图:Y值缩放适配主Y轴 geom_line(mapping = aes(x = Date, y = Weather/15), color = 'purple') + # 天气数值标签:Y值缩放 geom_label(data = odd_weather, mapping = aes(x = Date, y = Weather/15, label = paste(Weather, sep = ','))) + # 平滑线:Y值缩放 geom_smooth(mapping = aes(x = Date, y = Weather/15), method = "lm", formula = y ~ poly(x, 3), se = FALSE) + # X轴设置 scale_x_date( name = " ", breaks = seq.Date(as.Date("2021-08-27"), as.Date("2021-09-24"), by = "4 days"), date_labels = "%a\n%d") + # Y轴(主+次轴)设置 scale_y_continuous( name = "Usage", limits = c(0, 8), breaks = seq(0.0, 8.0, by = 2.0), labels = c('0.0', '2.0', '4.0', '6.0', '8.0'), # 次轴:将主Y轴缩放值还原为Weather实际数值 sec.axis = sec_axis(~.*15, name = "Weather", breaks = seq(0, 120, by = 30), labels = c('0', '30', '60', '90', '120'))) + # 日期分割线 annotate("segment", x = median(c(as.Date("2021-08-31"), as.Date("2021-09-01"))), xend = median(c(as.Date("2021-08-31"), as.Date("2021-09-01"))), y = 0, yend = 8.0, colour = 'gray88', size = 0.5) + # 主题样式设置 theme(plot.background = element_rect(fill = 'gray96'), panel.background = element_rect(fill = 'gray96'), panel.grid.major.x = element_blank(), panel.grid.minor.x = element_blank(), panel.grid.major.y = element_line(color = 'gray88', size = 0.3, linetype = 1), panel.grid.minor.y = element_blank(), axis.ticks = element_blank(), axis.text.x = element_text(size = 8), axis.text.y = element_text(size = 8))
关键说明
- 次轴的
~.*15是将主Y轴的缩放值还原为Weather的实际数值,因此绘图时必须先将Weather除以15,才能在主Y轴坐标系中正确显示; - 可根据
Weather的实际数值范围调整次轴的breaks和labels,确保刻度合理; - "Sep"标签的
vjust参数从-11.2调整为-1,避免因之前数值错误导致的极端偏移,可根据实际显示效果微调。
内容的提问来源于stack exchange,提问作者Seoyoung Park
相关产品推荐
相关产品推荐

