ggplot facet_wrap edit strip labels

Hello,

I am using the following code to create the plot displayed in the attached image.

p <- ggplot(taxa.data, aes(y=R, x=reorder(Genus, R, fun=mean),fill=Morphotype)) + geom_boxplot()+coord_cartesian(ylim =c(1,6.5)) + theme_gray() + scale_y_continuous(breaks = c(1,2,3,4,5,6))+ylab("CCRI")

p +guides(fill=guide_legend(nrow=8))+ theme(axis.title.x = element_blank(), legend.position = "none",panel.grid.major.x = element_blank(),panel.grid.minor.x = element_blank()) +facet_grid(~Type+Morphotype, space="free", scales="free")

Q1. The data is sorted by type and morphotype - both of which are displayed in the strip title. I would like to create new labels for the strip that only include the variables from Morphotype and not the type. Is there a way to suppress the Type labels?

Q2. There are only two Types within the data. Is there a way to create two overarching headings above the strip that summarise this sort (as opposed to at the moment where the type is specified in every facet-grid box).

Q3. Is there a way to sort the order of the facet boxes by the mean of the morphotype they are sorted into?

Thanks

Hi Emily, welcome!

To help us help you, could you please turn this into a proper reproducible example (reprex) illustrating your issue? Please have a look at this guide, to see how to create one:

Here is one approach with some toy data. The last plot is what I understand you want. Your RmType() function would have to use a more flexible regex since I could get away with always removing just two characters.

library(ggplot2)
library(tidyr)
library(dplyr)
DF <- data.frame(type = sample(LETTERS[1:2], 200, replace = TRUE),
                 morphotype = sample(LETTERS[5:7], 200, replace = TRUE),
                 R = sample(LETTERS[9:12], 200, replace = TRUE),
                 Value = runif(200, min = 5, max = 15))
DF <- DF %>% unite("BothLabels", type, morphotype, sep = "_", remove = FALSE)

ggplot(DF, aes(x = R, y = Value)) + geom_boxplot() + 
  facet_grid(~type+morphotype)



#Use BothLabels as the facetting variable
ggplot(DF, aes(x = R, y = Value)) + geom_boxplot() + 
  facet_grid(~BothLabels)


#Make a function to remove the first part of BothLabels
RmType <- function(string) {
  sub("._", "", string)
}

ggplot(DF, aes(x = R, y = Value)) + geom_boxplot() + 
  facet_grid(~BothLabels, 
             labeller = labeller(BothLabels = RmType))

Created on 2019-10-19 by the reprex package (v0.3.0.9000)

1 Like

Hello, and thanks for the welcome!
Thank you for alerting me to reprex - it has taken a while to get my head around it, but I think I have it now!

Please find what I think is a reprex minimal dataset and code below. Any help with the above questions would be much appreciated. Thank you.

library(ggplot2)
df <- data.frame(
    R = c(2.25, 1.96, 1.51, 1.78, 2.12, 2.24, 2.31, 2.61, 2.08, 2.62,
          2.5, 3.1, 2.74, 2.64, 2.62, 2.65, 3.1),
    Genus = as.factor(c("Ab", "Ab", "Ac", "Ac", "At1", "At1", "En", "En",
                        "Mo", "Mo", "St", "St", "St", "s1", "s1", "s2",
                        "s2")),
    Morphotype = as.factor(c("Acropora", "Acropora", "Acropora", "Acropora",
                             "Acropora", "Acropora", "Branching", "Branching",
                             "Branching", "Branching", "Branching", "Branching",
                             "Branching", "Sand", "Sand", "Sand", "Sand")),
    Type = as.factor(c("biotic", "biotic", "biotic", "biotic", "biotic",
                       "biotic", "biotic", "biotic", "biotic", "biotic",
                       "biotic", "biotic", "biotic", "abiotic", "abiotic",
                       "abiotic", "abiotic"))
)

ggplot(df, aes(y = R, x = reorder(Genus, R, fun = mean))) +
    geom_boxplot() +
    facet_grid(~Type+Morphotype)

Created on 2019-10-27 by the reprex package (v0.3.0.9000)

Dear FJCC,

Thank you so much for your help and kind examples from last week.
However, being completely new to r studio, I found it very difficult to follow the code with my data. In another reply I have just posted an eg of my data and code. If you have the time I would greatly appreciate if you could replicate your examples with my data. Many thanks,
Emily

1 Like

Is this what you are trying to accomplish?

library(ggplot2)

df <- data.frame(
    R = c(2.25, 1.96, 1.51, 1.78, 2.12, 2.24, 2.31, 2.61, 2.08, 2.62,
          2.5, 3.1, 2.74, 2.64, 2.62, 2.65, 3.1),
    Genus = as.factor(c("Ab", "Ab", "Ac", "Ac", "At1", "At1", "En", "En",
                        "Mo", "Mo", "St", "St", "St", "s1", "s1", "s2",
                        "s2")),
    Morphotype = as.factor(c("Acropora", "Acropora", "Acropora", "Acropora",
                             "Acropora", "Acropora", "Branching", "Branching",
                             "Branching", "Branching", "Branching", "Branching",
                             "Branching", "Sand", "Sand", "Sand", "Sand")),
    Type = as.factor(c("biotic", "biotic", "biotic", "biotic", "biotic",
                       "biotic", "biotic", "biotic", "biotic", "biotic",
                       "biotic", "biotic", "biotic", "abiotic", "abiotic",
                       "abiotic", "abiotic"))
)

ggplot(df, aes(y = R, x = reorder(Genus, R, fun = mean), fill=Morphotype)) +
    geom_boxplot() +
    facet_grid(Type~Morphotype, scales = "free")

Note: Please notice the way I have fixed your reprex and the way I'm presenting my answer, you have to integrate the sample data into the code.

1 Like

I have adapted my previous code to data posted by andresrcs.

library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 3.5.3
library(tidyr)
#> Warning: package 'tidyr' was built under R version 3.5.3

df <- data.frame(
  R = c(2.25, 1.96, 1.51, 1.78, 2.12, 2.24, 2.31, 2.61, 2.08, 2.62,
        2.5, 3.1, 2.74, 2.64, 2.62, 2.65, 3.1),
  Genus = as.factor(c("Ab", "Ab", "Ac", "Ac", "At1", "At1", "En", "En",
                      "Mo", "Mo", "St", "St", "St", "s1", "s1", "s2",
                      "s2")),
  Morphotype = as.factor(c("Acropora", "Acropora", "Acropora", "Acropora",
                           "Acropora", "Acropora", "Branching", "Branching",
                           "Branching", "Branching", "Branching", "Branching",
                           "Branching", "Sand", "Sand", "Sand", "Sand")),
  Type = as.factor(c("biotic", "biotic", "biotic", "biotic", "biotic",
                     "biotic", "biotic", "biotic", "biotic", "biotic",
                     "biotic", "biotic", "biotic", "abiotic", "abiotic",
                     "abiotic", "abiotic"))
)

df <- df %>% unite(col = BothLabels, Type, Morphotype, sep = "_", remove = FALSE)

RmType <- function(string) {
  sub(".+_", "", string)
}

ggplot(df, aes(y=R, x=reorder(Genus, R, fun=mean),fill=Morphotype)) + geom_boxplot() + 
  facet_grid(~BothLabels,  labeller = labeller(BothLabels = RmType), scales = "free_x") +
  labs(x = "Genus")

Created on 2019-10-27 by the reprex package (v0.3.0.9000)

1 Like

3 posts were merged into an existing topic: change theme, labels in ggplot2 with conditions

Thank you for fixing my reprex - I will improve in the future!

That is one way of doing it, however it is the answer below that answers question 1 of my original posting. Thank you.

If you have a moment, would you be able to help with Q2, and Q3 from my original post?

Many thanks,
Emi

Hello,

That is fantastic! Thank you so much - exactly what I was hoping for.
I wonder if there is anyway to achieve Q2, and Q3 of my original posting? Is there a way to have two overarching titles over the biotic and abiotic types (Q2) , and also a way where the facet boxes can be sorted by group mean? (Q3, at the moment, the boxes are sorted alphabetically)

Many thanks,
Emily

I do not know how to achieve your Q2.

For Q3, do you mean like this?

library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 3.5.3
library(tidyr)
#> Warning: package 'tidyr' was built under R version 3.5.3
library(dplyr)
#> Warning: package 'dplyr' was built under R version 3.5.3
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

df <- data.frame(
  R = c(2.25, 1.96, 1.51, 1.78, 2.12, 2.24, 2.31, 2.61, 2.08, 2.62,
        2.5, 3.1, 2.74, 2.64, 2.62, 2.65, 3.1),
  Genus = as.factor(c("Ab", "Ab", "Ac", "Ac", "At1", "At1", "En", "En",
                      "Mo", "Mo", "St", "St", "St", "s1", "s1", "s2",
                      "s2")),
  Morphotype = as.factor(c("Acropora", "Acropora", "Acropora", "Acropora",
                           "Acropora", "Acropora", "Branching", "Branching",
                           "Branching", "Branching", "Branching", "Branching",
                           "Branching", "Sand", "Sand", "Sand", "Sand")),
  Type = as.factor(c("biotic", "biotic", "biotic", "biotic", "biotic",
                     "biotic", "biotic", "biotic", "biotic", "biotic",
                     "biotic", "biotic", "biotic", "abiotic", "abiotic",
                     "abiotic", "abiotic"))
)

df <- df %>% unite(col = BothLabels, Type, Morphotype, sep = "_", remove = FALSE) 
df <- df %>% mutate(BothLabels = reorder(BothLabels, R, mean))

RmType <- function(string) {
  sub(".+_", "", string)
}

ggplot(df, aes(y=R, x=reorder(Genus, R, fun=mean),fill=Morphotype)) + geom_boxplot() + 
  facet_wrap(~BothLabels,  labeller = labeller(BothLabels = RmType), scales = "free_x") +
  labs(x = "Genus")

Created on 2019-10-28 by the reprex package (v0.3.0.9000)

Hi FJCC,

That is exactly it within groups! Thanks. My only issue with this code is that when I use my larger dataset, it reorders all of the facet grids without taking the Type into account. So for example, the abiotic grids will be in the middle of the biotic grids.

Ideally I would like the biotic data to appear first, ordered by mean; then the abiotic data; and then a third category called morphotype in my larger dataset.

Is there a way to achieve this?

Many thanks,

Use tidytext::reorder_within() here is a blog post that explains how to use it

https://juliasilge.com/blog/reorder-within/

Thanks for the direction to the blog post!
However, I am struggling to understand how to work this into my code above, especially as the reorder_within() function seems to only allow you to sort the variable, in this case morphotype, by one factor (such as R or mean, not both), before specifying the group to sort within.
Does that make sense? I'm so sorry for my misunderstanding, but I just cant seem to work out where the reorder-within part of the code would go.

Would the reorder_witin function be in place of this part of the code, with the second function added to the last part of the +ggplot?