Can this type of plot be done with ggplot2?

Viewed 319

I am using R and ggplot2 to do some plots for publishing purposes. I have come across this plot and I would like to replicate it using ggplot2. However, I have never seen a plot like this made using ggplot2.

Can it be done with ggplot2? What about the text below the bars? I guess these will have to be hard coded in the ggplot2 codes. And how do you align those text?

Bar graph

3 Answers

This gets fairly close:

# Generate sample data (I'm too lazy to type out the full labels)
df <- data.frame(
    perc = c(60, 36, 44, 41, 42, 57, 34, 52),
    type = rep(c("blue", "green"), 4),
    label = rep(c(
        "Individual reports created as needed",
        "Regular reports on single topics",
        "Analytics using data integrated from multiple systems",
        "Business unit-specific dashboards and visuals"), each = 2))


library(ggplot2)
ggplot(df, aes(1, perc, fill = type)) +
    geom_col(position = "dodge2") +
    scale_fill_manual(values = c("turquoise4", "forestgreen"), guide = FALSE) +
    facet_wrap(~ label, ncol = 1, strip.position = "bottom") +
    geom_text(
        aes(y = 1, label = sprintf("%i%%", perc)),
        colour = "white",
        position = position_dodge(width = .9),
        hjust = 0,
        fontface = "bold") +
    coord_flip(expand = F) +
    theme_minimal() +
    theme(
        axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        strip.text = element_text(angle = 0, hjust = 0, face = "bold"))

enter image description here

A few explanations:

  1. We use dodged bars and matching dodged labels with position = "dodge2" (note that this requires ggplot_ggplot2_3.0.0, otherwise use position = position_dodge(width = 1.0)) and position = position_dodge(width = 0.9), respectively.
  2. We use facet_wrap and force a one-column layout; strip labels are moved to the bottom.
  3. We rotate the entire plot with coord_flip(expand = F), where expand = F ensures that left aligned (hjust = 0) facet strip texts align with 0.
  4. Finally we tweak the theme to increase the overall aesthetic similarity.

You can try using the data from the other answer. Differences are: we use scales::percent to draw percents. We use ggpubr::theme_transparent() theme to tweak as less as possible.

df$perc <- c(.60, .36, .44, .41, .42, .57, .34, .52)

ggplot(df, aes(label, perc, label=scales::percent(round(perc,2)),fill= factor(type))) + 
   geom_col(position = position_dodge(0.9), show.legend = F) + 
   geom_text(aes(y=0), position = position_dodge(0.9), size=5, hjust=-0.1, color="white", fontface="bold") +
   scale_y_continuous("",labels = scales::percent) + 
   coord_flip(expand = F) + 
   facet_wrap(~label,scales = "free", strip.position = "bottom", ncol = 1) +
   ggpubr::theme_transparent() +
   xlab("") + 
   theme(strip.background = element_blank(),
         strip.text = element_text(size = 12, face = "bold",hjust=0))

enter image description here

Maybe using facet wrap and adjusting the style?

dat <- data.frame(perc = c(60, 20, 90, 30), col = rep(c("gr1", "gr2"), 2),
                  text = c(rep("text1", 2), rep("text2", 2)))

ggplot(dat, aes(y = perc, x = col, fill = col)) +
  geom_bar(stat = "identity", position = "dodge") +
  coord_flip() +
  facet_wrap(~text, strip.position = "bottom", ncol = 1)
Related