R ggplot2创建带百分比的金字塔图报错:离散值传入连续刻度
解决金字塔图的离散值报错与轴标签需求
错误原因
你将Value列转换为带%的字符串后,该列从数值型变为字符型,而scale_y_continuous要求y轴为连续数值类型,因此触发Discrete value supplied to continuous scale报错。正确思路是保留数值型数据用于绘图,通过刻度标签设置来实现%符号显示和负号隐藏,不要修改原始数据的类型。
修正后的完整代码
library(tidyverse) library(plotly) # 加载plotly包以支持交互式绘图 # 原始数据 pop = structure(list(age_group = c("< 5 years", "5 - 9", "10 - 14", "15 - 19", "20 - 24", "25 - 29", "30 - 34", "35 - 44", "45 - 54", "55 - 64", "65 - 74", "75 - 84", "85 +"), males = c(6, 6, 7, 6, 7, 7, 8, 17, 15, 11, 6, 3, 1), females = c(6, 5, 6, 6, 6, 7, 7, 16, 15, 12, 7, 4, 2)), row.names = c(NA, -13L), spec = structure(list(cols = list(`AGE GROUP` = structure(list(), class = c("collector_character", "collector")), MALES = structure(list(), class = c("collector_double", "collector")), FEMALES = structure(list(), class = c("collector_double", "collector"))), default = structure(list(), class = c("collector_guess", "collector")), delim = ","), class = "col_spec"), problems = NULL, class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame")) # 数据整理:保留数值型Value,不转换为字符串 pop_df = pop %>% select(age_group, males, females) %>% gather(key = Type, value = Value, -age_group) %>% mutate(Value = ifelse(Type == "males", -Value, Value)) # 用mutate更符合tidyverse风格 # 绘制金字塔图 gg_pop = ggplot(pop_df, aes(x = age_group, y = Value, fill = Type)) + geom_col() # geom_col等价于stat="identity"的geom_bar,代码更简洁 scale_y_continuous( labels = function(x) paste0(abs(x), "%"), # 取绝对值并添加%符号 breaks = seq(-20, 20, 5) # 可选:自定义刻度间隔,根据数据调整 ) + ggtitle("Male vs Female Population Comparison") + labs(x = "Age group", y = "Percentage", fill = "Gender") + coord_flip() # 生成交互式图表 ggplotly(gg_pop)
关键修改说明
- 移除了
pop_df$Value = paste0(pop_df$Value, "%"),保留Value列的数值类型,确保绘图时y轴为连续刻度。 - 用
mutate替代直接修改数据列,遵循tidyverse编码规范。 - 替换
geom_bar(stat="identity")为geom_col,简化代码。 - 在
scale_y_continuous中通过自定义标签函数实现两个需求:abs(x):去掉负号,让所有轴标签显示为正数。paste0(abs(x), "%"):为数值添加%符号,满足百分比显示需求。
- 可选的
breaks参数可以自定义刻度位置,让轴标签分布更均匀。
内容的提问来源于stack exchange,提问作者Ed_Gravy
相关产品推荐
相关产品推荐

