Amanda
Amanda

Reputation: 107

Change order of one set of factors plotted in ggplot2

I am creating a plot using ggplot2 which is almost perfect, it looks like this:

enter image description here

However, I want to change the order that the 'watering treatment' boxes are shown - I want the order to be red, yellow, blue, purple, green.

To create the dataframe for my plot, I started with a dataframe that looked like this (note: 'Water' letters are abbreviations for the colours mentioned above):

  Ring CO2 Water plot_NH4.2x25
1     1 550     B      2.228750
2     1 550     P      4.945625
3     1 550     R     22.724375
4     1 550     W     -0.644375
5     1 550     Y     -0.770000
6     2 475     B      2.228750
7     2 475     P      4.945625
8     2 475     R      1.348750

etc.

I thought I could do one of the following: a) change the name of the watering treatment to A B C D or 1 2 3 4 so they automatically plot in the correct order b) add a bit of code that asks ggplot to plot them in the order I want.

But I can't figure out how to do either! I've messed around with 'ifelse', but this seems to require you to make a statement that is relevant to a numeric column, not another factor. I also tried 'xlim' but am unsure how to make this work for a factor that is being plotted as the colour, rather than the primary value on the x axis.

The code I've used to create the plot is:

g.Amm.2 <-   ggplot(data=NH4_24March_plot, aes(x=CO2, y=plot_NH4.2x25, fill=Water)) +
  stat_boxplot(geom ='errorbar', width = 0.5, position=position_dodge(0.75))+
  geom_boxplot()+
  theme_bw()+
  theme(panel.border = element_blank(),                            #remove box boarder
    axis.line.x = element_line(color="black", size = 0.5),      #add x axis line
    axis.line.y = element_line(color="black", size = 0.5),      #add y axis line
    panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
    panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
    legend.key.size = unit(1.5, 'lines'),
    legend.position=c(0.9,0.8),
    legend.key = element_blank(),    #remove grey box from around legend
    panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
 scale_y_continuous(expand = c(0, 0), limits = c(-5,140), breaks=seq(0,140,20))+     #change x axis to intercept y axis at 0
  scale_fill_manual(values=c("skyblue2", "orchid1", "firebrick1", "seagreen3", "yellow2"),
                name=" Watering treatment",
                labels=c("optimal summer \noptimal autumn", "excess summer \nlimited autumn", 
                         "excess summer \noptimal autumn","limited summer \nexcess autumn",
                         "optimal summer \nlimited autumn"))+
  ylab(expression(Membrane~available~NH[4]^{" +"}~-N~(~mu~g~resin^{-1}~14~day^{-1})))+
  xlab(expression(CO[2]~concentration~(mu~mol~mol^{-1})))

Any thoughts would be greatly appreciated, thanks in advance :-)

Upvotes: 2

Views: 10978

Answers (2)

eipi10
eipi10

Reputation: 93761

Following up on my comment, here's how you could use facetting to make the Water values easier to follow without a legend. I also include the factor code to set the order of the Water levels. In addition, it might be easier to just recode the levels of Water before plotting, so I include code to do that as well.

# Fake data
set.seed(491)
NH4_24March_plot = data.frame(CO2=rep(c(550,475), each=30), Water=rep(c("A","B","C"), 20), 
                              values=rnorm(60, 50, 10))

# Set order of Water column
NH4_24March_plot$Water = factor(NH4_24March_plot$Water, levels=c("B","A","C"))

# Recode Water values (and note that the recoded values maintain the corresponding order 
# of the Water levels that we set in the previous line of code)
library(dplyr)
NH4_24March_plot$Water_recode = recode(NH4_24March_plot$Water,
                                       "A"="optimal summer\noptimal autumn",
                                       "B"="excess summer\nlimited autumn",
                                       "C"="limited summer\nexcess autumn")

ggplot(NH4_24March_plot, aes(Water_recode, values, fill=Water_recode)) +
  geom_boxplot(show.legend=FALSE) +
  facet_grid(. ~ CO2, labeller=label_bquote(cols=CO[2]:~.(CO2)~mu*mol%.%mol^{-1})) +
  scale_y_continuous(limits=c(0, max(NH4_24March_plot$values))) +
  theme_bw() 

enter image description here

Upvotes: 1

jrdnmdhl
jrdnmdhl

Reputation: 1955

To get your colors in order, do the following: 1. Set the water column as a factor with the levels in the order that you want them to appear. 2. When setting the values in scale_fill_manual, set the colors in the order you want them to appear.

See below for result. Note that I removed your labels to make it more clear what colors correspond to what factor levels. You can add them back in, of course.

myDf = data.frame(
  Ring = c(1,1,1,1,1,2,2,2),
  CO2 = c(550,550,550,550,550,475,475,475),
  Water=c("B","P","R","W","Y","B","P","R"),
  "plot_NH4.2x25" = c(2.228750,4.945625,22.724375,-0.644375,-0.770000,2.228750,4.945625,1.348750)
)

myDf$Water = factor(myDf$Water, levels = c("R","Y","B","P","W"))


ggplot(data=myDf, aes(x=CO2, y=plot_NH4.2x25, fill=Water)) +
  stat_boxplot(geom ='errorbar', width = 0.5, position=position_dodge(0.75))+
  geom_boxplot()+
  theme_bw()+
  theme(panel.border = element_blank(),                            #remove box boarder
        axis.line.x = element_line(color="black", size = 0.5),      #add x axis line
        axis.line.y = element_line(color="black", size = 0.5),      #add y axis line
        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        legend.key.size = unit(1.5, 'lines'),
        legend.position=c(0.9,0.8),
        legend.key = element_blank(),    #remove grey box from around legend
        panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
  scale_y_continuous(expand = c(0, 0), limits = c(-5,140), breaks=seq(0,140,20))+     #change x axis to intercept y axis at 0
  scale_fill_manual(values=c("firebrick1", "yellow2","skyblue2", "orchid1",  "seagreen3"),
                    name=" Watering treatment")+
  ylab(expression(Membrane~available~NH[4]^{" +"}~-N~(~mu~g~resin^{-1}~14~day^{-1})))+
  xlab(expression(CO[2]~concentration~(mu~mol~mol^{-1})))

Note that my plot below doesn't match yours (presumably) due to the limited number of rows provided. enter image description here

Upvotes: 1

Related Questions