Black Lives Matter. Please consider donating to Black Girls Code today.

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 is a free and open-source graphing library for R. We recommend you read our Getting Started guide for the latest installation or upgrade instructions, then move on to our Plotly Fundamentals tutorials or dive straight in to some Basic Charts tutorials.

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")

fig <- ggplotly(p)

fig

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")

fig <- ggplotly(p)

fig

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)

fig <- ggplotly(p)


fig

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())

fig <- ggplotly(p)

fig

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"))

fig <- ggplotly(p)

fig

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()

fig <- ggplotly(p)


fig

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")

fig <- ggplotly(p)

fig

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")

fig <- ggplotly(p)

fig

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")

fig <- ggplotly(p)

fig

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")

fig <- ggplotly(p)

fig

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")

fig <- ggplotly(p)

fig

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")

fig <- ggplotly(p)

fig

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")

fig <- ggplotly(p)

fig

What About Dash?

Dash for R is an open-source framework for building analytical applications, with no Javascript required, and it is tightly integrated with the Plotly graphing library.

Learn about how to install Dash for R at https://dashr.plot.ly/installation.

Everywhere in this page that you see fig, you can display the same figure in a Dash for R application by passing it to the figure argument of the Graph component from the built-in dashCoreComponents package like this:

library(plotly)

fig <- plot_ly() 
# fig <- fig %>% add_trace( ... )
# fig <- fig %>% layout( ... ) 

library(dash)
library(dashCoreComponents)
library(dashHtmlComponents)

app <- Dash$new()
app$layout(
    htmlDiv(
        list(
            dccGraph(figure=fig) 
        )
     )
)

app$run_server(debug=TRUE, dev_tools_hot_reload=FALSE)