Search code examples
rggplot2plotpointfacet

ggplot: geom_dotplot, center the dots over multiple lines


I have the following dotplot:

enter image description here

I want to achieve two things:

  1. Instead of having the dots in a single row per facet, I want the dots to be lined across two rows (with 5 dots in the first row, and a further 5 dots in the second row), like this:

enter image description here

  1. In each facet, the dotplots should be in the very center.

Is it possible to achieve this with geom_dotplot()? I would be grateful for your help!

My dataframe:

df <- tibble::tibble(
  has_twitter = c(0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1),
  Quartile = c("Q1", "Q1", "Q1", "Q1", "Q1", "Q1", "Q1", "Q1", "Q1", "Q1", 
    "Q2", "Q2", "Q2", "Q2", "Q2", "Q2", "Q2", "Q2", "Q2", "Q2", "Q3", 
    "Q3", "Q3", "Q3", "Q3", "Q3", "Q3", "Q3", "Q3", "Q3", "Q4", "Q4", 
    "Q4", "Q4", "Q4", "Q4", "Q4", "Q4", "Q4", "Q4")

My ggplot:

library(ggplot2)
ggplot(df, aes(x = Quartile, y = 1)) +
  geom_dotplot(binaxis="y",
               fill = factor(df$has_twitter),
               binwidth = 1,
               dotsize=0.2,
               stackdir="centerwhole") +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank()) +
  facet_wrap(~ Quartile, nrow = 4)

Solution

  • Is this a solution you are looking for?

    library(tidyverse)
    
    # data manipulation
    df1 <- df %>% 
        mutate(group = ifelse(Quartile == "Q1" | Quartile == "Q2", "Q1_Q2", "Q3_Q4")) %>% 
        group_by(group) %>% 
        mutate(id = rep(row_number(), each=10, length.out = n()))
    
    # plot
    ggplot(df1, aes(x = 0.9, y = id)) +
        geom_dotplot(binaxis="y",
                     fill = factor(df$has_twitter),
                     binwidth = 1,
                     dotsize=0.2,
                     binpositions = "all") +
        theme(axis.title = element_blank(),
              axis.text = element_blank(),
              axis.ticks = element_blank()) +
        facet_wrap(~ group, nrow =2) +
        coord_cartesian(xlim = c(0.5, 1.5))
    

    enter image description here