Show Sidebar Hide Sidebar

geom_bar in ggplot2

How to make a bar chart in ggplot2 using geom_bar. Examples of grouped, stacked, overlaid, filled, and colored bar charts.

New to Plotly?

Plotly's R library is free and open source!
Get started by downloading the client and reading the primer.
You can set up Plotly to work in online or offline mode.
We also have a quick-reference cheatsheet (new!) to help you get started!

Version Check

Version 4 of Plotly's R package is now available!
Check out this post for more information on breaking changes and new features available in this version.

library(plotly)
packageVersion('plotly')
## [1] '4.9.1'

Bar Chart

library(plotly)

dat <- data.frame(
    time = factor(c("Lunch","Dinner"), levels=c("Lunch","Dinner")),
    total_bill = c(14.89, 17.23)
)

p <- ggplot(data=dat, aes(x=time, y=total_bill)) +
    geom_bar(stat="identity")

p <- ggplotly(p)

p

Colored Bar Chart

filled bar chart with geom_bar

library(plotly)

dat <- data.frame(
    time = factor(c("Lunch","Dinner"), levels=c("Lunch","Dinner")),
    total_bill = c(14.89, 17.23)
)

p <- ggplot(data=dat, aes(x=time, y=total_bill, fill=time)) +
    geom_bar(stat="identity")

p <- ggplotly(p)

p

No Legend

geom_bar with no legend

library(plotly)

dat <- data.frame(
    time = factor(c("Lunch","Dinner"), levels=c("Lunch","Dinner")),
    total_bill = c(14.89, 17.23)
)

# No legend, since the information is redundant
p <- ggplot(data=dat, aes(x=time, y=total_bill, fill=time)) +
    geom_bar(colour="black", stat="identity") +
    guides(fill=FALSE)

p <- ggplotly(p)


p

Position Dodge

geombar with positiondodge

library(plotly)

dat1 <- data.frame(
    sex = factor(c("Female","Female","Male","Male")),
    time = factor(c("Lunch","Dinner","Lunch","Dinner"), levels=c("Lunch","Dinner")),
    total_bill = c(13.53, 16.81, 16.24, 17.42)
)

# Bar graph, time on x-axis, color fill grouped by sex -- use position_dodge()
p <- ggplot(data=dat1, aes(x=time, y=total_bill, fill=sex)) +
    geom_bar(stat="identity", position=position_dodge())

p <- ggplotly(p)

p

Custom Colors

geom_bar with manual colors

library(plotly)

dat1 <- data.frame(
    sex = factor(c("Female","Female","Male","Male")),
    time = factor(c("Lunch","Dinner","Lunch","Dinner"), levels=c("Lunch","Dinner")),
    total_bill = c(13.53, 16.81, 16.24, 17.42)
)

p <- ggplot(data=dat1, aes(x=time, y=total_bill, fill=sex)) +
    geom_bar(stat="identity", position=position_dodge(), colour="black") +
    scale_fill_manual(values=c("#999999", "#E69F00"))

p <- ggplotly(p)

p

Styles & Themes

geom_bar with styles and theme

library(plotly)

dat1 <- data.frame(
    sex = factor(c("Female","Female","Male","Male")),
    time = factor(c("Lunch","Dinner","Lunch","Dinner"), levels=c("Lunch","Dinner")),
    total_bill = c(13.53, 16.81, 16.24, 17.42)
)

# A bar graph
p <- ggplot(data=dat1, aes(x=time, y=total_bill, fill=sex)) +
    geom_bar(colour="black", stat="identity",
             position=position_dodge(),
             size=.3) +                        # Thinner lines
    xlab("Time of day") + ylab("Total bill") + # Set axis labels
    ggtitle("Average bill for 2 people") +     # Set title
    theme_bw()

p <- ggplotly(p)


p

Variable Comparison

using geom_bar for variable comparison

library(plotly)

DF <- read.table(text="Rank F1     F2     F3
1    500    250    50
2    400    100    30
3    300    155    100
4    200    90     10", header=TRUE)

library(reshape2)
DF1 <- melt(DF, id.var="Rank")

p <- ggplot(DF1, aes(x = Rank, y = value, fill = variable)) +
  geom_bar(stat = "identity")

p <- ggplotly(p)

p

Error Bars

barplot with error bars

library(plotly)
library(dplyr)
set.seed(123)

df <- diamonds[sample(1:nrow(diamonds), size = 1000),]

df.summ <- df %>% group_by(cut) %>% summarize(Mean = mean(table), Min = min(table), Max = max(table))

p <- ggplot(df.summ, aes(x = cut, y = Mean, ymin = Min, ymax = Max, fill = cut)) + 
  geom_bar(stat = "identity") + 
  geom_errorbar() + 
  ggtitle("Bar chart with Error Bars")

p <- ggplotly(p)

p

Stacked Bar Chart

geom_bar with stacked traces

library(plotly)
library(dplyr)

df <- structure(c(106487, 495681, 1597442, 2452577, 2065141, 2271925, 4735484, 3555352, 8056040, 4321887, 2463194, 347566, 621147, 1325727, 1123492, 800368, 761550, 1359737, 1073726, 36, 53, 141, 41538, 64759, 124160, 69942, 74862, 323543, 247236, 112059, 16595, 37028, 153249, 427642, 1588178, 2738157, 2795672, 2265696, 11951, 33424, 62469, 74720, 166607, 404044, 426967, 38972, 361888, 1143671, 1516716, 160037, 354804, 996944, 1716374, 1982735, 3615225, 4486806, 3037122, 17, 54, 55, 210, 312, 358, 857, 350, 7368, 8443, 6286, 1750, 7367, 14092, 28954, 80779, 176893, 354939, 446792, 33333, 69911, 53144, 29169, 18005, 11704, 13363, 18028, 46547, 14574, 8954, 2483, 14693, 25467, 25215, 41254, 46237, 98263, 185986), .Dim = c(19, 5), .Dimnames = list(c("1820-30", "1831-40", "1841-50", "1851-60", "1861-70", "1871-80", "1881-90", "1891-00", "1901-10", "1911-20", "1921-30", "1931-40", "1941-50", "1951-60", "1961-70", "1971-80", "1981-90", "1991-00", "2001-06"), c("Europe", "Asia", "Americas", "Africa", "Oceania")))
df.m <- melt(df)
df.m <- rename(df.m, Period = Var1, Region = Var2)

p <- ggplot(df.m, aes(x = Period, y = value/1e+06,fill = Region)) + ggtitle("Migration to the United States by Source Region (1820-2006), In Millions")
p <- p + geom_bar(stat = "identity", position = "stack")

p <- ggplotly(p)

p

Ordered Bar Chart

ordering variable in geom_bar

library(plotly)
library(plyr)

dane<-data.frame(x=1:10,y=seq(-5,4),g=rep(c('A','B'),each=5))
dane$x<-as.factor(dane$x)

p <- ggplot(data=dane,aes(x=x,y=y,fill=g)) +
    geom_bar(stat="identity")

p <- ggplotly(p)

p

Precentages

using geom_bar to show percentages

library(plotly)
set.seed(123)

df <- diamonds[sample(1:nrow(diamonds), size = 1000),]

p <- ggplot(df, aes(x = color)) + 
  geom_bar(aes(y = ..count../sum(..count..), fill = cut)) + 
  scale_fill_brewer(palette = "Set3") + 
  ylab("Percent") + 
  ggtitle("Show precentages in bar chart")

p <- ggplotly(p)

p

Manuel Colors

using geom_bar to manually specify colors

library(plotly)
library(RColorBrewer)
set.seed(123)

df <- diamonds[sample(1:nrow(diamonds), size = 1000),]

# Simply use fill = a vector of colors
p <- ggplot(df, aes(x = color)) +
  geom_bar(fill = brewer.pal(length(unique(df$color)), "Set3")) + 
  ylab("Count") + 
  ggtitle("Specify manual colors in a bar chart")

p <- ggplotly(p)

p

Reordered Bar Chart

Re-ordering bars shown using geom_bar

library(plotly)

df <- data.frame(x = as.factor(LETTERS[1:5]), 
                 y = sample(10:20, size = 5))

# First change factor levels
df$x <- factor(df$x, levels = c("C", "B", "A", "D", "E"))

# Plot
p <- ggplot(df, aes(x, y, fill = x)) + 
  geom_bar(stat = "identity") +
  ggtitle("Bar Chart with changed factor levels")

p <- ggplotly(p)

p