求助:优化ggplot2柱状图与折线图美观度并解决绘图异常
图表优化方案
需求与问题
- 优化需求:
- 为App_1、App_2两条折线添加数据点,并在每个点上方标注对应百分比数值
- 在Total_Wth蓝色柱状图的中间标注对应数值
- 遇到的问题:使用
geom_point时右侧Y轴消失,且新增了第二个重复图例
修正后的完整代码
x <- c("Mar_22", "Apr_22", "May_22", "June_22", "July_22", "Aug_22") Total_Wth <- c(88959, 100396, 117989, 130561, 150282, 148970) App_1 <- c(0.91, 0.9, 0.91, 0.88, 0.9, 0.9) App_2 <- c(0.09, 0.1, 0.09, 0.12, 0.10, 0.10) df <- data.frame(x, Total_Wth, App_1, App_2) transf_fact <- max(df$Total_Wth)/max(df$App_1) df %>% mutate_at(vars(matches("App")), ~.*transf_fact) %>% gather(y_var, val, -x) %>% ggplot(aes(x = factor(x, df$x), y = val, fill = y_var)) + # 绘制柱状图 geom_col(data = . %>% filter(y_var == "Total_Wth")) + # 标注柱状图中间数值 geom_text(data = . %>% filter(y_var == "Total_Wth"), aes(label = val), vjust = 0.5, size = 3) + # 绘制折线 geom_line(data = . %>% filter(y_var != "Total_Wth"), aes(color = y_var, group = y_var), size = 1.2) + # 添加折线数据点 geom_point(data = . %>% filter(y_var != "Total_Wth"), aes(color = y_var, group = y_var), size = 3) + # 标注折线的百分比数值(转换回原始比例) geom_text(data = . %>% filter(y_var != "Total_Wth"), aes(label = scales::percent(val/transf_fact), color = y_var), vjust = -1, size = 3) + # 统一fill和color的图例 scale_fill_discrete(aesthetics = c("colour", "fill")) + # 设置双Y轴 scale_y_continuous(sec.axis = sec_axis(trans = ~ . / transf_fact, name = "%", labels = scales::percent), limits = c(0, 170000), breaks = c(34000 * 0:5)) + # 图表标签设置 labs(x = "月份", y = "总计", title = "示例标题", subtitle = "示例副标题") + theme_bw() + theme(legend.position = "bottom", legend.title = element_blank(), legend.key.size = unit(0.5, 'cm'), legend.text = element_text(size=7), panel.grid.major.x = element_blank(), panel.border = element_blank(), plot.title = element_text(hjust = 0), plot.subtitle = element_text(size=8, hjust=0, face="italic", color="black"), axis.text.x = element_text(size = 10, face = "bold"))
关键修改说明
- 折线数据点与标注:
geom_point明确指定过滤后的App类数据,继承折线的color和group映射,避免新增图例- 百分比标注通过
val/transf_fact转换回原始比例,用scales::percent格式化,vjust=-1让文字显示在点上方
- 柱状图数值标注:
- 单独过滤Total_Wth数据,用
geom_text在柱子中间(vjust=0.5)标注数值
- 单独过滤Total_Wth数据,用
- 避免轴与图例异常:
- 所有图层都严格指定对应的数据子集,确保双Y轴的转换逻辑不被破坏,图例保持统一
内容的提问来源于stack exchange,提问作者Bren85
相关产品推荐
相关产品推荐

