10

I have a data which can be divaded via two seperators. One is year and second is a field characteristics.

box<-as.data.frame(1:36)

box$year <- c(1996,1996,1996,1996,1996,1996,1996,1996,1996,
              1997,1997,1997,1997,1997,1997,1997,1997,1997,
              1996,1996,1996,1996,1996,1996,1996,1996,1996,
              1997,1997,1997,1997,1997,1997,1997,1997,1997)
box$year <- as.character(box$year)

box$case <- c(6.40,6.75,6.11,6.33,5.50,5.40,5.83,4.57,5.80,
              6.00,6.11,6.40,7.00,NA,5.44,6.00,  NA,6.00,
              6.00,6.20,6.40,6.64,6.33,6.60,7.14,6.89,7.10,
              6.73,6.27,6.64,6.41,6.42,6.17,6.05,5.89,5.82)

box$code <- c("L","L","L","L","L","L","L","L","L","L","L","L",
              "L","L","L","L","L","L","M","M","M","M","M","M",
              "M","M","M","M","M","M","M","M","M","M","M","M")

colour <- factor(box$code, labels = c("#F8766D", "#00BFC4"))

In boxplots, I want to display points over them, to see how data is distributed. That is easily done with one single boxplot for every year:

ggplot(box, aes(x = year, y = case, fill = "#F8766D")) +
  geom_boxplot(alpha = 0.80) +
  geom_point(colour = colour, size = 5) +
  theme(text = element_text(size = 18),
        axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.major.x = element_blank(),
        legend.position = "none")

enter image description here

But it become more complicated as I add fill parameter in them:

ggplot(box, aes(x = year, y = case, fill = code)) +
  geom_boxplot(alpha = 0.80) +
  geom_point(colour = colour, size = 5) +
  theme(text = element_text(size = 18),
        axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.major.x = element_blank(),
        legend.position = "none")

enter image description here

And now the question: How to move these points to boxplot axes, where they belong? As blue points to blue boxplot and red to red one.

Community
  • 1
  • 1
Kryštof Chytrý
  • 348
  • 1
  • 3
  • 15
  • [`geom_dotplot`](http://docs.ggplot2.org/current/geom_dotplot.html) using `binaxis = 'y'` may also be of interest. – bouncyball Jan 20 '17 at 14:00

2 Answers2

21

Like Henrik said, use position_jitterdodge() and shape = 21. You can clean up your code a bit too:

  1. No need to define box, then fill it piece by piece
  2. You can let ggplot hash out the colors if you wish and skip constructing the colors factor. If you want to change the defaults, look into scale_fill_manual and scale_color_manual.

    box <- data.frame(year = c(1996,1996,1996,1996,1996,1996,1996,1996,1996,
                      1997,1997,1997,1997,1997,1997,1997,1997,1997,
                      1996,1996,1996,1996,1996,1996,1996,1996,1996,
                      1997,1997,1997,1997,1997,1997,1997,1997,1997),
                      case  = c(6.40,6.75,6.11,6.33,5.50,5.40,5.83,4.57,5.80,
                      6.00,6.11,6.40,7.00,NA,5.44,6.00,  NA,6.00,
                      6.00,6.20,6.40,6.64,6.33,6.60,7.14,6.89,7.10,
                      6.73,6.27,6.64,6.41,6.42,6.17,6.05,5.89,5.82),
                      code = c("L","L","L","L","L","L","L","L","L","L","L","L",
                      "L","L","L","L","L","L","M","M","M","M","M","M",
                      "M","M","M","M","M","M","M","M","M","M","M","M"))
    
    ggplot(box, aes(x = factor(year), y = case, fill = code)) +
      geom_boxplot(alpha = 0.80) +
      geom_point(aes(fill = code), size = 5, shape = 21, position = position_jitterdodge()) +
      theme(text = element_text(size = 18),
            axis.title.x = element_blank(),
            axis.title.y = element_blank(),
            panel.grid.minor.x = element_blank(),
            panel.grid.major.x = element_blank(),
            legend.position = "none")
    

enter image description here

Jake Kaupp
  • 7,892
  • 2
  • 26
  • 36
6

I see you've already accepted @JakeKaupp's nice answer, but I thought I would throw in a different option, using geom_dotplot. The data you are visualizing is rather small, so why not forego the boxplot?

ggplot(box, aes(x = factor(year), y = case, fill = code))+
    geom_dotplot(binaxis = 'y', stackdir = 'center',
                 position = position_dodge())

enter image description here

bouncyball
  • 10,631
  • 19
  • 31