Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

R ggplotly reverts legend name changes in ggplot2

Based on the data and code below, ggplotly changes the legend labels back to the column values.

I did find a solution, but that requires adding a new column. Is there a way to do this without modifying the data?

The ggplotly() ignores legend labels editing despite using scale_fill_manual()

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Data (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"))

Code:

# 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 = '')
      )
    )

>Solution :

I’m not sure if this falls under "not modifying the data", but it instead modifies the data being used defining the aesthetic.

Pass Type as a factor when defining the fill aesthetic and define your labels there. You no longer need to explicitly add the labels in scale_fill_manual and plotly will pick up on them, but you need to update the color mappings to use the capitalized version of the labels.

gg_pop_hisp = ggplot(
  pop_hisp_df, 
  aes( 
    x = forcats::as_factor(age_group), 
    y = Value, 
    # explicitly define fill using a factor to define the labels
    fill = factor(
      Type, levels = c("females", "males"), labels = c("Females", "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), "%")) +          
  
  # Update the color mappings to use the new labels
  # No need for the labels arguement because it's taken from the factor labels
  scale_fill_manual(name = "", values = c("Females"="#FC921F", "Males"="#149ECE")) +
  
  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()
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading