Create Histograms & Box Plots
Learn to create histograms and box plots in Python with this hands-on tutorial from the Data Science with Python track. Step-by-step instructions, troubleshooting tips, and comparisons to help you visualize data distributions effectively.
Focus: create histograms and box plots
You've got a DataFrame with thousands of rows, and you're drowning in numbers. You know there's a story in there — maybe a skewed distribution, a cluster of outliers, or a surprising gap — but the raw values refuse to tell it. This is exactly where histograms and box plots come to the rescue: they turn an overwhelming wall of numbers into a picture you can read in seconds. In this lesson, you'll learn to create both charts with Python's data visualization libraries, understand what they reveal, and know when each one is the right tool for the job — a crucial step for every exploratory data analysis in your Data Science with Python journey.
The problem this lesson solves
Raw numbers are terrible at telling stories. Open a DataFrame with 10,000 rows — you'll see values, but you won't see the shape of your data. Are most customers spending close to the average, or is there a tiny group of power users skewing everything? Are your test scores roughly symmetric, or is there a long tail of failing grades? These questions are impossible to answer by staring at rows of printed output.
The real pain: you can't make good decisions based on data you don't understand. Summary statistics like mean and std give you a single snapshot, but they hide the distribution — how values are spread across the range. A dataset with two clusters (say, a product used by both hobbyists and professionals) can have the same mean as a perfectly uniform one. You need a visual to see that.
Histograms and box plots are two of the most fundamental exploratory data analysis (EDA) tools for exactly this reason. They reveal distribution shape, spread, central tendency, and outliers at a glance. Without them, you're flying blind.
Core concept / mental model
Think of your dataset as a crowd of people standing on a number line. Each person stands at the value of their data point — a salary, an age, a test score. Now, step back and look:
- A histogram is like a photo of the crowd. It divides the number line into bins (segments) and counts how many people stand in each. The result is a bar chart showing the overall shape — where the crowd is dense, where it's sparse, where it's empty.
- A box plot is like a temperature gauge for the crowd. It compresses the whole scene into a single box: the median (the middle person), the interquartile range (the middle 50% of people), and the whiskers (the typical range). Any points beyond the whiskers are marked as outliers — the people who wandered far from the rest.
Another way to see it: a histogram gives you the full picture with all its glorious detail, while a box plot gives you a condensed summary — a rugged, no-frills version that's easy to compare across categories.
Both are built on the same underlying idea: understanding your data's distribution — how values spread from the minimum to the maximum, where they cluster, and where they break away.
How it works step by step
Creating both charts is a systematic process. Here's the logic:
- Load the data — you need a DataFrame (or a Series) of numeric values.
- Import a plotting library —
matplotlibandseabornare the two most common for this task. - For a histogram: choose how many bins (bars) you want. The default is often fine, but you can tweak it for more or less detail. Then call the plotting function and pass the data.
- For a box plot: you can plot a single series, or group by a categorical column to compare multiple groups side by side.
- Customize and display — add titles, labels, colors, and use
plt.show()to render the chart.
The core idea is simple: choose the right chart for the question you're asking. If you want to see the shape of one distribution, use a histogram. If you want to compare distributions across multiple categories, use a box plot.
Hands-on walkthrough
Let's get practical. You'll create both charts using matplotlib directly and also with seaborn for a nicer default style. We'll use a small synthetic dataset so you can see exactly what's happening.
First, install the required libraries if you haven't already:
pip install matplotlib seaborn pandas numpy
Example 1: Basic histogram with Matplotlib
import matplotlib.pyplot as plt
import numpy as np
# Generate synthetic data: ages of 1000 customers
np.random.seed(42)
ages = np.random.normal(loc=35, scale=10, size=1000)
# Create a histogram with 20 bins
plt.hist(ages, bins=20, edgecolor='black', alpha=0.7)
plt.title('Customer Age Distribution')
plt.xlabel('Age (years)')
plt.ylabel('Number of Customers')
plt.show()
Expected output: a bell-shaped curve centered around age 35, with most customers between 20 and 50.
💡 Pro tip: The
binsargument is the most important knob. Too few bins and you miss the shape; too many and you get noise. Start with 10–30 and adjust based on your data size.
Example 2: Histogram with Seaborn (with density curve)
Seaborn builds on Matplotlib and gives you nicer defaults plus a kernel density estimate (KDE) overlay, which is a smoothed curve showing the likely probability density:
import seaborn as sns
import pandas as pd
# Create a DataFrame with heights
heights = np.random.normal(loc=170, scale=7, size=500)
df = pd.DataFrame({'height': heights})
# Histogram with KDE
sns.histplot(data=df, x='height', bins=25, kde=True, color='skyblue')
plt.title('Height Distribution with KDE')
plt.xlabel('Height (cm)')
plt.ylabel('Count')
plt.show()
Expected output: a histogram with a smooth curve tracing the shape of the distribution.
Example 3: Box plot with Matplotlib (single group)
import matplotlib.pyplot as plt
# Using the same heights data
data_to_plot = [heights]
plt.boxplot(data_to_plot, vert=True, patch_artist=True)
plt.title('Box Plot of Heights')
plt.ylabel('Height (cm)')
plt.xticks([1], ['Heights'])
plt.show()
Expected output: a box plot showing the median (line in the box), the interquartile range (box edges), and whiskers extending to the most extreme points within 1.5 × IQR. Individual points beyond the whiskers appear as circles (outliers).
Example 4: Grouped box plot with Seaborn
This is where box plots shine — comparing distributions across categories:
import pandas as pd
import numpy as np
import seaborn as sns
# Create a dataset with two groups
np.random.seed(7)
group_a = np.random.normal(loc=60, scale=8, size=100)
group_b = np.random.normal(loc=75, scale=12, size=100)
df = pd.DataFrame({
'score': np.concatenate([group_a, group_b]),
'group': ['A'] * 100 + ['B'] * 100
})
# Grouped box plot
sns.boxplot(data=df, x='group', y='score')
plt.title('Scores by Group')
plt.xlabel('Group')
plt.ylabel('Score')
plt.show()
Expected output: two side-by-side boxes, with Group B showing a higher median and larger spread than Group A.
Compare options / when to choose what
Both charts are essential, but they answer different questions. Here's a quick comparison to guide your choice:
| Feature | Histogram | Box Plot |
|---|---|---|
| What it shows | Full distribution shape | Summary statistics and outliers |
| Detail level | High (every bin) | Low (five-number summary) |
| Best for | Single distribution analysis | Comparing multiple groups |
| Outliers | Hard to spot directly | Clear markers |
| Sample size | Needs enough data for stable bins | Works even with small samples |
| Applications | Checking skewness, modality, gaps | Identifying outliers, group comparisons |
When to use a histogram: * You want to see the shape — is it normal, skewed, bimodal? * You want to understand the peak and the tails. * You're exploring a single variable before modeling.
When to use a box plot: * You need to compare several groups or conditions at once. * You want a clean, compact summary for reports. * You need to highlight outliers quickly.
💡 Pro tip: A violin plot is a middle ground — it combines the box plot's summary with the histogram's shape. Seaborn offers it via
sns.violinplot(). Great when you want both in one figure.
Variations:
* Seaborn gives you histplot and boxplot — more polished and integrated with pandas.
* Matplotlib gives you plt.hist and plt.boxplot — lower-level, full control.
* Plotly for interactive charts — hover over bins or boxes for exact values.
Troubleshooting & edge cases
1. Histogram bins are empty or too cluttered
* Symptom: You see huge gaps or a flat mess.
* Fix: Adjust the bins parameter. Use bins='auto' or a manual integer. Check the data range first with df['col'].min() and .max().
2. Box plot shows only a line — no box * Why: If the data has very low variance (e.g., all values nearly the same), the box collapses to a line. * Fix: That's actually correct — it's telling you there's almost no spread. Consider the range of your data; you may need to work with more variation.
3. Outliers are overwhelming the box plot * Symptom: You see a box squished at the bottom and dozens of outlier points. * Fix: This means your data is highly skewed. You might want to log-transform it first or use a different plot (e.g., a strip plot) to better visualize the distribution.
4. Histogram y-axis is count but you wanted density
* Fix: Use density=True in plt.hist() or stat='density' in sns.histplot(). This normalizes so the total area under the bars = 1, which helps compare datasets of different sizes.
5. Seaborn says "No module named 'seaborn'"
* Fix: Run pip install seaborn in your terminal or activate the correct conda environment.
6. Categorical column for box plot has too many categories
* Fix: Filter to the top N categories, or use order to sort them logically. Too many boxes become unreadable.
What you learned & what's next
You've mastered two powerful EDA tools. Let's recap what you can now explain:
- The core idea behind histograms and box plots: visualizing the distribution of numeric data.
- How to create histograms with
plt.hist()andsns.histplot(), controlling bins and adding KDE. - How to create box plots with
plt.boxplot()andsns.boxplot(), including grouped comparisons. - When to choose each chart based on your question — shape vs. summary vs. comparison.
- How to troubleshoot common issues like binning problems, collapsed boxes, and outlier clutter.
Now you can look at any numeric column and answer: Where is the bulk of the data? Are there outliers? How different are my groups?
Your next lesson in the Data Science with Python track builds on this foundation — likely covering more advanced visualizations or statistical summaries. You'll be ready to explore scatter plots, correlation matrices, or time series plots with the same confidence. Keep your plotting toolkit growing; every chart you master brings you closer to telling compelling data stories.
💡 Pro tip: Always plot your data before running summary statistics. The numbers can lie; the shape rarely does.
Practice recap
Open a dataset you're familiar with (or use sns.load_dataset('tips')). Create a histogram of the total_bill column, then a box plot of total_bill grouped by day. What do you learn about the distribution? Try adjusting bins and adding a KDE curve. Then compare with a grouped box plot — which day shows the most variability?
Common mistakes
- Choosing too few bins in a histogram, hiding the real shape — try
bins=10tobins=50based on data size. - Using a box plot to view the full distribution — you'll miss multimodal shapes that only a histogram can reveal.
- Forgetting to call
plt.show()in non-Jupyter environments, resulting in blank output. - Plotting non-numeric columns directly — both histograms and box plots require numeric data.
Variations
- Use
sns.histplotwithkde=Trueto overlay a density curve on the histogram. - Use
sns.violinplotas a hybrid that shows both the box plot summary and the full distribution shape. - Use
plt.boxplot(..., vert=False)to draw horizontal box plots, useful when category names are long.
Real-world use cases
- Customer segmentation: plot age and spending histograms to identify distinct cohorts.
- Quality control: use a box plot of product measurements to spot outliers deviating from spec limits.
- A/B testing analysis: compare conversion rates across experiment groups with grouped box plots.
Key takeaways
- Visualizing the distribution is essential —
meanandstdcan hide multiple modes and outliers. - Histograms show the full shape of a single distribution; box plots summarize and compare groups.
- Control bins (
binsargument) to balance detail vs. noise in histograms. - Box plot whiskers use 1.5 × IQR; points beyond are outliers.
- Seaborn offers higher-level functions with better defaults than raw Matplotlib.
- Always explore your data visually before modeling.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.