Overview
In this tutorial, we’ll learn how to create a bar chart in R using the ggplot2 package. Here’s a brief overview of what we’ll cover:
How to create a bar chart How to Create a Bar Chart
A bar chart is an effective way to compare categorical data.
show code ggplot( candy ) +
aes( x = rating, y = reorder (name, rating ) ) +
geom_bar( stat = "identity" , fill = "steelblue" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 )) +
labs( alt = "Bar chart of candy ratings, ordered from highest to lowest (Jolly Ranchers - 4.7, Jelly Beans - 4.5, Cotton Candy - 4.2, Lollipop - 4.0, Gummy Bears - 3.8, Marshmallow - 3.5)" ,
title = "Kids love Jolly Ranchers & Jelly Beans" ,
subtitle = "Ratings (1-5)" ,
caption = "Source: The School of Data" ,
x = NULL , y = NULL ) +
theme_minimal() +
theme( text = element_text( family = "PT Sans" ) ,
panel.grid.major.y = element_blank() ,
panel.grid.minor.y = element_blank() ,
plot.title.position = "plot" ,
plot.caption.position = "plot" ,
plot.title = element_text( face = "bold" , size = 16 ) ,
plot.subtitle = element_text( face = "italic" , 12 ) ,
axis.text = element_text( size = 12 ))
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2"> Step 1: Create a base layer
Start with the ggplot
function and specify the data frame.
show code ggplot( candy )
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2"> Use the aes
function to map the variables to x and y axes.
show code ggplot( candy ) +
aes( x = rating, y = name )
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2"> Step 3: Add geometric objects
Use geom_bar(stat = "identity")
to create the bars.
show code ggplot( candy ) +
aes( x = rating, y = name ) +
geom_bar( stat = "identity" )
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2"> Adjust the x-axis position and set appropriate limits and breaks.
show code ggplot( candy ) +
aes( x = rating, y = name ) +
geom_bar( stat = "identity" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 ))
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2"> Step 5: Add labels and titles
Add alt text, title, subtitle, and caption to the plot.
show code ggplot( candy ) +
aes( x = rating, y = name ) +
geom_bar( stat = "identity" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 )) +
labs( alt = "Bar chart of candy ratings" ,
title = "Kids love Jolly Ranchers & Jelly Beans" ,
subtitle = "Ratings (1-5)" ,
caption = "Source: The School of Data" ,
x = NULL , y = NULL ) +
theme( plot.title.position = "plot" )
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2"> Apply a theme and customize text appearance.
show code ggplot( candy ) +
aes( x = rating, y = name ) +
geom_bar( stat = "identity" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 )) +
labs( alt = "Bar chart of candy ratings" ,
title = "Kids love Jolly Ranchers & Jelly Beans" ,
subtitle = "Ratings (1-5)" ,
caption = "Source: The School of Data" ,
x = NULL , y = NULL ) +
theme_minimal() +
theme( text = element_text( family = "PT Sans" ) ,
panel.grid.major.y = element_blank() ,
panel.grid.minor.y = element_blank() ,
plot.title.position = "plot" ,
plot.title = element_text( face = "bold" , size = 16 ) ,
plot.subtitle = element_text( face = "italic" , 12 ) ,
axis.text = element_text( size = 12 ))
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2"> Change the color of the bars and fine-tune the appearance.
show code ggplot( candy ) +
aes( x = rating, y = name ) +
geom_bar( stat = "identity" , fill = "steelblue" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 )) +
labs( alt = "Bar chart of candy ratings (Jelly Beans - 4.5, Gummy Bears - 3.8, Lollipop - 4.0, Cotton Candy - 4.2, Jolly Ranchers - 4.7, Marshmallow - 3.5)" ,
title = "Kids love Jolly Ranchers & Jelly Beans" ,
subtitle = "Ratings (1-5)" ,
caption = "Source: The School of Data" ,
x = NULL , y = NULL ) +
theme_minimal() +
theme( text = element_text( family = "PT Sans" ) ,
panel.grid.major.y = element_blank() ,
panel.grid.minor.y = element_blank() ,
plot.title.position = "plot" ,
plot.caption.position = "plot" ,
plot.title = element_text( face = "bold" , size = 16 ) ,
plot.subtitle = element_text( face = "italic" , 12 ) ,
axis.text = element_text( size = 12 ))
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2"> Reorder the bars based on the rating values for better visualization.
show code ggplot( candy ) +
aes( x = rating, y = reorder (name, rating ) ) +
geom_bar( stat = "identity" , fill = "steelblue" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 )) +
labs( alt = "Bar chart of candy ratings, ordered from highest to lowest (Jolly Ranchers - 4.7, Jelly Beans - 4.5, Cotton Candy - 4.2, Lollipop - 4.0, Gummy Bears - 3.8, Marshmallow - 3.5)" ,
title = "Kids love Jolly Ranchers & Jelly Beans" ,
subtitle = "Ratings (1-5)" ,
caption = "Source: The School of Data" ,
x = NULL , y = NULL ) +
theme_minimal() +
theme( text = element_text( family = "PT Sans" ) ,
panel.grid.major.y = element_blank() ,
panel.grid.minor.y = element_blank() ,
plot.title.position = "plot" ,
plot.caption.position = "plot" ,
plot.title = element_text( face = "bold" , size = 16 ) ,
plot.subtitle = element_text( face = "italic" , 12 ) ,
axis.text = element_text( size = 12 ))
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2">
Getting started
We’ll use a custom dataset called candy
throughout this course. Here’s how we create it:
Step 1: Create a base layer
Let’s start by creating the base layer of our plot. You won’t see anything yet, but this is the first step in creating a ggplot2 plot.
ggplot( candy )
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2">
Step 2: Add aesthetic layer
The next step is to add an aesthetic layer to our plot. We’ll map the rating
variable to the x-axis and the name
variable to the y-axis. This tells ggplot2 how to represent the data visually.
We’ll see a blank canvas with the x and y axes labeled with the variables we mapped.
Step 3: Add geom layer
Now that we have our aesthetic layer set up, we can add the geometric layer to create the bars. We’ll use the geom_bar()
function with the stat = "identity"
argument. This tells ggplot2 to use the actual values in the data to create the bars.
Now, let’s format our axis. We’ll move the x-axis to the top, set limits from 0 to 5, and add breaks at every integer:
ggplot( candy ) +
aes( x = rating, y = name ) +
geom_bar( stat = "identity" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 ))
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2">
Step 5: Add text
Let’s add some text elements to our plot. We will add alt text, title, subtitle, and caption. We’ll also remove the x and y axis labels since we mention it in the title (this is optional).
ggplot( candy ) +
aes( x = rating, y = name ) +
geom_bar( stat = "identity" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 )) +
labs( alt = "Bar chart of candy ratings" ,
title = "Kids love Jolly Ranchers & Jelly Beans" ,
subtitle = "Ratings (1-5)" ,
caption = "Source: The School of Data" ,
x = NULL , y = NULL ) +
theme( plot.title.position = "plot" )
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2">
Step 6: Modify theme
Now, let’s format our text. We’ll use the theme_minimal()
theme and customize the appearance of our text elements. We’ll also remove the y-axis gridlines to declutter the plot. We increased the font size of the title and subtitle for better readability.
ggplot( candy ) +
aes( x = rating, y = name ) +
geom_bar( stat = "identity" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 )) +
labs( alt = "Bar chart of candy ratings" ,
title = "Kids love Jolly Ranchers & Jelly Beans" ,
subtitle = "Ratings (1-5)" ,
caption = "Source: The School of Data" ,
x = NULL , y = NULL ) +
theme_minimal() +
theme( text = element_text( family = "PT Sans" ) ,
panel.grid.major.y = element_blank() ,
panel.grid.minor.y = element_blank() ,
plot.title.position = "plot" ,
plot.title = element_text( face = "bold" , size = 16 ) ,
plot.subtitle = element_text( face = "italic" , 12 ) ,
axis.text = element_text( size = 12 ))
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2">
Step 7: Customize bars
Let’s add some color. We’ll change the fill color of the bars to steelblue and customize the appearance of the plot further:
ggplot( candy ) +
aes( x = rating, y = name ) +
geom_bar( stat = "identity" , fill = "steelblue" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 )) +
labs( alt = "Bar chart of candy ratings (Jelly Beans - 4.5, Gummy Bears - 3.8, Lollipop - 4.0, Cotton Candy - 4.2, Jolly Ranchers - 4.7, Marshmallow - 3.5)" ,
title = "Kids love Jolly Ranchers & Jelly Beans" ,
subtitle = "Ratings (1-5)" ,
caption = "Source: The School of Data" ,
x = NULL , y = NULL ) +
theme_minimal() +
theme( text = element_text( family = "PT Sans" ) ,
panel.grid.major.y = element_blank() ,
panel.grid.minor.y = element_blank() ,
plot.title.position = "plot" ,
plot.caption.position = "plot" ,
plot.title = element_text( face = "bold" , size = 16 ) ,
plot.subtitle = element_text( face = "italic" , 12 ) ,
axis.text = element_text( size = 12 ))
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2">
Step 8: Reorder bars
Finally, let’s reorder our bars based on the rating. To do this we can wrap the y axis variable with the reorder()
function. The first argument in reorder
is the variable to reorder, and the second argument is the variable to order by. In this case, we’re ordering the name
variable by the rating
variable.
ggplot( candy ) +
aes( x = rating, y = reorder (name, rating ) ) +
geom_bar( stat = "identity" , fill = "steelblue" ) +
scale_x_continuous( position = "top" , limits = c ( 0 , 5 ) , breaks = seq ( 0 , 5 , 1 )) +
labs( alt = "Bar chart of candy ratings, ordered from highest to lowest (Jolly Ranchers - 4.7, Jelly Beans - 4.5, Cotton Candy - 4.2, Lollipop - 4.0, Gummy Bears - 3.8, Marshmallow - 3.5)" ,
title = "Kids love Jolly Ranchers & Jelly Beans" ,
subtitle = "Ratings (1-5)" ,
caption = "Source: The School of Data" ,
x = NULL , y = NULL ) +
theme_minimal() +
theme( text = element_text( family = "PT Sans" ) ,
panel.grid.major.y = element_blank() ,
panel.grid.minor.y = element_blank() ,
plot.title.position = "plot" ,
plot.caption.position = "plot" ,
plot.title = element_text( face = "bold" , size = 16 ) ,
plot.subtitle = element_text( face = "italic" , 12 ) ,
axis.text = element_text( size = 12 ))
copied = true)" @mouseleave.debounce.1000ms="copied && (copied = false)" @keydown.enter.debounce.1000ms="copied && (copied = false)" @keydown.space.debounce.1000ms="copied && (copied = false)" @touchstart.debounce.1000ms="copied && (copied = false)" class="group flex select-none items-center justify-between gap-2 rounded p-2 hover:bg-3 hover:text-brand focus-visible:outline-none focus-visible:ring-1 motion-safe:transition-colors absolute right-0 top-0 text-2">
This is how you can create a bar chart in R using ggplot2. By following these steps, you can create clear and informative bar charts that effectively communicate your data insights.
If you need to customize your plots further, you can explore the ggplot2 documentation. You can visit https://ggplot2.tidyverse.org .
Practice
Exercise Try using a different variable like price
. Replace the blank spaces in the code with the variable name and see how the bar chart changes.
Add a title and subtitle that best describe the data you’re visualizing. For example, your title can be “Price of Candy by Type” and subtitle can be “Price in USD”.
Quiz Which ggplot2 geometry is typically used to create a bar chart? What does 'stat = 'identity' mean in geom_bar()? Which function is used to add labels to a ggplot2 chart?
Review
Congratulations! You’ve successfully created a bar chart in R using ggplot2. Here’s a quick recap of the steps we followed:
Step 1: Create a base layer with ggplot()
.
Step 2: Add aesthetics using aes()
.
Step 3: Add geometric objects with geom_bar(stat = "identity")
.
Step 4: Format the axis with scale_x_continuous()
.
Step 5: Add labels and titles with labs()
.
Step 6: Customize the appearance with theme_minimal()
and theme()
.
Step 7: Customize the bars with fill
and further theme modifications.
Step 8: Reorder the bars for better data presentation.
In the next section, we’ll learn how to create a column chart in R with ggplot2. Let’s continue our data visualization journey!