Combine two graphs from two datasets in one ggplot

Viewed 43

I want two combine a boxplot and a barplot in one graph with two y-axes. They should match on the name of the x-axis. In the code I provide the code and the data for each plot.

Plot 1:

ggplot(F3a, aes(x= name, fill = name, y = value))+
  geom_boxplot(alpha = 0.7)+
  geom_dotplot(binaxis = "y", stackdir = "center", position = "dodge")+
  theme_bw()+
  theme(legend.position = "bottom",
        legend.title = element_text(size=8),
        legend.text=element_text(size=8),
        axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank()
  )+
  guides(fill=guide_legend(nrow=4,byrow=TRUE))+
  labs( x = "", y = "Zufriedenheit", fill = "")+
  scale_y_continuous(trans = "reverse", breaks = c(1,2,3,4,5))+
  scale_color_viridis_d(aesthetics = "fill")+
  ylim(5,1)

 structure(list(name = c("Newsletter", "Blog", "Rückmeldungen zu \nfachlichen Anfragen beim\n DRK-Generalsekretariat", 
"Fortbildungen", "Treffen der \n Landesreferent:innen", "Newsletter", 
"Blog", "Rückmeldungen zu \nfachlichen Anfragen beim\n DRK-Generalsekretariat", 
"Treffen der \n Landesreferent:innen", "Newsletter", "Blog", 
"Rückmeldungen zu \nfachlichen Anfragen beim\n DRK-Generalsekretariat", 
"Fortbildungen", "Treffen der \n Landesreferent:innen", "Newsletter", 
"Blog", "Rückmeldungen zu \nfachlichen Anfragen beim\n DRK-Generalsekretariat", 
"Fortbildungen", "Treffen der \n Landesreferent:innen", "Newsletter", 
"Blog", "Rückmeldungen zu \nfachlichen Anfragen beim\n DRK-Generalsekretariat", 
"Fortbildungen", "Treffen der \n Landesreferent:innen", "Newsletter", 
"Blog", "Rückmeldungen zu \nfachlichen Anfragen beim\n DRK-Generalsekretariat", 
"Fortbildungen", "Treffen der \n Landesreferent:innen", "Newsletter", 
"Blog", "Rückmeldungen zu \nfachlichen Anfragen beim\n DRK-Generalsekretariat", 
"Fortbildungen", "Treffen der \n Landesreferent:innen", "Fortbildungen", 
"Newsletter", "Fortbildungen", "Newsletter", "Blog", "Rückmeldungen zu \nfachlichen Anfragen beim\n DRK-Generalsekretariat", 
"Fortbildungen", "Treffen der \n Landesreferent:innen", "Newsletter", 
"Blog", "Fortbildungen", "Treffen der \n Landesreferent:innen"
), value = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 2, 1, 
2, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 3, 1, 1, 1, 1, 
1, 2, 2, 2, 2, 1, 2, 1, 1)), row.names = c(NA, -46L), class = c("tbl_df", 
"tbl", "data.frame"))

Code and data for the second plot:

ggplot(F1a, aes(x = name, y = percent, fill = name))+
  geom_col(alpha = 0.8)+
  theme_bw()+
  labs(x = "Angebot", y = "Prozent" )+
  scale_color_viridis_d(aesthetics = "fill")

structure(list(name = structure(c(1L, 4L, 2L, 3L, 5L), .Label = c("Blog", 
"Fortbildungen", "Newsletter", "Fachliche Anfragen beim \n DRK-Generalsekretariat", 
"Treffen der \n Landesreferent:innen"), class = "factor"), value = c(1, 
1, 1, 1, 1), n = c(9L, 8L, 9L, 10L, 9L), percent = c(18.8, 16.7, 
18.8, 20.8, 18.8)), row.names = c(NA, -5L), class = c("tbl_df", 
"tbl", "data.frame"))
1 Answers

Edit: the first answer (using patchwork) is preserved below.


First, you have a name that is different between them.

setdiff(F3a$name, F1a$name)
# [1] "Rückmeldungen zu \nfachlichen Anfragen beim\n DRK-Generalsekretariat"
setdiff(F1a$name, F3a$name)
# [1] "Fachliche Anfragen beim \n DRK-Generalsekretariat"

I'm inferring that these should be the same. I'll (arbitrarily) choose one of them and change the other.

F3a$name["Rückmeldungen zu \nfachlichen Anfragen beim\n DRK-Generalsekretariat" == F3a$name] <- "Fachliche Anfragen beim \n DRK-Generalsekretariat"

From here, we'll add geom_col(data=..). However, ylim(5,1) is breaking its addition, so I'll make a few other changes (noted) to aesthetics to get an approximation. I'll add sec.axis/sec_axis to get another y-axis.

ggplot(F3a, aes(x= name, fill = name, y = 6 - value)) +          # CHANGE
  geom_col(mapping = aes(x = name, y = percent/10, fill = name), # ADD
           data = F1a, alpha = 0.8, inherit.aes = FALSE) +
  geom_boxplot(alpha = 0.7) +
  geom_dotplot(binaxis = "y", stackdir = "center", position = "dodge") +
  theme_bw() +
  theme(legend.position = "bottom",
        legend.title = element_text(size=8),
        legend.text=element_text(size=8),
        axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank()
  ) +
  guides(fill=guide_legend(nrow=4,byrow=TRUE)) +
  labs( x = "", y = "Zufriedenheit", fill = "") +
  scale_color_viridis_d(aesthetics = "fill") +
  scale_y_continuous(breaks = c(1,2,3,4,5),                      # CHANGE
                     sec.axis = sec_axis(~ 10 * ., breaks = seq(0, 20 , by = 4)))

ggplot with combined methods

You are likely to want to change the height of the columns; for that, make sure that you change both the divisor /10 and the second axis scaler ~ 10 * ..


Especially since you have two different plotting methods, I suggest the patchwork package.

gg3a <- ggplot(F3a, aes(x= name, fill = name, y = value))+
  geom_boxplot(alpha = 0.7)+
  geom_dotplot(binaxis = "y", stackdir = "center", position = "dodge")+
  theme_bw()+
  theme(legend.position = "bottom",
        legend.title = element_text(size=8),
        legend.text=element_text(size=8),
        axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank()
  )+
  guides(fill=guide_legend(nrow=4,byrow=TRUE))+
  labs( x = "", y = "Zufriedenheit", fill = "")+
  scale_y_continuous(trans = "reverse", breaks = c(1,2,3,4,5))+
  scale_color_viridis_d(aesthetics = "fill")+
  ylim(5,1)
# Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.
gg1a <- ggplot(F1a, aes(x = name, y = percent, fill = name))+
  geom_col(alpha = 0.8)+
  theme_bw()+
  labs(x = "Angebot", y = "Prozent" )+
  scale_color_viridis_d(aesthetics = "fill")

And then simply this to combine them:

gg1a / gg3a

two ggplots combined

One can also do gg3a + gg1a for side-by-side joining. There are many other ways that patchwork can arrange multiple images, I suggest you read its docs.

Related