Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot2: how to change the order of a legend

library(tidyverse)
library(ggplot2)
library(ggstance)
dat <- structure(list(Gender = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                           1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("Female", "Male"
                                           ), class = "factor"), Status = c("Case", "Case", "Case", "Case", 
                                                                            "Control", "Control", "Control", "Control", "Case", "Case", "Case", 
                                                                            "Case", "Control", "Control", "Control", "Control"), Type = c("Age30", 
                                                                                                                                          "Age30", "Age30", "Age30", "Age30", "Age30", "Age30", "Age30", 
                                                                                                                                          "Age50", "Age50", "Age50", "Age50", "Age50", "Age50", "Age50", 
                                                                                                                                          "Age50"), Risk = c(21.59862, 3.27479, 1.10073, 1.70754, 8.85253, 
                                                                                                                                                             1.66318, 0.23228, 0.44844, 18.01182, 3.80135, 1.40662, 2.75944, 
                                                                                                                                                             4.81212, 1.93184, 0.29695, 0.72521), Disease = c("D1", "D2", 
                                                                                                                                                                                                              "D3", "D4", "D1", "D2", "D3", "D4", "D1", "D2", "D3", "D4", "D1", 
                                                                                                                                                                                                              "D2", "D3", "D4")), .Names = c("Gender", "Status", "Type", "Risk", 
                                                                                                                                                                                                                                             "Disease"), row.names = c(NA, -16L), class = "data.frame")

ggplot(dat, aes(x = Risk, y = forcats::fct_reorder(Status, Risk), 
                           group = Status,
                           fill = Type)) +
  facet_grid(Disease ~ ., switch = 'y') +
  geom_barh(aes(fill = interaction(Status, Type)), 
            stat = 'identity', position = 'stackv', color = "darkgrey",
            size = 0.3) +
  scale_x_continuous(limits = c(0, 100)) +
  labs( y = "Disease", x = "Risk",
       plot.title = element_text(hjust = 0.5)) + 
  theme_minimal() + 
  theme(
    text = element_text(size=10),
    strip.text.y = element_text(angle = 0),
    axis.text.y=element_blank(),
    axis.ticks.y=element_blank(),
    plot.title = element_text(size = 11, hjust = 0.5),
    legend.position = "bottom",
    legend.key.size = unit(0.2, "cm")) +
  scale_fill_manual("", 
                    values = c("#756bb1", "#2ca25f", "#bcbddc",
                                "#99d8c9"),
                    labels = c("Age 30 Case", "Age 30 Control", 
                               "Age 50 Case", "Age 50 Control"))

enter image description here

I would like to change the order of my legend labels to the following (from left to right):

[ ] Age 30 Case  [ ] Age 50 Case  [ ] Age 30 Control  [ ] Age 50 Control

I've tried reordering the values and labels but then the colors of the bars are then shuffled. I want the keep the colors as they are, i.e. dark purple corresponds to age 30 case, light purple to age 50 case. Dark green corresponds to age 30 control, and light green to age 50 control.

I understand that the colors correspond to the levels of the variable, but in my plot, the colors depend on the combination of 2 variables. So I couldn't think of a way to use relevel and change the order of my legend labels.

like image 226
Adrian Avatar asked Jul 10 '18 19:07

Adrian


People also ask

How do you reorder items in legend?

Step 1: To reorder the bars, click on the chart and select Chart Tools. Under the Data section, click Select Data. Step 2: In the Select Data Source pop up, under the Legend Entries section, select the item to be reallocated and, using the up or down arrow on the top right, reposition the items in the desired order.

How do I change the position of my legend in R?

Control legend position with legend. You can place the legend literally anywhere. To put it around the chart, use the legend. position option and specify top , right , bottom , or left . To put it inside the plot area, specify a vector of length 2, both values going between 0 and 1 and giving the x and y coordinates.

How do you reverse the order of legend in R?

R. To Reverse the order of Legend, we have to add guides() and guide_legend() functions to the geom_point() function. Inside guides() function, we take the parameter color, which will call guide_legend() guide function as value.

How do I change the order of multiple legends in R?

You can change the order of legends in any order using the order attribute within the function of the guide.


1 Answers

In your case, you want to set the breaks. The values and labels won't change the order. They should be given in the order of the breaks. The interaction() creates levels for you by putting a period between the two categories. You can check that with with(dat, levels(interaction(Status, Type))). Then you can five an order for this via breaks=. For example

scale_fill_manual("", 
                breaks = c("Case.Age30", "Case.Age50",
                           "Control.Age30", "Control.Age50"),
                values = c("#756bb1", "#2ca25f", 
                           "#bcbddc", "#99d8c9"), 
                labels = c("Age 30 Case", "Age 50 Case",
                           "Age 30 Control", "Age 50 Control"))

enter image description here

like image 119
MrFlick Avatar answered Sep 20 '22 10:09

MrFlick