How To Draw A Histogram In R

6 min read

Creating a histogram in R is a fundamental skill for anyone who works with data, whether you are a student exploring descriptive statistics or a professional building reports for stakeholders. A histogram visualizes the distribution of a continuous variable by grouping values into bins and displaying the frequency—or density—of observations in each bin. Also, mastering how to draw a histogram in r enables you to quickly spot patterns such as skewness, modality, and outliers, which are essential steps before diving into more complex analyses. In this guide we will walk through the process using both base R graphics and the popular ggplot2 package, show you how to customize appearance, add density curves, facet by groups, and export your plots for sharing or publication.

People argue about this. Here's where I land on it.

Preparing Your Data

Before you can plot anything, you need a numeric vector or a column inside a data frame. For demonstration we will use the built‑in mtcars dataset, focusing on the horsepower variable (hp). If you have your own data, simply replace mtcars$hp with your variable name Less friction, more output..

# Load the dataset (already available in base R)
data(mtcars)

# Inspect the first few rows
head(mtcars)

Make sure the variable is truly numeric; if it is stored as a factor or character, convert it with as.numeric():

mtcars$hp <- as.numeric(mtcars$hp)

Basic Histogram with Base R

The simplest way to create a histogram in R is to call the hist() function. This function automatically determines a reasonable number of bins using Sturges’ rule, but you can override that choice Turns out it matters..

# Basic histogram
hist(mtcars$hp,
     main = "Histogram of Horsepower",
     xlab = "Horsepower (hp)",
     ylab = "Frequency",
     col = "steelblue",
     border = "white")

Key arguments explained

Argument Purpose
main Title of the plot
xlab Label for the x‑axis
ylab Label for the y‑axis (frequency by default)
col Fill color of the bars
border Color of the bar edges
breaks Number of bins or a vector of cut points (optional)

If you prefer to specify the bin width directly, you can supply a sequence to breaks:

hist(mtcars$hp,
     breaks = seq(0, 350, by = 25),   # bins of width 25 hp
     col = "tomato",
     main = "Histogram with Custom Bin Width")

Using ggplot2 for More Flexibility

While base R graphics are quick and sufficient for exploratory work, ggplot2 offers a layered grammar of graphics that makes customization, faceting, and saving plots more intuitive. First, install and load the package if you haven’t already Took long enough..

install.packages("ggplot2")   # run once
library(ggplot2)

A basic histogram with ggplot2 looks like this:

ggplot(mtcars, aes(x = hp)) +
  geom_histogram(binwidth = 25,          # width of each bin
                 fill = "darkgreen",
                 color = "black") +
  labs(title = "Histogram of Horsepower",
       x = "Horsepower (hp)",
       y = "Count") +
  theme_minimal()

Why choose ggplot2?

  • Layered syntax: you can add geoms, stats, and themes sequentially.
  • Consistent aesthetics: colors, fonts, and themes are easy to modify globally.
  • Faceting: split histograms by categorical variables with facet_wrap() or facet_grid().

Customizing Appearance

Both systems allow extensive tweaking. Below are common customizations you might want.

Changing Bin Number or Width

  • Base R: adjust the breaks argument.
  • ggplot2: set binwidth in geom_histogram() or use bins = 30 to approximate a number of bins.

Adding a Density Curve

Overlaying a density estimate helps you see the shape of the distribution relative to a smooth curve.

Base R

hist(mtcars$hp,
     probability = TRUE,   # scale y‑axis to density
     col = "lightgray",
     border = "white",
     main = "Histogram with Density Curve",
     xlab = "Horsepower (hp)")
lines(density(mtcars$hp),
      col = "red",
      lwd = 2)

ggplot2

ggplot(mtcars, aes(x = hp)) +
  geom_histogram(aes(y = ..density..),
                 binwidth = 25,
                 fill = "lightblue",
                 color = "black") +
  geom_density(color = "red", size = 1.2) +
  labs(title = "Histogram with Density Overlay",
       x = "Horsepower (hp)",
       y = "Density") +
  theme_classic()

Changing Colors and Themes

  • Base R: use col, border, and bg parameters; for more sophisticated palettes, consider the RColorBrewer package.
  • ggplot2: swap theme_minimal() for theme_bw(), theme_classic(), or any custom theme; modify fill with scale_fill_manual() or scale_fill_brewer().

Adding Facets

If you want to compare horsepower distributions across the number of cylinders (cyl), faceting is the way to go.

ggplot(mtcars, aes(x = hp)) +
  geom_histogram(binwidth = 20,
                 fill = "purple",
                 color = "white") +
  facet_wrap(~ cyl, ncol = 3) +
  labs(title = "Horsepower Distribution by Cylinder Count",
       x = "Horsepower (hp)",
       y = "Count") +
  theme_strip()

Each panel now shows a histogram for 4‑, 6‑, and 8‑cylinder cars, making it easy to spot that higher‑cylinder engines tend to have greater horsepower.

Saving Your Plot

Once you are satisfied with the visualization, export it to a file format suitable for reports or presentations The details matter here..

Base R

png("hp_histogram.png", width = 800, height = 600, res = 150)
hist(mtcars$hp,
     breaks = 15,
     col = "gold",
     border = "black",
     main = "Saved Histogram")
dev.off()

ggplot2 (recommended for vector quality)

ggsave("hp_histogram_ggplot.pdf",
       plot = last_plot

## Interactive Histograms

While static plots are excellent for reports and publications, interactive versions can greatly enhance exploration, especially when dealing with complex datasets. The `plotly` package bridges the gap between `ggplot2` and web-based interactivity with a single line of code.

```r
library(plotly)
p <- ggplot(mtcars, aes(x = hp, fill = factor(cyl))) +
  geom_histogram(binwidth = 20, color = "white", alpha = 0.8) +
  labs(title = "Interactive Horsepower Distribution by Cylinders",
       x = "Horsepower (hp)", y = "Count") +
  theme_minimal()

ggplotly(p)

This converts your ggplot2 object into an interactive widget where you can:

  • Hover over bars to see exact counts and bin ranges. Think about it: - Toggle visibility of cylinder groups with a click. - Zoom and pan to focus on specific horsepower regions.

For base R histograms, you can use plotly directly, though the syntax is slightly different:

plotly_hist <- plotly::plot_ly(data = mtcars, x = ~hp, type = "histogram",
                               color = ~factor(cyl), nbinsx = 20)

Choosing the Right Number of Bins

One of the most critical decisions in histogram design is selecting the bin width, as it directly influences the interpretation of your data's distribution Worth keeping that in mind..

  • Too few bins: Can oversimplify the data, hiding important features like bimodality or outliers.
  • Too many bins: May create a noisy, jagged appearance that obscures the underlying pattern.

As a rule of thumb:

  • Use bins = 30 for most datasets as a balanced starting point.
  • For small datasets (n < 100), consider bins = 10-15 to avoid excessive sparsity.
  • For large datasets (n > 1000), bins = 50-100 can reveal finer details.

You can also use algorithms like the Freedman-Diaconis rule (default in ggplot2), which calculates bin width based on the interquartile range (IQR), or Sturges' rule, which scales with the logarithm of sample size. In ggplot2, these are automatically applied unless you specify a manual binwidth Small thing, real impact. That's the whole idea..

Conclusion

Histograms remain one of the most fundamental and effective tools for visualizing the distribution of continuous data. Whether you opt for the simplicity and control of base R graphics or the elegance and extensibility of ggplot2, both systems provide solid mechanisms for creating informative visualizations. By mastering bin selection, aesthetic customization, faceting, and even interactivity, you can tailor histograms to reveal insights that might otherwise remain hidden in raw numbers. The key is to experiment—adjust bin widths, overlay density curves, and compare subgroups—to ensure your final plot accurately and clearly communicates the story within your data.

Just Went Live

The Latest

Curated Picks

Related Posts

Thank you for reading about How To Draw A Histogram In R. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home