---
description: A bar chart is a great way to display categorical variables in the x-axis. This type of graph denotes two aspects in the y-axis. The first one counts the number of occurrence between groups.The second
title: Bar Chart &#038; Histogram in R with Example
image: https://www.guru99.com/images/bar-chart-histogram-in-r.png
---

[Skip to content](#main)

**⚡ Smart Summary**

Bar Chart and Histogram in R are built with ggplot2, using geom\_bar() for categorical counts and geom\_histogram() for continuous distributions. This walkthrough customises colour, grouping, stacking, orientation, binning, and in-bar labels on the mtcars dataset.

- 📊 **Core Distinction:** A bar chart summarises a categorical variable, while a histogram bins a single continuous variable into intervals.
- 🧱 **Grammar of Graphics:** Every plot combines a dataset, an aes() mapping, and a geometric object joined with the plus sign.
- 🎨 **Colour Control:** Place fill inside geom\_bar() for one uniform colour, and inside aes() to colour bars by group.
- 📐 **Position Adjustments:** position = “fill” converts counts to percentages and position\_dodge() places grouped bars side by side.
- 🔢 **Plotting Values:** Pass stat = “identity” when the y-axis already holds a computed statistic such as a group mean.
- 📏 **Histogram Binning:** Set bins or binwidth in geom\_histogram(), because the default of 30 bins rarely suits the data.

Read More

![Bar Chart Histogram in R]()

## What is a Bar Chart in R?

A bar chart is a great way to display categorical variables in the x-axis. This type of graph denotes two aspects in the y-axis.

1. The first counts the number of occurrences in each group.
2. The second shows a summary statistic (minimum, maximum, average and so on) of a variable on the y-axis.

You will use the mtcars dataset, which has the following variables:

- cyl: Number of the cylinder in the car. Numeric variable
- am: Type of transmission. 0 for automatic and 1 for manual. Numeric variable
- mpg: Miles per gallon. Numeric variable

Because a histogram looks so similar, it is worth settling the difference before writing any code.

## Bar Chart vs Histogram in R: Key Differences

The two charts look alike, and they are constantly confused. They answer different questions and use different geometric objects.

| Criteria | Bar Chart | Histogram |
| --- | --- | --- |
| X-axis variable | Categorical or factor | Continuous and numeric |
| What a bar represents | One category | One interval, or bin, of values |
| Gaps between bars | Yes, categories are separate | No, bins are adjacent |
| Bar order | Can be rearranged freely | Fixed by the numeric scale |
| Question answered | How do groups compare? | How is one variable distributed? |
| ggplot2 object | geom\_bar() | geom\_histogram() |

The rule of thumb: if reordering the bars would still make sense, you have a bar chart. If reordering them would destroy the meaning, you have a histogram. For quartile-based summaries of the same continuous variable, use a [box plot](https://www.guru99.com/r-boxplot-tutorial.html).

## How to Create a Bar Chart in R

To create graph in [R](https://www.guru99.com/r-tutorial.html), you can use the library ggplot which creates ready-for-publication graphs. The basic syntax of this library is:

```
ggplot(data, mapping = aes()) +
geometric object 

arguments: 
data: dataset used to plot the graph 
mapping: Control the x and y-axis 
geometric object: The type of plot you want to show. The most common objects are:

- Point: `geom_point()`
- Bar: `geom_bar()`
- Line: `geom_line()`
- Histogram: `geom_histogram()` 

```

This tutorial focuses on the geometric object geom\_bar(), which draws the bar chart, and on geom\_histogram() for continuous data.

## Bar chart: count

Your first graph shows the frequency of cylinder with geom\_bar(). The code below is the most basic syntax.

```
library(ggplot2)
# Most basic bar chart
ggplot(mtcars, aes(x = factor(cyl))) +
    geom_bar()

```

Code Explanation

- You pass the dataset mtcars to ggplot.
- Inside the aes() argument, you set the x-axis to the factor variable cyl
- The + sign means you want R to keep reading the code. It makes the code more readable by breaking it.
- Use geom\_bar() for the geometric object.

**Output:**

[![Bar chart: count]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis1.png)

**Note**: make sure you convert the variables into a factor otherwise R treats the variables as numeric. See the example below.

[![Bar chart: count]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis2.png)

## Customize the graph

Four arguments can be passed to customize the graph:

```
- `stat`: Controls what is plotted on the y-axis. By default `count`, which tallies rows. To plot a value you already computed, pass `stat = "identity"`
- `alpha`: Control density of the color
- `fill`: Change the color of the bar
- `size`: Control the size the bar	

```

### Change the color of the bars

You can change the color of the bars. Note that the colors of the bars are all similar.

```
# Change the color of the bars
ggplot(mtcars, aes(x = factor(cyl))) +
    geom_bar(fill = "coral") +
    theme_classic()

```

Code Explanation

- The colors of the bars are controlled by the aes() mapping inside the geometric object (i.e. not in the ggplot()). You can change the color with the fill arguments. Here, you choose the coral color.

**Output:**

[![Change the Color of the Bars]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis3.png)

You can use this code:

```
grDevices::colors()
```

to see all the colors available in R. There are around 650 colors.

### Change the intensity

You can increase or decrease the intensity of the bars’ color

```
# Change intensity
ggplot(mtcars,
        aes(factor(cyl))) +
    geom_bar(fill = "coral",
        alpha = 0.5) +
    theme_classic()

```

Code Explanation

- To increase/decrease the intensity of the bar, you can change the value of the alpha. A large alpha increases the intensity, and low alpha reduces the intensity. alpha ranges from 0 to 1. At 1 the colour matches the palette exactly; at 0 the bar is invisible. Here you choose alpha = 0.5.

**Output:**

[![Change the Intensity]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis4.png)

### Color by groups

You can change the colors of the bars, meaning one different color for each group. For instance, cyl variable has three levels, then you can plot the bar chart with three colors.

```
# Color by group
ggplot(mtcars, aes(factor(cyl),
        fill = factor(cyl))) +
    geom_bar()

```

Code Explanation

- The argument fill inside the aes() changes the colour of the bar. You change the color by setting fill = x-axis variable. In your example, the x-axis variable is cyl; fill = factor(cyl)

**Output:**

[![Color by Groups]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis5.png)

### Add a group in the bars

You can further split the y-axis based on another factor level. For instance, you can count the number of automatic and manual transmission based on the cylinder type.

You will proceed as follow:

- Step 1: Create the data frame with mtcars dataset
- Step 2: Label the am variable with auto for automatic transmission and man for manual transmission. Convert am and cyl as a factor so that you don’t need to use factor() in the ggplot() function.
- Step 3: Plot the bar chart to count the number of transmission by cylinder

```
library(dplyr)
# Step 1
data <- mtcars %>% 
#Step 2
mutate(am = factor(am, labels = c("auto", "man")),
    cyl = factor(cyl))

```

With the dataset ready, you can plot the graph:

\# Step 3

```
ggplot(data, aes(x = cyl, fill = am)) +
    geom_bar() +
    theme_classic()

```

Code Explanation

- The ggplot() call receives the dataset data and the aes() mapping.
- In the aes() you include the variable x-axis and which variable is required to fill the bar (i.e. am)
- geom\_bar(): Create the bar chart

**Output:**

[![Add a Group in the Bars]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis6.png)

The mapping will fill the bar with two colors, one for each level. It is effortless to change the group by choosing other factor variables in the dataset.

### Bar chart in percentage

You can visualize the bar in percentage instead of the raw count.

\# Bar chart in percentage

```
ggplot(data, aes(x = cyl, fill = am)) +
    geom_bar(position = "fill") +
    theme_classic()

```

Code Explanation

- Use position = “fill” in the geom\_bar() argument to create a graphic with percentage in the y-axis.

**Output:**

[![Bar Chart in Percentage]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis7.png)

### Side by side bars

It is easy to plot the bar chart with the group variable side by side.

```
# Bar chart side by side
ggplot(data, aes(x = cyl, fill = am)) +
    geom_bar(position = position_dodge()) +
    theme_classic()

```

Code Explanation

- position=position\_dodge(): Explicitly tells how to arrange the bars

**Output:**

[![Side by Side Bars]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis8.png)

**Don't Miss:**

- [What is R Programming Language? Introduction & Basics of R](https://www.guru99.com/r-programming-introduction-basics.html)
- [Functions in R Programming with Example](https://www.guru99.com/r-functions-programming.html)
- [R Select(), Filter(), Arrange(), Pipeline with Example](https://www.guru99.com/r-select-filter-arrange.html)
- [Scatter Plot in R Using ggplot2 with Example](https://www.guru99.com/r-scatter-plot-ggplot2.html)

## Bar Chart with a Summary Statistic

In the second part of the tutorial, the y-axis carries a computed value rather than a count. Note that this is still a bar chart: a true histogram is covered further down, and it uses a different geometric object.

Your objective is to create a graph with the average mile per gallon for each type of cylinder. To draw an informative graph, you will follow these steps:

- Step 1: Create a new variable with the average mile per gallon by cylinder
- Step 2: Create a basic histogram
- Step 3: Change the orientation
- Step 4: Change the color
- Step 5: Change the size
- Step 6: Add labels to the graph

**Step 1)** Create a new variable

You create a data frame named data\_histogram which simply returns the average miles per gallon by the number of cylinders in the car. You call this new variable mean\_mpg, and you round the mean with two decimals.

\# Step 1

```
data_histogram <- mtcars %>%
mutate(cyl = factor(cyl)) %>%
group_by(cyl) %>%
summarize(mean_mpg = round(mean(mpg), 2))

```

**Step 2)** Create a basic histogram

You can plot the histogram. It is not yet polished enough to hand to a client, but it already shows the trend.

```
ggplot(data_histogram, aes(x = cyl, y = mean_mpg)) +
    geom_bar(stat = "identity")

```

Code Explanation

- The aes() has now two variables. The cyl variable refers to the x-axis, and the mean\_mpg is the y-axis.
- You pass stat = “identity” so that geom\_bar() uses the y-axis variable as it is instead of counting rows. The default for geom\_bar() is stat = “count”.

**Output:**

[![Histogram]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis9.png)

**Step 3)** Change the orientation

You change the orientation of the graph from vertical to horizontal.

```
ggplot(data_histogram, aes(x = cyl, y = mean_mpg)) +
    geom_bar(stat = "identity") +
    coord_flip()

```

Code Explanation

- You can control the orientation of the graph with coord\_flip().

**Output:**

[![Histogram]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis10.png)

**Step 4)** Change the color

You can differentiate the colors of the bars according to the factor level of the x-axis variable.

```
ggplot(data_histogram, aes(x = cyl, y = mean_mpg, fill = cyl)) +
    geom_bar(stat = "identity") +
    coord_flip() +
    theme_classic()

```

Code Explanation

- You can plot the graph by groups with the fill= cyl mapping. R takes care automatically of the colors based on the levels of cyl variable

**Output:**

[![Histogram]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis11.png)

**Step 5)** Change the size

To make the graph looks prettier, you reduce the width of the bar.

```
graph <- ggplot(data_histogram, aes(x = cyl, y = mean_mpg, fill = cyl)) +
    geom_bar(stat = "identity",
        width = 0.5) +
    coord_flip() +
    theme_classic()

```

Code Explanation

- The width argument inside geom\_bar() controls the thickness of the bar. A larger value makes it wider.
- The plot is stored in the object graph, because the next step reuses it unchanged. Storing intermediate plots keeps the code readable.

**Output:**

[![Histogram]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis12.png)

**Step 6)** Add labels to the graph

The last step adds the value of mean\_mpg as a label inside each bar.

```
graph +
    geom_text(aes(label = mean_mpg),
        hjust = 1.5,
        color = "white",
        size = 3) +
    theme_classic()

```

Code Explanation

- The function geom\_text() is useful to control the aesthetic of the text.
  - label=: Add a label inside the bars
  - mean\_mpg: Use the variable mean\_mpg for the label
- hjust controls where the label sits along the bar. Values close to 1 place it near the end of the bar, and larger values push it back towards the axis. If the orientation of the graph is vertical, change hjust to vjust.
- color=”white”: Change the color of the text. Here you use the white color.
- size=3: Set the size of the text.

**Output:**

[![Histogram]()](https://www.guru99.com/images/r_programming/032918_0752_BarChartHis13.png)

## How to Order and Label Bars in a Bar Chart in R

Two finishing touches separate a draft chart from a publishable one: sorting the bars by value and labelling the axes properly.

**Reordering bars.** ggplot2 arranges factor levels alphabetically by default, which is rarely the most informative order. Wrap the x variable in reorder() to sort by a second variable:

```
# Sort the bars from lowest to highest mean_mpg
ggplot(data_histogram, aes(x = reorder(cyl, mean_mpg), y = mean_mpg)) +
    geom_bar(stat = "identity", fill = "coral") +
    theme_classic()
```

Prefix the sorting variable with a minus sign, reorder(cyl, -mean\_mpg), to reverse the direction.

**Adding titles and axis labels.** The labs() function sets every text element in one call:

```
ggplot(data_histogram, aes(x = cyl, y = mean_mpg, fill = cyl)) +
    geom_bar(stat = "identity") +
    labs(title = "Average fuel economy by cylinder count",
        subtitle = "mtcars dataset",
        x = "Number of cylinders",
        y = "Mean miles per gallon",
        fill = "Cylinders",
        caption = "Source: mtcars") +
    theme_classic()
```

Set fill = NULL inside labs() to drop the legend title entirely, and use theme(legend.position = “none”) to remove the legend when the x-axis already names the groups.

**Choosing your own colours.** Replace the default palette with an explicit one so the chart matches your house style:

```
scale_fill_manual(values = c("4" = "#0e9cd1", "6" = "coral", "8" = "grey40"))
```

## How to Create a Histogram in R with geom\_histogram()

A histogram shows how a single continuous variable is distributed. Instead of counting categories, ggplot2 slices the numeric range into bins and counts how many observations fall into each one.

```
library(ggplot2)
# Most basic histogram
ggplot(mtcars, aes(x = mpg)) +
    geom_histogram()
```

R prints a message recommending that you pick a better bin count, because the default of 30 bins is arbitrary. Two arguments control this:

- **bins**: the number of intervals to split the range into.
- **binwidth**: the width of each interval, expressed in the units of the variable. Use this one when the units are meaningful.

```
# Set the number of bins
ggplot(mtcars, aes(x = mpg)) +
    geom_histogram(bins = 10, fill = "coral", color = "white") +
    theme_classic()

# Or set the width of each bin instead
ggplot(mtcars, aes(x = mpg)) +
    geom_histogram(binwidth = 4, fill = "coral", color = "white") +
    theme_classic()
```

Binning is the single most important choice in a histogram. Too few bins hide real structure such as a second peak; too many turn the chart into noise. Try several values before settling on one.

**Comparing groups.** Map a factor to fill and set the position so the distributions stay readable:

```
ggplot(mtcars, aes(x = mpg, fill = factor(cyl))) +
    geom_histogram(bins = 10, position = "identity", alpha = 0.5) +
    theme_classic()
```

With position = “identity” and a reduced alpha the histograms overlap so you can compare shapes directly. Use position = “dodge” if you would rather see the bins side by side.

**Density instead of counts.** When the groups differ in size, plot density so the areas are comparable, and overlay a smoothed curve:

```
ggplot(mtcars, aes(x = mpg)) +
    geom_histogram(aes(y = after_stat(density)), bins = 10,
        fill = "coral", alpha = 0.6) +
    geom_density(color = "steelblue", linewidth = 1) +
    theme_classic()
```

## Bar Chart and Histogram in R: Code Reference

A bar chart suits a categorical x-axis, where the y-axis is either a count or a summary statistic. The table below lists the ggplot2 call for each variant covered above:

| Objective | Code |
| --- | --- |
| Count | <pre>ggplot(df, aes(x = factor(x1))) + geom_bar()</pre> |
| Count with different color of fill | <pre>ggplot(df, aes(x = factor(x1), fill = factor(x1))) + geom_bar()</pre> |
| Count with groups, stacked | <pre>ggplot(df, aes(x = factor(x1), fill = factor(x2))) + geom_bar()</pre> |
| Count with groups, side by side | <pre>ggplot(df, aes(x = factor(x1), fill = factor(x2))) + geom_bar(position = position_dodge())</pre> |
| Count with groups, stacked in % | <pre>ggplot(df, aes(x = factor(x1), fill = factor(x2))) + geom_bar(position = "fill")</pre> |
| Values (summary statistic) | <pre>ggplot(df, aes(x = factor(x1), y = x2)) + geom_bar(stat = "identity")</pre> |
| Histogram of a continuous variable | <pre>ggplot(df, aes(x = x1)) + geom_histogram(bins = 30)</pre> |

## FAQs

📊 When should you use a histogram instead of a bar chart?

Use a histogram when the x-axis variable is continuous and you want to see its distribution. Use a bar chart when the x-axis holds distinct categories and you want to compare them.

🎨 Why does fill behave differently inside and outside aes()?

Inside aes() fill maps a variable to colour, so each group gets its own shade. Outside aes(), inside geom\_bar(), fill is a fixed value applied to every bar.

🔢 How many bins should a histogram have?

There is no universal answer. Start with the square root of the observation count, then adjust. Too few bins hide structure such as a second peak, and too many produce a noisy, spiky chart.

🤖 How do AI workflows use bar charts and histograms?

Histograms are the standard first step in exploratory data analysis for AI projects, revealing skew, outliers, and class imbalance before any model is trained. Bar charts then summarise feature importance and category frequencies.

🧠 Can AI assistants generate ggplot2 code from a description?

Yes. AI assistants can draft ggplot2 layers from a plain description of the chart and explain errors such as a missing stat argument. Always run the generated code on your own data to confirm the mapping is right.

#### Summarize this post with:

ChatGPTPerplexityGrokGoogle AI

**Stay Updated on AI** **Get Weekly AI Skills, Trends, Actionable Advice.**

##### Sign up for the newsletter

Subscribe for Free

You have successfully subscribed.  
Please check your inbox.

![AI-Newsletter]() Chosen by over **350,000+** professionals

[Scroll to top](#wrapper)

×

Search for:

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://www.guru99.com/#organization","name":"Guru99","sameAs":["https://www.facebook.com/Guru99Official","https://twitter.com/guru99com"],"logo":{"@type":"ImageObject","@id":"https://www.guru99.com/#logo","url":"https://www.guru99.com/images/guru99-logo-v1-150x59.png","contentUrl":"https://www.guru99.com/images/guru99-logo-v1-150x59.png","caption":"Guru99","inLanguage":"en-US"}},{"@type":"WebSite","@id":"https://www.guru99.com/#website","url":"https://www.guru99.com","name":"Guru99","publisher":{"@id":"https://www.guru99.com/#organization"},"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https://www.guru99.com/images/bar-chart-histogram-in-r.png","url":"https://www.guru99.com/images/bar-chart-histogram-in-r.png","width":"700","height":"250","caption":"Bar Chart &amp; Histogram in R","inLanguage":"en-US"},{"@type":"BreadcrumbList","@id":"https://www.guru99.com/r-bar-chart-histogram.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":"1","item":{"@id":"https://www.guru99.com","name":"Home"}},{"@type":"ListItem","position":"2","item":{"@id":"https://www.guru99.com/r-programming","name":"R Programming"}},{"@type":"ListItem","position":"3","item":{"@id":"https://www.guru99.com/r-bar-chart-histogram.html","name":"Bar Chart &#038; Histogram in R with Example"}}]},{"@type":"WebPage","@id":"https://www.guru99.com/r-bar-chart-histogram.html#webpage","url":"https://www.guru99.com/r-bar-chart-histogram.html","name":"Bar Chart &#038; Histogram in R with Example","dateModified":"2026-10-10T15:57:09+05:30","isPartOf":{"@id":"https://www.guru99.com/#website"},"primaryImageOfPage":{"@id":"https://www.guru99.com/images/bar-chart-histogram-in-r.png"},"inLanguage":"en-US","breadcrumb":{"@id":"https://www.guru99.com/r-bar-chart-histogram.html#breadcrumb"}},{"@type":"Person","@id":"https://www.guru99.com/author/editorial","name":"Editorial Team","url":"https://www.guru99.com/author/editorial","image":{"@type":"ImageObject","@id":"https://www.guru99.com/images/favicon-new-logo.png","url":"https://www.guru99.com/images/favicon-new-logo.png","caption":"Editorial Team","inLanguage":"en-US"},"sameAs":["https://www.guru99.com/editorial-team"],"worksFor":{"@id":"https://www.guru99.com/#organization"}},{"articleSection":"R Programming","headline":"Bar Chart &#038; Histogram in R with Example","description":"A bar chart is a great way to display categorical variables in the x-axis. This type of graph denotes two aspects in the y-axis. The first one counts the number of occurrence between groups.The second","keywords":"R, Programming","speakable":{"@type":"SpeakableSpecification","cssSelector":[".entry-title",".summary"]},"@type":"Article","author":{"@id":"https://www.guru99.com/author/editorial","name":"Editorial Team"},"dateModified":"2026-10-10T15:57:09+05:30","image":{"@id":"https://www.guru99.com/images/bar-chart-histogram-in-r.png"},"copyrightYear":"2026","name":"Bar Chart &#038; Histogram in R with Example","subjectOf":[{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"When should you use a histogram instead of a bar chart?","acceptedAnswer":{"@type":"Answer","text":"Use a histogram when the x-axis variable is continuous and you want to see its distribution. Use a bar chart when the x-axis holds distinct categories and you want to compare them."}},{"@type":"Question","name":"Why does fill behave differently inside and outside aes()?","acceptedAnswer":{"@type":"Answer","text":"Inside aes() fill maps a variable to colour, so each group gets its own shade. Outside aes(), inside geom_bar(), fill is a fixed value applied to every bar."}},{"@type":"Question","name":"How many bins should a histogram have?","acceptedAnswer":{"@type":"Answer","text":"There is no universal answer. Start with the square root of the observation count, then adjust. Too few bins hide structure such as a second peak, and too many produce a noisy, spiky chart."}},{"@type":"Question","name":"How do AI workflows use bar charts and histograms?","acceptedAnswer":{"@type":"Answer","text":"Histograms are the standard first step in exploratory data analysis for AI projects, revealing skew, outliers, and class imbalance before any model is trained. Bar charts then summarise feature importance and category frequencies."}},{"@type":"Question","name":"Can AI assistants generate ggplot2 code from a description?","acceptedAnswer":{"@type":"Answer","text":"Yes. AI assistants can draft ggplot2 layers from a plain description of the chart and explain errors such as a missing stat argument. Always run the generated code on your own data to confirm the mapping is right."}}]}],"@id":"https://www.guru99.com/r-bar-chart-histogram.html#schema-1152155","isPartOf":{"@id":"https://www.guru99.com/r-bar-chart-histogram.html#webpage"},"publisher":{"@id":"https://www.guru99.com/#organization"},"inLanguage":"en-US","mainEntityOfPage":{"@id":"https://www.guru99.com/r-bar-chart-histogram.html#webpage"}}]}
```
