Search code examples
rggplot2visualizationcategorical-data

Vertical dots showing distribution for several groups in the same plot


I have a data frame with the following structure:

dat <- data.frame(
values = c (2,  5,  6,  7,   
            4,  6,  8,  9,   
             6, 8,  10, 13),
race = c("black", "black", "black",  "black", 
          "white", "white", "white",   "white",
           "Hispanic", "Hispanic",  "Hispanic",  "Hispanic"))

I would like to graph the data so that each "race" appears on the x-axis and the "values" are on the y-axis. I really don't want a barplot -- instead, I want to plot all the data points (because a barplot obscures the fact that there may be outliers, and it hides the gaps in each distribution, etc.)

I know most people would prefer a boxplot, violin plot, or other variant here... but I would really like a vertical dot plot that shows all the data points by racial group, like the one I drew by hand (please see below).

I have tried the following:

p <- ggplot(data = dat, 
aes(x = race, y =  values)) + geom_point()
p + facet_wrap(~race, nrow = 1)

but, of course, I end up with 3 panels -- like this: facet-plot

but I want all 3 columns of dots to appear in a single panel.

This is really what I want: drawn-by-hand

(The graph I drew by hand does not reflect the actual data I have in my dataframe above, but you get the idea)


Solution

  • Just for fun:

    "This is really what I want"

    library(ggplot2)
    
    dat <- data.frame(
      values = c (2,  5,  6,  7,   
                  4,  6,  8,  9,   
                  6, 8,  10, 13),
      race = c("Black", "Black", "Black",  "Black", 
               "White", "White", "White",   "White",
               "Hispanic", "Hispanic",  "Hispanic",  "Hispanic"))
    
    
    ggplot(data = dat, 
           aes(x = race, y =  values, color = race)) + 
      geom_point(size = 4, show.legend = FALSE)+
      scale_color_manual(values = c("#0102fc", "#f3554f", "#04cefe"))+
      scale_y_continuous(breaks=c(0:max(dat$values)))+
      labs(x = "", y = "", color="")+
      expand_limits(x = 0, y = 0)+
      theme_classic()+
      theme(
        text = element_text(size=16),
        axis.line = element_line(colour = '#074489', linewidth = 1.5),
        axis.text.y = element_text(colour = "#074489"),
        axis.text.x = element_text(colour = c("#0102fc", "#f3554f", "#04cefe")),
        axis.ticks.length=unit(.25, "cm")
        )
    
    

    enter image description here