Build Bar & Pie Charts
Learn how to build bar charts and pie charts in Python for data science. Step-by-step tutorial with hands-on exercises.
Focus: build bar charts and pie charts
You’ve cleaned your data, grouped it, and summarized it — but when you present your findings to stakeholders, all you get back is a blank stare. Raw numbers in a table rarely tell a story. That’s the pain this lesson solves: turning tidy data into bar charts and pie charts that make trends and proportions instantly obvious. By the end, you’ll be able to build bar charts and pie charts in Python with Matplotlib, tweak them for clarity, and choose the right chart for the story your data is telling — no design degree required.
The problem this lesson solves
Spreadsheets and DataFrames are great for computation, but humans are visual creatures. A table of sales by region might contain a clear insight — “the West region dominates” — but your audience won’t see it until you draw a picture. This lesson tackles the exact pain of communicating data insights through two of the most common chart types: bar charts for comparing categories and pie charts for showing parts of a whole.
Without these skills, you’ll find yourself copying numbers into a slides deck or explaining trends in prose — slow, error-prone, and unconvincing. Worse, you might try to eyeball a chart from a screenshot or use a spreadsheet tool, breaking your Python workflow. This lesson gives you a direct path from pandas DataFrame to publication-ready chart in a few lines of code.
Core concept / mental model
Think of a bar chart as a comparing machine: each bar’s height encodes a value, so your eye can instantly judge which category is bigger. A pie chart is a sharing machine: each slice’s area encodes a proportion, so you see how the whole splits into parts.
| Concept | Mental model | Best for |
|---|---|---|
| Bar chart | Comparing categories | Rankings, differences, trends over time |
| Pie chart | Parts of a whole | Proportions, percentages, composition |
In Matplotlib, both charts are built from the same canvas: a Figure holding one or more Axes. You call a single method — bar() or pie() — and then layer on labels, titles, and styling. The mental model is simple: data → Figure → Axes → plot method → labels → show/save.
How it works step by step
1. Set up the data
Every chart starts with clean, structured data. For a bar chart, you need categories and numeric values. For a pie chart, you need slice labels and numeric sizes. This often comes from a DataFrame using groupby() or value_counts().
2. Create the figure and axes
Matplotlib’s plt.subplots() gives you a canvas and a plotting area. Always use it — it’s the modern, explicit way to control your chart.
3. Plot the chart
Choose the right method:
- ax.bar(x, height) for vertical bars
- ax.barh(x, width) for horizontal bars
- ax.pie(sizes, labels=labels) for a pie chart
4. Add context
Titles, axis labels, and legends turn a raw chart into a message. Never skip labels — a chart without them is noise.
5. Show or save
Use plt.show() in a notebook or fig.savefig('chart.png') for reports.
The cause → effect logic: better labels → better comprehension; correct chart choice → clearer insight; consistent styling → professional presentation.
Hands-on walkthrough
Let’s build both charts from a real dataset. We’ll use a sample of sales by region and product category.
Setup
import matplotlib.pyplot as plt
import pandas as pd
# Sample data: sales by region
sales = pd.DataFrame({
'region': ['North', 'South', 'East', 'West'],
'sales': [5200, 4100, 3800, 6900]
})
print(sales)
Output:
region sales
0 North 5200
1 South 4100
2 East 3800
3 West 6900
Build a bar chart
fig, ax = plt.subplots(figsize=(8, 5))
ax.bar(sales['region'], sales['sales'], color=['#4C72B0', '#55A868', '#C44E52', '#8172B2'])
ax.set_title('Sales by Region', fontsize=16)
ax.set_xlabel('Region')
ax.set_ylabel('Sales (USD)')
ax.grid(axis='y', linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()
You should see a clean bar chart with four colored bars, a title, and labeled axes. The West region clearly stands out.
Build a pie chart
fig, ax = plt.subplots(figsize=(7, 7))
sizes = sales['sales']
labels = sales['region']
ax.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90, colors=['#4C72B0', '#55A868', '#C44E52', '#8172B2'])
ax.set_title('Sales Distribution by Region', fontsize=16)
plt.show()
Output: a pie chart with percentage labels on each slice, starting from the top (90°) and going clockwise.
Add data labels to bar charts
fig, ax = plt.subplots(figsize=(8, 5))
bars = ax.bar(sales['region'], sales['sales'])
ax.bar_label(bars, fmt='${:,.0f}')
ax.set_title('Sales by Region with Labels')
plt.show()
ax.bar_label() adds value labels on top of each bar — a pro move that saves your audience from reading the y-axis.
Compare options / when to choose what
| Chart type | Strengths | Weaknesses | When to choose |
|---|---|---|---|
| Bar chart | Precise comparison, handles many categories, easy to label | Doesn’t show proportion of whole | Comparing values, rankings, trends |
| Pie chart | Shows parts of a whole at a glance | Hard to judge small differences, cluttered with many slices | 2–6 categories, proportions matter |
Pro tip: When in doubt, pick a bar chart. Research shows humans compare bar lengths more accurately than pie slice angles. Use a pie only when the whole-to-part story is the headline.
Variations to consider
- Horizontal bar chart (
ax.barh()) for long category names - Grouped bar chart for comparing multiple series side-by-side
- Donut chart (a pie with a hole) for a modern look and center labels
Troubleshooting & edge cases
Pie chart percentages don’t sum to 100%
This happens when your values aren’t the whole. Ensure you pass all parts, or the pie will mislead. Use autopct='%1.1f%%' — Matplotlib computes percentages internally, but only from the values you give it.
Overlapping labels
Long labels on a pie can collide. Fix by:
- Using plt.tight_layout()
- Increasing figure size
- Rotating labels with rotatelabels=True
- Switching to a bar chart if labels are too long
Bars look too thin or too thick
Adjust the width parameter in ax.bar() (default 0.8). A value like 0.6 makes bars slimmer and reduces crowding.
Negative values in bar chart
Bar charts handle negatives fine, but the baseline moves. Use ax.axhline(0, color='black', linewidth=0.8) to draw a zero line for clarity.
Pie chart with zero or negative values
Never use a pie with zero or negative values — slices vanish or mislead. Clean your data first, or switch to a bar chart.
Chinese/Unicode labels show as boxes
Set a font that supports your characters:
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
Colormap too similar
Use a distinct colormap or pass explicit colors as a list. Avoid default colors for adjacent slices that are hard to tell apart.
What you learned & what's next
You now know how to build bar charts and pie charts in Python: you’ve set up Matplotlib, plotted both chart types, added labels and titles, and styled them for clarity. You can choose between a bar and a pie based on your data story, and you’ve picked up troubleshooting skills for common issues like overlapping labels and misleading pies.
These charts are your first step into data visualization. Next up, you’ll learn how to create histograms and box plots to explore the distribution of your data — a natural follow-on that reveals spread, outliers, and shape. You’ll reuse everything you learned here: the same subplots() canvas, the same ax.set_title() pattern, and the same instinct to question whether your chart is telling the truth.
Open a notebook and practice: take a DataFrame you already have, group it by a categorical column, and build both a bar and a pie chart. Then ask yourself — which one tells the story better? That judgment, not the code, is the skill that will make you a better data scientist.
Practice recap
Grab a DataFrame from an earlier lesson (or create your own), group it by a categorical column like 'month' or 'category', and build both a bar chart and a pie chart. Play with colors, labels, and figsize — then save one as a PNG. Try switching a pie with more than 5 slices to a horizontal bar chart and notice how much easier it is to read.
Common mistakes
- Using a pie chart for more than 6 categories — slices become indistinguishable; switch to a bar chart instead.
- Forgetting to set
autopct='%1.1f%%'on a pie chart, so no percentages appear. - Not adding
plt.tight_layout()— labels and titles get cut off when saving or showing. - Passing raw values that don't sum to 100% to a pie chart — the resulting proportions misrepresent your data.
- Ignoring
ax.bar_label()and forcing readers to decode the y-axis instead of showing values directly.
Variations
- Use horizontal bar charts (
ax.barh()) when category names are long or there are many categories — they're easier to read. - Create grouped bar charts to compare two or more series side-by-side; use
ax.bar()with an offset on the x-axis. - Try a donut chart (pie with
wedgeprops=dict(width=0.5)) for a modern look or to add a center label without clutter.
Real-world use cases
- A sales dashboard showing monthly revenue by product category to quickly spot top performers.
- A survey results report using a pie chart to display the distribution of responses (e.g., 45% Yes, 55% No).
- An e-commerce quarterly review comparing customer acquisition channels with a grouped bar chart to highlight growth.
Key takeaways
- Bar charts compare discrete categories; pie charts show proportions of a whole — choose accordingly.
- Always use
plt.subplots()to create a Figure and Axes before plotting. - Add titles, axis labels, and data labels (
ax.bar_label) to make charts self-explanatory. - Pie charts work only for parts-of-a-whole data with positive values; zero or negative values break them.
- Use
plt.tight_layout()to avoid cut-off labels and ensure your chart renders cleanly. - When in doubt, prefer a bar chart over a pie for easier visual comparison.
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.