Combined bar plot and points in ggplot2

22,809

Solution 1

You can add layers together, but if they have different data and/or aesthetics you'll want to include the data and aes arguments in each graphical layer.

p3 <- ggplot() +
    geom_bar(data=my_dat, aes(y=my_mean,x=cyl,ymin=my_mean-my_se,ymax=my_mean+my_se), stat="identity", width = 0.75) + 
    geom_errorbar(data=my_dat, aes(y=my_mean,x=cyl,ymin=my_mean-my_se,ymax=my_mean+my_se), width = 0.75) +
    geom_point(data=mtcars, aes(y=disp, x=cyl, fill=cyl)) +
    ylim(c(0,500)) +
    theme_classic()

If you want to make it so that the the points are off to the side of the bars, you could subtract an offset from the cyl values to move over the points. Like @LukeA mentioned, by changing the geom_point to geom_point(data=mtcars, aes(y=disp, x=cyl-.5, fill=cyl)).

Solution 2

You can specify each layer individually to ggplot2. Often you are using the same data frame and options for each geom, so it makes sense to set defaults in ggplot(). In your case you should specify each geom separately:

library(ggplot2)
library(gridExtra)
library(dplyr)

se <- function(x){sd(x)/sqrt(length(x))}
my_dat <- summarise(group_by(mtcars, cyl),
                    my_mean = mean(disp),
                    my_se = se(disp))
p1 <- ggplot() + 
  geom_bar(data = my_dat,
           aes(y = my_mean, x = cyl,
               ymin = my_mean - my_se,
               ymax = my_mean + my_se), stat="identity", width=0.75) + 
  geom_errorbar(data = my_dat,
                aes(y = my_mean, x = cyl,
                    ymin = my_mean - my_se,
                    ymax = my_mean + my_se), stat="identity", width=0.75) + 
  geom_point(data = mtcars, aes(y = disp, x = cyl, fill = cyl)) +
  theme_classic() + ylim(c(0,500))

p1
Share:
22,809
jokel
Author by

jokel

Updated on March 03, 2020

Comments

  • jokel
    jokel about 4 years

    I would like to plot a "combined" bar plot with points. Consider to following dummy data:

    library(ggplot2)
    library(gridExtra)
    library(dplyr)
    
    se <- function(x){sd(x)/sqrt(length(x))}
    
    p1 <- ggplot(mtcars, aes(y=disp, x=cyl, fill=cyl)) 
    p1 <- p1 + geom_point() + theme_classic() + ylim(c(0,500))
    
    my_dat <- summarise(group_by(mtcars, cyl), my_mean=mean(disp),my_se=se(disp))
    
    p2 <- ggplot(my_dat, aes(y=my_mean,x=cyl,ymin=my_mean-my_se,ymax=my_mean+my_se))
    p2 <- p2 + geom_bar(stat="identity",width=0.75) +     geom_errorbar(stat="identity",width=0.75) + theme_classic() + ylim(c(0,500))
    

    The final plot should look like that: example plot

  • lukeA
    lukeA about 9 years
    Or geom_point(data=mtcars, aes(y=disp, x=cyl-.5, fill=cyl)) to get the desired offset.