2

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"))
KC15
  • 150
  • 10

1 Answers1

3

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.

r2evans
  • 141,215
  • 6
  • 77
  • 149
  • Thank you for your answer! First, I had an error in the data which I solved. Second, this is unfortunately not the solution I was hoping for.. I want the two plots within the same grafic... – KC15 Jul 07 '22 at 11:38
  • 1
    These two plots _are_ within the same graphic. Are you hoping they would share the same legend? If so, see https://stackoverflow.com/a/59324590/3358272 (but the legends are different ...) – r2evans Jul 07 '22 at 11:41
  • I want them to share the same x-axis. Basically, that one plot is layed on top of the other – KC15 Jul 07 '22 at 11:47
  • 2
    See my edit, I think it's what you're trying to do (at least a start). – r2evans Jul 07 '22 at 12:13
  • 2
    btw I appreciate all the explanations along with your code! It gives me and other beginners the opportunity to learn a lot! – KC15 Jul 07 '22 at 17:27