1

For example, i have two trials, each with main factors of year and treatment. I want to plot response to the same plot, preferably Trial one / treatment / year and the same for trial 2. Closest that i can get is shown on the simple example picture. Basically i get two graphs joined together, one showing effects of treatment in trial 1 and trial 2 with y axis representing content, and other showing effect of year in trial 1 and trial 2 with y axis representing the same content.

Simple example of plot with Si content affected by treatments and year of sampling

Is it possible to facet wrap graphs together, or at least to remove redundant y axis?

Code that i use is:

a <- ggplot(I1, aes(x=fct_reorder(SISTEM, ORDER), y=Si)) + geom_jitter(show.legend=FALSE, width=0.25, color="black", size=0.5) + stat_summary(fun.data = mean_cl_normal, show.legend=FALSE, color="red", size=0.3) + labs(x=NULL,
   y="Si (mg / 100 g)") + facet_wrap(~POSKUS, ncol=2, scales="free_x") + theme_classic(base_family = "Palatino Linotype") + theme(axis.text=element_text(colour="black", size=8), axis.title=element_text(colour="black", size=8), axis.text.x=element_text(angle=45, vjust = 1, hjust=1)) + theme(strip.background = element_blank()) + ggplot(I1, aes(x=Leto, y=Si)) + geom_jitter(show.legend=FALSE, width=0.25, color="black", size=0.5) + scale_x_continuous(breaks=c(2016,2017)) + stat_summary(fun.data = mean_cl_normal, show.legend=FALSE, color="red", size=0.3) + labs(x=NULL,
   y="") + facet_wrap(~POSKUS + Leto, ncol=4, scales="free_x") + theme_classic(base_family = "Palatino Linotype") + theme(axis.text=element_text(colour="black", size=8), axis.title=element_text(colour="black", size=8), axis.text.x=element_text(angle=45, vjust = 1, hjust=1)) +  theme(strip.background = element_blank())`

The solution as given below sorta works with minor tweaks still needed. Using the provided code, and expanding it to sort the treatments as needed, and changing the order of variables in the facet wrap provided the plot as shown in figure 2. However, facets labels are now showing only 1 and 2 rather than Trial 1 and Trial 2. Furthermore, is it possible to have only one Trial 1 and Trial 2 name for both TREATMENT and YEAR variables? Plot using the code as proposed

Added dput:

I2 <- structure(list(Leto = c("2016", "2016", "2016", "2016", "2016", 
"2016", "2016", "2016", "2016", "2016", "2016", "2016", "2016", 
"2016", "2016", "2017", "2017", "2017", "2017", "2017", "2017", 
"2017", "2017", "2017", "2017", "2017", "2017", "2017", "2017", 
"2017", "2016", "2016", "2016", "2016", "2016", "2016", "2016", 
"2016", "2016", "2016"), POSKUS = structure(c(1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L), .Label = c("Trial 1", "Trial 2"), class = "factor"), 
    SISTEM = structure(c(5L, 5L, 5L, 1L, 1L, 1L, 2L, 2L, 2L, 
    3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 1L, 1L, 1L, 2L, 2L, 2L, 
    3L, 3L, 3L, 4L, 4L, 4L, 6L, 6L, 6L, 7L, 7L, 7L, 8L, 8L, 8L, 
    9L), .Label = c("Manure-N0", "Manure-N1", "Manure-N2", "Manure-N3", 
    "No.org-N0", "No.org-N3", "Straw-N0", "Straw-N1", "Straw-N2", 
    "Straw-N3"), class = "factor"), ORDER = c(1, 1, 1, 2, 2, 
    2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 1, 1, 1, 2, 2, 2, 3, 3, 3, 
    4, 4, 4, 5, 5, 5, 5, 5, 5, 1, 1, 1, 2, 2, 2, 3), DUSIK = c(0, 
    0, 0, 0, 0, 0, 55, 55, 55, 110, 110, 110, 165, 165, 165, 
    0, 0, 0, 0, 0, 0, 55, 55, 55, 110, 110, 110, 165, 165, 165, 
    165, 165, 165, 0, 0, 0, 55, 55, 55, 110), Si = c(9.35, 11.6, 
    9.71, 8.96, 6.13, 7.08, 3.74, 3.72, 4.75, 1.3, 1.82, 3.41, 
    5.13, 3.41, 3.68, 7.67, 7.48, 6.21, 5.02, 9.46, 7.79, 8.11, 
    3.59, 8.28, 7.36, 9.69, 9.08, 6.46, 5.48, 7.9, 5.27, 4.06, 
    4.22, 5.6, 5.92, 6.9, 3.26, 4.45, 3.09, 4.38), P = c(2.62, 
    2.26, 2.33, 2.57, 3.06, 2.99, 1.71, 2.06, 2.18, 1.48, 1.71, 
    2.66, 2.24, 2.38, 2.55, 2.49, 2.48, 3.9, 2.65, 1.79, 2.88, 
    2.54, 3.22, 2.54, 2.88, 2.93, 3.26, 2.09, 3.03, 2.56, 2.43, 
    2.72, 2.59, 2.58, 3.71, 2.5, 2.45, 2.48, 3.49, 3.31), S = c(1.24, 
    0.95, 1.07, 1.17, 1.15, 1.15, 0.81, 1.08, 1.07, 0.89, 0.85, 
    1.15, 1.12, 1.22, 1.24, 1.16, 0.98, 1.32, 1.29, 1.04, 1, 
    0.9, 1.19, 1.03, 1.14, 1.05, 1.14, 1.1, 1.13, 1.25, 0.92, 
    1.19, 0.84, 1.27, 1.14, 1.05, 1.29, 1.05, 1.15, 1.02), Cl = c(0.39, 
    0.31, 0.32, 0.3, 0.39, 0.38, 0.24, 0.26, 0.32, 0.35, 0.3, 
    0.31, 0.3, 0.32, 0.28, 0.3, 0.24, 0.27, 0.29, 0.28, 0.25, 
    0.34, 0.38, 0.34, 0.33, 0.31, 0.33, 0.33, 0.31, 0.35, 0.25, 
    0.25, 0.26, 0.35, 0.35, 0.39, 0.33, 0.25, 0.25, 0.28), K = c(4.47, 
    4.05, 3.59, 4.18, 4.07, 4.43, 3.12, 3.79, 4.63, 5.02, 4.52, 
    4.49, 4.64, 4.21, 4.38, 4.27, 4.08, 5.23, 3.66, 3.39, 4.14, 
    3.99, 4.21, 3.83, 4.19, 4.95, 5.11, 3.44, 4.27, 4.6, 4.99, 
    4.54, 4.12, 3.82, 5.55, 4.48, 3.7, 3.8, 5.08, 4.47), Ca = c(0.78, 
    0.68, 0.66, 0.69, 0.77, 0.73, 0.46, 0.6, 0.66, 0.59, 0.61, 
    0.71, 0.77, 0.58, 0.7, 0.61, 0.79, 0.87, 0.77, 0.69, 0.84, 
    0.62, 0.77, 0.62, 0.66, 0.71, 0.68, 0.59, 0.67, 0.73, 0.62, 
    0.69, 0.61, 0.69, 0.8, 0.72, 0.56, 0.6, 0.63, 0.65), Ti = c(78.5, 
    73.7, 74, 69, 68.9, 52.3, 33.7, 35, 26.6, 41, 50.7, 42.2, 
    33.6, 38.7, 41.5, 56.9, 64.6, 60.1, 69.4, 65.7, 65.7, 52.6, 
    42.2, 46.1, 50.8, 44.1, 35.6, 47.3, 39.2, 47.7, 39.6, 40.3, 
    38.2, 67.9, 52.3, 63.1, 43.4, 35.1, 37.2, 27), Fe = c(56.2, 
    52.9, 57.1, 48.8, 46.7, 35.1, 45.8, 48.6, 49.6, 71.5, 66, 
    85.7, 45.6, 70.2, 58.8, 75.6, 85.2, 93.9, 85.7, 68.7, 70.1, 
    61.2, 60.6, 76.8, 113, 68.5, 74.9, 91.9, 44.4, 104, 62.1, 
    55.3, 78.5, 75.7, 51.7, 53.2, 49, 74.4, 51.9, 57.6), Zn = c(31.3, 
    29.9, 28, 27.4, 27.9, 27.7, 19.6, 19.6, 22, 20.6, 23.1, 20.6, 
    25.1, 22.6, 22.7, 32.5, 35.5, 31.1, 28.6, 29.2, 29.6, 21.8, 
    29.5, 25, 26.1, 24.7, 20.1, 23.9, 20.3, 24.6, 20.3, 21.1, 
    26.6, 27.4, 32.6, 30.4, 19.9, 21.8, 24.7, 20.7), Br = c(8.54, 
    7.65, 6.27, 5.83, 7.25, 6.92, 4.74, 4.79, 4.51, 7.53, 5.02, 
    4.35, 3.98, 3.64, 4.26, 10, 13.7, 12.7, 7.67, 8.62, 10.1, 
    2.52, 3.63, 2.7, 2.44, 2.73, 2.49, 5.9, 2.52, 2.56, 6.05, 
    5.6, 6.98, 7.81, 12.3, 8.11, 5.91, 6.01, 6.15, 5.74), Rb = c(1.95, 
    1.53, 2.12, 1.44, 2.54, 1.84, 1.62, 2.78, 2.35, 3.24, 3.62, 
    3.48, 4.74, 3.34, 4.21, 5.43, 3.94, 5.55, 3.01, 2.19, 3.34, 
    3.55, 5.08, 2.63, 5.44, 4.67, 4.71, 6.52, 2.99, 3.24, 4.19, 
    3.11, 4.11, 1.57, 1.26, 1.14, 1.95, 2.21, 2.57, 2.41), Sr = c(0.94, 
    0.97, 0.86, 1.07, 1.19, 1.97, 1.08, 1.23, 1.35, 1.23, 1.17, 
    1.03, 0.86, 0.96, 0.86, 3.51, 1.94, 3.44, 1.47, 1.95, 2.14, 
    1.36, 4.22, 2.07, 1.92, 1.8, 2.34, 2.89, 2.13, 2.62, 1.3, 
    1.16, 1.95, 1, 1.41, 0.77, 1.25, 1.09, 1.37, 1.28), N = c(5.68, 
    4.93, 4.36, 6.36, 4.68, 5, 4.67, 3.38, 3.33, 3.94, 3.61, 
    3.52, 3.03, 2.74, 2.7, 8.47, 7.33, 5.82, 8.01, 7.34, 7.12, 
    5.84, 4.5, 4.17, 3.91, 3.57, 2.35, 3.44, 4.2, 1.94, 2.97, 
    3.1, 3.42, 5.04, 5.42, 7.35, 3.28, 3.55, 4.2, 3.79), C = c(-29.04, 
    -28.81, -29.12, -28.91, -29.07, -29.13, -29.16, -29.16, -28.98, 
    -28.81, -28.74, -28.56, -28.58, -28.33, -28.51, -29.49, -30.45, 
    -30.34, -29.91, -30.13, -30.86, -30.3, -30.23, -30.46, -29.69, 
    -29.43, -29.74, -29.75, -29.92, -29.52, -28.44, -28.24, -28.01, 
    -28.68, -28.77, -29.13, -29.13, -29.41, -29, -28.85)), row.names = c(NA, 
40L), class = "data.frame")
stefan
  • 90,330
  • 6
  • 25
  • 51
Ales Kolma
  • 27
  • 4

1 Answers1

1

One way to achieve your desired result using faceting would be to split your dataframe into two like so:

  1. The first dataframe contains the data by treatment, the second the data by year.
  2. In each of these data frames rename the vars to be plotted on the x-axis to have the same name (I chose ´x). Doing so allows use to have one x-axis for the two different variables. But make sure to convert year or ´Leto to a character.
  3. Add an identifier to each data.frame which could be used for facetting (besides your variable POSKUS).
  4. Splitting the data into two df we need both two geom_jitter and two stat_summary layers.
  5. Finally I added a custom labelled function to facet_wrap to show only the trial labels in the facet strip text.
library(dplyr)
library(ggplot2)

d1 <- I2 %>% 
  select(x = SISTEM, Si, POSKUS) %>% 
  mutate(name = "SISTEM", name = factor(name, levels = c("SISTEM", "Leto")))

d2 <- I2 %>% 
  select(x = Leto, Si, POSKUS) %>% 
  mutate(name = "Leto", name = factor(name, levels = c("SISTEM", "Leto")))

base <- ggplot(mapping = aes(x = x, y = Si)) +
  geom_jitter(data = d1, show.legend = FALSE, width = 0.25, color = "black", size = 0.5) +
  stat_summary(data = d1, fun.data = mean_cl_normal, show.legend = FALSE, color = "red", size = 0.3) +
  geom_jitter(data = d2, show.legend = FALSE, width = 0.25, color = "black", size = 0.5) +
  stat_summary(data = d2, fun.data = mean_cl_normal, show.legend = FALSE, color = "red", size = 0.3) +
  labs(
    x = NULL,
    y = "Si (mg / 100 g)"
  ) +
  #theme_classic(base_family = "Palatino Linotype") +
  theme_classic() +
  theme(axis.text = element_text(colour = "black", size = 8), 
        axis.title = element_text(colour = "black", size = 8), 
        axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
  theme(strip.background = element_blank())

base +
  facet_wrap(~name+POSKUS, nrow = 1, scales = "free_x", labeller = function(d) list(as.character(d$POSKUS)))
#> Warning: Removed 1 rows containing missing values (geom_segment).

EDIT To have only one label for each trial after changing the order of the variables you could make use of ggh4x:: facet_nested_wrap:

base +
  ggh4x::facet_nested_wrap(~POSKUS+name, nrow = 1, scales = "free_x", labeller = function(d) list(as.character(d$POSKUS)))
#> Warning: Removed 1 rows containing missing values (geom_segment).

stefan
  • 90,330
  • 6
  • 25
  • 51
  • Many thanks. I updated my question with the result that I get using your approach. As shown, there are now problems with facet labels, producing only 1 and 2 instead of Trial 1 and Trial 2. Furthermore, if possible only one Trial label for both factors should be used. – Ales Kolma Jun 30 '21 at 07:08
  • Hi Ales. I just made an edit to fix the issue with the duplicated strip labels. Concerning the issue with the labels showing only 1 and 2 ... As my code works fine with the **random example data** I guess that this issue is related to your real data which could not be fixed without providing a snippet of your data. See [how to make a minimal reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) To post your data type `dput(NAME_OF_DATASET)` into the console and copy & paste the output starting with `structure(....` into your post. – stefan Jun 30 '21 at 09:04
  • If your dataset has a lot of observations you could do `dput(head(NAME_OF_DATASET, 40))` for the first 40 rows of data. Or try to make a random example dataset as I did to mimic the structure of your data. – stefan Jun 30 '21 at 09:06
  • I have added the first 40 rows as requested. Hopefully you can spot the problem. – Ales Kolma Jun 30 '21 at 13:16
  • Hi Ales. I just made another edit. Already guessed that the issue was that `POSKUS` was a factor in your real data. To fix the issue with the labels my edit now uses `list(as.character(d$POSKUS))` in the `labeller` function. – stefan Jun 30 '21 at 13:31
  • Great, perfect. The solution works perfectly. One final question though, i want to manually add group significance letters on the top of the plots. Closest that i can get is specifying letter within "Trial 1" and "Trial 2". Problem is, that for example within "trials groups" i have two separate factors (fertilization and year). Using my approach generates 5 levels of factor "year" with the same significance letters as specified for factor "fertilization". – Ales Kolma Jul 03 '21 at 10:04
  • Is it possible to add a compact letter display on top of each faceted group? I cannot find a solution for this nested design. I can open a new topic if necessary because this question is beyond my original problem. Many thanks in advance. – Ales Kolma Jul 06 '21 at 12:02