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

将数据框pct值乘100后ggplot条形图为空的问题排查

问题

原本使用ggplot2绘制条形图显示正常,为了展示真实百分比,将数据框中pct列的值乘以100后,绘制的条形图变为空。以下是绘图代码和数据结构:

绘图代码

ggplot(remove_missing(mydata), mapping = aes(x = value, y = pct)) +
  geom_col(aes(fill = value),
           width = 0.30) +
  scale_y_continuous(lim=c(0,1),labels=scales::percent) +
  geom_text(aes(label=round(pct,1)), colour="black", size=3) +
  
  scale_fill_manual(
    values = c('option1' = "blue", 
               'option2' = "blue", 
               'option3' = "blue",
               'option4' = "blue",
               'option5' = "blue",
               'option6' = "blue",
               'option7' = "blue",
               'option8' = "blue",
               'option9' = "blue",
               'option10' = "blue",
               'option11' = "blue",
               'option12' = "blue",
               'option13' = "blue"),
    drop = FALSE) +
  labs(x = "", y = "pct of responders") +
  guides(fill = "none") +
  theme(
    plot.margin = margin(t = 0, r =  30, b = 20, l = 5.5),
    plot.title = element_text(size = 15, face = "plain"),
    panel.background = element_blank(),
    panel.grid.major = element_line(colour = "grey"),
    panel.grid.major.x = element_blank(),
    panel.grid.minor = element_line(colour = "lightgrey"),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_line(colour = "grey"),
    axis.text.y = element_text(
      size = 11,
      face = "plain",
      hjust = 0
    ), 
    axis.text.x = element_text(
      size = 11,
      face = "plain",
      hjust = 0
    ),
    axis.title.x = element_text(size = 12),
  ) +
  coord_flip() +
  ggtitle("") +
  scale_x_discrete(labels = function(x)
    str_wrap(x, width = 20))

数据结构

structure(list(variable = c("option1", "option1", "option10", 
"option10", "option11", "option11", "option12", "option12", "option13", 
"option13", "option2", "option2", "option3", "option3", "option4", 
"option4", "option5", "option5", "option6", "option6", "option7", 
"option7", "option8", "option8", "option9", "option9"), value = structure(c(1L, 
NA, 10L, NA, 11L, NA, 12L, NA, 13L, NA, 2L, NA, 3L, NA, 4L, NA, 
5L, NA, 6L, NA, 7L, NA, 8L, NA, 9L, NA), .Label = c("option1", 
"option2", "option3", "option4", "option5", "option6", "option7", 
"option8", "option9", "option10", "option11", "option12", "option13"
), class = c("ordered", "factor")), n = c(98L, 49L, 107L, 40L, 
59L, 88L, 46L, 101L, 9L, 138L, 133L, 14L, 50L, 97L, 98L, 49L, 
138L, 9L, 103L, 44L, 37L, 110L, 84L, 63L, 14L, 133L), pct = c(66.6666666666667, 
33.3333333333333, 72.7891156462585, 27.2108843537415, 40.1360544217687, 
59.8639455782313, 31.2925170068027, 68.7074829931973, 6.12244897959184, 
93.8775510204082, 90.4761904761905, 9.52380952380952, 34.0136054421769, 
65.9863945578231, 66.6666666666667, 33.3333333333333, 93.8775510204082, 
6.12244897959184, 70.0680272108844, 29.9319727891156, 25.1700680272109, 
74.8299319727891, 57.1428571428571, 42.8571428571429, 9.52380952380952, 
90.4761904761905)), class = c("grouped_df", "tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -26L), groups = structure(list(
    variable = c("option1", "option10", "option11", "option12", 
    "option13", "option2", "option3", "option4", "option5", "option6", 
    "option7", "option8", "option9"), .rows = structure(list(
        1:2, 3:4, 5:6, 7:8, 9:10, 11:12, 13:14, 15:16, 17:18, 
        19:20, 21:22, 23:24, 25:26), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -13L), .drop = TRUE))

原因及解决方案

原因

问题出在y轴刻度范围的设置:

  • 原始数据中pct是0-1的小数(比如0.666对应66.6%),此时scale_y_continuous(lim=c(0,1))的范围刚好匹配,条形图正常显示。
  • 当你把pct乘以100后,数值变成了66.6、33.3这类0-100的整数,但y轴范围仍被限制在0-1,所有条形的高度都超出了显示区域,所以看起来是空图。

解决方案

有两种可行方式,任选其一即可:

  1. 调整y轴范围:将scale_y_continuous的lim参数改为c(0,100),同时保留labels=scales::percent(它会自动把100转换为100%显示)。
  2. 不修改原始数据:直接用scales::percent格式化y轴标签,它会自动把0.666这类小数转换成66.6%,不需要手动乘以100,仅在文本标签中对pct做乘100处理即可。

推荐第二种方式,避免修改原始数据,以下是调整后的代码:

ggplot(remove_missing(mydata), mapping = aes(x = value, y = pct)) +
  geom_col(aes(fill = value), width = 0.30) +
  # 保留原y轴范围,scales::percent自动转换小数为百分比格式
  scale_y_continuous(lim=c(0,1), labels=scales::percent) +
  # 文本标签显示百分比,需将pct乘以100后保留一位小数
  geom_text(aes(label=round(pct*100,1)), colour="black", size=3) +
  
  scale_fill_manual(
    values = rep("blue",13), # 简化重复的颜色设置
    drop = FALSE) +
  labs(x = "", y = "pct of responders") +
  guides(fill = "none") +
  theme(
    plot.margin = margin(t = 0, r =  30, b = 20, l = 5.5),
    plot.title = element_text(size = 15, face = "plain"),
    panel.background = element_blank(),
    panel.grid.major = element_line(colour = "grey"),
    panel.grid.major.x = element_blank(),
    panel.grid.minor = element_line(colour = "lightgrey"),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_line(colour = "grey"),
    axis.text.y = element_text(size = 11, face = "plain", hjust = 0), 
    axis.text.x = element_text(size = 11, face = "plain", hjust = 0),
    axis.title.x = element_text(size = 12)
  ) +
  coord_flip() +
  ggtitle("") +
  scale_x_discrete(labels = function(x) str_wrap(x, width = 20))

若选择第一种修改数据的方式,仅需将scale_y_continuous(lim=c(0,1))改为scale_y_continuous(lim=c(0,100), labels=scales::percent)即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:45:43