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

R语言中ggplotly还原ggplot2修改的图例名称问题求助

问题:ggplotly还原ggplot2修改后的图例标签

使用ggplotly转换ggplot2图表时,会将通过scale_fill_manual修改后的图例标签还原为数据列的原始值(比如把"Females"变回"females")。目前已找到添加新数据列的解决办法,想寻求无需修改原始数据的方案。

原始数据(pop_gen_df)

structure(list(age_group = c("<  5 years", "5 - 14", "15  -  24", 
"25  -  34", "35  -  44", "45  -  54", "55  -  64", "65  -  74", 
"75  -  84", "85 +", "<  5 years", "5 - 14", "15  -  24", "25  -  34", 
"35  -  44", "45  -  54", "55  -  64", "65  -  74", "75  -  84", 
"85 +"), Type = c("males", "males", "males", "males", "males", 
"males", "males", "males", "males", "males", "females", "females", 
"females", "females", "females", "females", "females", "females", 
"females", "females"), Value = c(-6, -13, -13, -15, -17, -15, 
-11, -6, -3, -1, 6, 12, 12, 14, 16, 15, 12, 7, 4, 2)), row.names = c(NA, 
-20L), class = c("tbl_df", "tbl", "data.frame"))

原绘图代码

# Plot
gg_pop_hisp = ggplot(pop_hisp_df, aes( x = forcats::as_factor(age_group), y = Value, fill = Type)) +
  geom_bar(data = subset(pop_hisp_df, Type == "females"), stat = "identity") + 
  geom_bar(data = subset(pop_hisp_df, Type == "males"), stat = "identity") + 
  scale_y_continuous(labels = function(z) paste0(abs(z), "%")) +          # CHANGE
  scale_fill_manual(name = "", values = c("females"="#FC921F", "males"="#149ECE"), labels = c("Females", "Males")) +
  ggtitle("HISPANIC POPULATION BY GENDER AND AGE GROUP") +
  labs(x = "PERCENTAGE POPULATION", y = "AGE GROUPS", fill = "Gender") +
  theme_minimal() +
  theme(legend.position="bottom") +
  coord_flip()

# Interactive and place legend at the bottom
ggplotly(gg_pop_hisp) %>% 
  layout(
    legend = list(
      orientation = 'h', x = 0.3, y = -0.1, 
      title = list(text = '')
      )
    )

无需修改原始数据的解决方案

方案1:在ggplot映射中直接重编码因子

不用改动原始数据,直接在aes(fill = ...)中用forcats::fct_recode重编码Type的标签,让ggplotly能正确识别修改后的文本:

gg_pop_hisp = ggplot(pop_hisp_df, aes( x = forcats::as_factor(age_group), y = Value, 
                                       fill = forcats::fct_recode(Type, "Females" = "females", "Males" = "males"))) +
  geom_bar(data = subset(pop_hisp_df, Type == "females"), stat = "identity") + 
  geom_bar(data = subset(pop_hisp_df, Type == "males"), stat = "identity") + 
  scale_y_continuous(labels = function(z) paste0(abs(z), "%")) +
  scale_fill_manual(name = "Gender", values = c("Females"="#FC921F", "Males"="#149ECE")) +
  ggtitle("HISPANIC POPULATION BY GENDER AND AGE GROUP") +
  labs(x = "PERCENTAGE POPULATION", y = "AGE GROUPS") +
  theme_minimal() +
  theme(legend.position="bottom") +
  coord_flip()

ggplotly(gg_pop_hisp) %>% 
  layout(
    legend = list(
      orientation = 'h', x = 0.3, y = -0.1, 
      title = list(text = 'Gender')
      )
    )

方案2:在ggplotly中手动指定图例文本

直接在ggplotly返回的交互式对象中修改图例的text属性,无需调整原ggplot代码:

ggplotly(gg_pop_hisp) %>% 
  layout(
    legend = list(
      orientation = 'h', x = 0.3, y = -0.1, 
      title = list(text = 'Gender'),
      text = c("Females", "Males")  # 手动设置图例显示文本
      )
    )

方案3:合并geom_bar调用(简化代码)

原代码分两次调用geom_bar其实没必要,合并成一次后,ggplotly能正确读取scale_fill_manual中设置的标签:

gg_pop_hisp = ggplot(pop_hisp_df, aes( x = forcats::as_factor(age_group), y = Value, fill = Type)) +
  geom_bar(stat = "identity") +  # 无需按Type拆分调用
  scale_y_continuous(labels = function(z) paste0(abs(z), "%")) +
  scale_fill_manual(name = "Gender", values = c("females"="#FC921F", "males"="#149ECE"), labels = c("Females", "Males")) +
  ggtitle("HISPANIC POPULATION BY GENDER AND AGE GROUP") +
  labs(x = "PERCENTAGE POPULATION", y = "AGE GROUPS") +
  theme_minimal() +
  theme(legend.position="bottom") +
  coord_flip()

ggplotly(gg_pop_hisp) %>% 
  layout(
    legend = list(
      orientation = 'h', x = 0.3, y = -0.1
      )
    )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:16:01