Search code examples
rggplot2legendline-breaks

reordering legend items and adding line breaks in R


I have a grouped bar plot and I'm trying to reorder the items in the legend. Currently, they're showing up by alphabetical order, and I tried reordering before I created the plot and it worked. But then when I used fill=str_wrap to add line breaks, it changed the order of the legend items again. Is it possible to do both - change the order of the legend items, and add line breaks?

I'm trying to add line breaks because otherwise the legend item text on one line is too long.

Below is all of my code:

race_disparities <- data.frame(race = c("Latino", "Latino", "Latino", "American Indian/Alaska Native", "American Indian/Alaska Native",
                                        "American Indian/Alaska Native", "Asian", "Asian", "Asian", "Black or African American",
                                        "Black or African American", "Black or African American", "White", "White", "White", "Other",
                                        "Other", "Other"),
                               disparities = c("Fair or poor condition of teeth", "No dental visits in the past year", "No dental insurance", 
                                               "Fair or poor condition of teeth", "No dental visits in the past year", "No dental insurance", 
                                               "Fair or poor condition of teeth", "No dental visits in the past year", "No dental insurance", 
                                               "Fair or poor condition of teeth", "No dental visits in the past year", "No dental insurance", 
                                               "Fair or poor condition of teeth", "No dental visits in the past year", "No dental insurance", 
                                               "Fair or poor condition of teeth", "No dental visits in the past year", "No dental insurance"),
                               perc = c(.399, .384, .498, .757, .669, .375, .484, .373, .450, .400, .502, .297, .392, .423, .373, .431, .341, .421))


# creating the grouped bar plot 

race_disparities_plot <- ggplot(data = race_disparities, mapping = aes(x=disparities, y=perc, fill =race)) +
  geom_bar(stat="identity", position = "dodge")


#changing order of bars/fill position
race_disparities$race <- factor(race_disparities$race,                   
                                levels = c("American Indian/Alaska Native", "Latino", "Black or African American",
                                           "Asian", "White", "Other"))  # Change ordering fill
race_disparities$disparities <- factor(race_disparities$disparities,                   
                                       levels = c("Fair or poor condition of teeth", "No dental visits in the past year",
                                                  "No dental insurance")) #changing order of x axis



#plotting the same thing, but now with the manipulated data in the right order
library(stringr)
race_disparities_plot <- ggplot(data = race_disparities, 
                                aes(y=perc, x=disparities, fill=str_wrap(race,16))) + #adding line breaks after 16 characters
  geom_bar(stat="identity", position = "dodge") +
  theme(
    axis.title.y = element_blank(),
    axis.title.x = element_blank())

race_disparities_plot







#customizing/formatting grouped bar plot
race_disparities_plot <- race_disparities_plot + 
  labs(fill = "Race/Ethnicity") +
  geom_bar(stat="identity", position = "dodge") +
  scale_y_continuous(labels = scales::percent) + #making y axis percentages
  scale_x_discrete(labels = c("Fair or poor\ncondition of teeth", "No dental visits\nin the past year", "No dental\ninsurance")) + #adding line breaks in x axis labels
  scale_fill_manual(values=c("#F6D9CB", "#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072", "#FDB462")) +  theme(text = element_text(family = "AppleGothic")) + #changing font of titles
  theme(axis.text.x=element_text(size=rel(1.2))) + #changing text size of x axis labels
  theme(axis.text.y=element_text(size=rel(1.2))) + #changing text size of y axis labels
  theme(legend.text=element_text(size=11)) + #changing text size of legend items
  theme(legend.title=element_text(size=13, face = "bold")) + #changing text size of legend title
  theme(legend.key.height=unit(1, "cm"))

race_disparities_plot

Thanks in advance!


Solution

  • Instead of str_wrap you could achieve your desired result by making use of label_wrap_gen to wrap the labels via the labels argument of scale_fill_manual :

    library(ggplot2)
    
    # plotting the same thing, but now with the manipulated data in the right order
    race_disparities_plot <- ggplot(
      data = race_disparities,
      aes(y = perc, x = disparities, fill = race)
    ) + # adding line breaks after 16 characters
      geom_bar(stat = "identity", position = "dodge") +
      theme(
        axis.title.y = element_blank(),
        axis.title.x = element_blank()
      )
    
    # customizing/formatting grouped bar plot
    race_disparities_plot <- race_disparities_plot +
      labs(fill = "Race/Ethnicity") +
      scale_y_continuous(labels = scales::percent) + # making y axis percentages
      scale_x_discrete(labels = c("Fair or poor\ncondition of teeth", "No dental visits\nin the past year", "No dental\ninsurance")) + # adding line breaks in x axis labels
      scale_fill_manual(values = c("#F6D9CB", "#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072", "#FDB462"),
                        labels = label_wrap_gen(width = 16)
                        ) +
      theme(text = element_text(family = "AppleGothic")) + # changing font of titles
      theme(axis.text.x = element_text(size = rel(1.2))) + # changing text size of x axis labels
      theme(axis.text.y = element_text(size = rel(1.2))) + # changing text size of y axis labels
      theme(legend.text = element_text(size = 11)) + # changing text size of legend items
      theme(legend.title = element_text(size = 13, face = "bold")) + # changing text size of legend title
      theme(legend.key.height = unit(1, "cm"))
    
    race_disparities_plot