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

ggplot2堆叠百分比条形图添加分区百分比标签及plotly实现咨询

核心问题原因

你当前代码的标签错位问题,是构造数据集时使用cbind()拼接向量,导致原本为数值型的pourcentage被强制转为字符型,ggplot识别y轴为分类变量,无法正确计算堆叠标签的位置。


修复后的ggplot实现

先修正数据集构造逻辑,再调整标签堆叠参数即可正常显示:

library(tidyverse)
library(plotly)

# 修正数据集构造,直接用data.frame保留各列数据类型
mois = c("avril",   "avril",   "avril",   "avril",   "mai",     "mai",     "mai",     "mai", "juin", "juin",  "juin",   "juin",    "juillet", "juillet", "juillet", "juillet", "aout", "aout",    "aout",    "aout",    "sept",    "sept",    "sept",    "sept")
pourcentage = c(56.7, 10.0, 13.3, 20.0, 64.5,  0.0,  3.2, 32.3, 73.3,  6.7,  3.3, 16.7, 54.8, 12.9,  9.7, 22.6, 45.2, 12.9,  6.5, 35.5, 10.0 , 0.0,  3.3, 86.7)
class = c("=< -5%",    "-5 et 0 %", "0 - 5%",    ">= 5%",     "=< -5%",    "-5 et 0 %", "0 - 5%",    ">= 5%",     "=< -5%",    "-5 et 0 %", "0 - 5%",    ">= 5%",     "=< -5%",    "-5 et 0 %", "0 - 5%",    ">= 5%",     "=< -5%",    "-5 et 0 %", "0 - 5%",    ">= 5%",     "=< -5%",    "-5 et 0 %", "0 - 5%",    ">= 5%" )
df <- data.frame(mois, pourcentage, class)
color <- c("green", "blue", "red", "yellow")

# 绘图代码调整
bar =  df %>%
  ggplot(mapping = aes(x = mois, y = pourcentage, fill = class))+
  geom_bar(position = 'fill', stat = 'identity', color = "black")+
  scale_y_continuous(labels = scales::percent)+
  # 过滤0%数值避免无效显示,调整reverse参数匹配堆叠顺序
  geom_text(aes(label = ifelse(pourcentage == 0, "", paste0(pourcentage,"%"))),
            position = position_fill(vjust = 0.5, reverse = FALSE),
            size = 3)+
  theme_classic()+
  scale_fill_manual(values = color)

ggplotly(bar)

纯plotly简化实现

不需要手动调整标签位置,直接调用plotly原生参数即可实现:

plot_ly(df, 
        x = ~mois, 
        y = ~pourcentage, 
        color = ~class, 
        colors = color,
        type = "bar",
        text = ~paste0(pourcentage, "%"),
        textposition = "inside",
        insidetextanchor = "middle"
) %>%
  layout(barmode = "stack",
         yaxis = list(tickformat = ".0%", title = "占比"),
         xaxis = list(title = "月份"),
         legend = list(title = list(text = "区间")))

注:你的数据集每个月的四类占比总和正好为100%,堆叠后y轴自动为百分比高度,不需要额外做占比换算。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:06:05