codermcgee
codermcgee

Reputation: 27

Merging two ggplot() boxplots together

I'm trying to make one graph that has 4 boxplots. Two for Word Test: Us and Non-US, and Two for Easy Test: Us and Non-Us. I'm trying to merge them together, so they look something like this:

What I want the graph to look like

I made two ggplots for each test, but I can't figure out a way to merge them together. Here is the tibble that I used. Please note that Q65 is for the Easy test and Q66 is for the Word test.

    # A tibble: 86 x 5
     Q65    Q66 nationality race_ethnicity  type
   <dbl>  <dbl> <chr>       <chr>          <dbl>
 1  55.1   51.2 Mexican     Mexican            2
 2  62.7   38.7 American    Asian              1
 3  53.2   34.7 USA         Hispanic           1
 4 193.    84.6 chinese     asian              2
 5  57.0   40.9 Taiwan      Asian              2
 6 103.    58.5 American    caucasian          1
 7  49.2   35.5 White       White              2
 8 213.  2135.  Chinese     Asian              2
 9  85.6   52.1 Chinese     Chinese            2
10 168.   113.  China       Asian              2
# ... with 76 more rows

Here is the code for the ggplots:

       EasyTestPlot <-
      ggplot(Qtibble, aes(as.factor(Qtibble$type), Q65, color = factor(type))) + geom_boxplot(
        alpha = 0.5, outlier.colour = "black", outlier.fill = "black", outlier.shape = 21, outlier.size = 
        2 ) + coord_cartesian(ylim = c(0, 250)) + labs(x = "Easy Test", y = "Number of Seconds to 
        Compare") + theme_light() + theme(axis.text.x = element_text(face = "bold", size = 10, angle =0),
        axis.text.y = element_text(face = "bold", size = 10, angle = 0))  + scale_x_discrete(labels = c("1" = "US", "2" = "Non-US")) + stat_summary(fun = mean, color = "darkred", position = position_dodge(0.75), geom = "point", shape = 18, size = 3, show.legend = FALSE) + scale_color_manual(values=c("Dark green", "red")) + labs(colour="Nationality",linetype="Nationality",shape="Nationality") + theme(legend.text = element_text(color = "white"),legend.title = element_text(color = "white"), legend.key = element_rect(fill = "white")) 
+ scale_color_discrete(guide = 
guide_legend(override.aes = list(color = "white")))

And

    WordTestPlot <-
      ggplot(Qtibble, aes(as.factor(Qtibble$type), Q66, color = factor(type))) + geom_boxplot(
        alpha = 0.5, outlier.colour = "black", outlier.fill = "black", outlier.shape = 21, outlier.size = 
        2 ) + coord_cartesian(ylim = c(0, 250)) + labs(x = "Word Test", y = "Number of Seconds to 
        Compare") + theme_light() + theme(axis.text.x = element_text(face = "bold", size = 10, angle =0),
        axis.text.y = element_text(face = "bold", size = 10, angle = 0))  + scale_x_discrete(labels = c("1" = "US", "2" = "Non-US")) + stat_summary(fun = mean, color = "darkred", position = position_dodge(0.75), geom = "point", shape = 18, size = 3, show.legend = FALSE) + scale_color_manual(values=c("Dark green", "red")) + labs(colour="Nationality",linetype="Nationality",shape="Nationality") + theme(legend.text = element_text(color = "white"),legend.title = element_text(color = "white"), legend.key = element_rect(fill = "white")) 
+ scale_color_discrete(guide = 
guide_legend(override.aes = list(color = "white")))

Also, I am using grid.arrange, but instead of being side by side I want it to be on one graph:

grid.arrange(WordTestPlot ,EasyTestPlot, nrow = 1, ncol =2)

What the graphs currently look like

What can I do to make the boxplots look like the first image?

Upvotes: 2

Views: 394

Answers (2)

Duck
Duck

Reputation: 39595

What you need is a facet approach. You can use facet_wrap() for that and the common structure for data in ggplot2 is using reshaped data as other users do. Here the code for a faceted plot. df is your data:

library(dplyr)
library(tidyr)
library(ggplot2)
#Code
df %>% pivot_longer(-c(nationality,race_ethnicity,type)) %>%
  ggplot(aes(x=factor(type),y=value,color = factor(type)))+
  geom_boxplot(alpha = 0.5, outlier.colour = "black",
               outlier.fill = "black", outlier.shape = 21,
               outlier.size =2)+coord_cartesian(ylim = c(0, 250))+
               labs(x = "Easy Test", y = "Number of Seconds to 
        Compare") +
  theme_light() +
  theme(axis.text.x = element_text(face = "bold", size = 10, angle =0),
        axis.text.y = element_text(face = "bold", size = 10, angle = 0))+
  scale_x_discrete(labels = c("1" = "US", "2" = "Non-US"))+
  stat_summary(fun = mean, color = "darkred",
               position = position_dodge(0.75),
               geom = "point",
               shape = 18, size = 3,
               show.legend = FALSE) +
  scale_color_manual(values=c("Dark green", "red")) +
  labs(colour="Nationality",linetype="Nationality",shape="Nationality") +
  theme(legend.text = element_text(color = "white"),
        legend.title = element_text(color = "white"),
        legend.key = element_rect(fill = "white"))+
  facet_wrap(.~name,scales = 'free',strip.position = 'bottom')+
  theme(panel.grid = element_blank(),
        strip.placement = 'outside',
        strip.background = element_blank(),
        strip.text = element_text(color='black',face='bold'))

Output:

enter image description here

If you wish only one y-axis you can replace the facet line with facet_wrap(.~name,scales = 'free_x',strip.position = 'bottom').

Upvotes: 1

akrun
akrun

Reputation: 887048

We can reshape the data into 'long' format and then apply the ggplot

library(dplyr)
library(tidyr)
library(ggplot2)
Qtibble_long <- Qtibble %>%
    pivot_longer(cols = Q65:Q66, names_to = 'Q6566') %>%
    mutate(type = factor(type))  %>%
    unite(typenew, Q6566, type)

and now use

ggplot(Qtibble_long, aes(typenew, value, color = typenew)) + 
 geom_boxplot(alpha = 0.5, outlier.colour = "black",
    outlier.fill = "black", outlier.shape = 21, outlier.size = 
     2) + 
 coord_cartesian(ylim = c(0, 250))

Upvotes: 0

Related Questions