DEV Community

Cover image for Matplotlib - Session 2
balaji s
balaji s

Posted on

Matplotlib - Session 2

Turning Data Into Decisions

Bar charts, histograms, scatter plots, subplots, and plotting straight from pandas


Previously learned to draw a line — literally. we now know how to create a figure, style it, and save it. But real analyst work rarely stops at trends over time. You'll need to compare categories, understand distributions, spot relationships between variables, and show several views of the data at once. That's exactly what today covers.

Grab a coffee — let's turn raw numbers into charts that actually tell a story.


1. Bar Charts: Comparing Categories

When to use one

Bar charts are your go-to whenever you're comparing discrete categories against each other — regions, products, departments, months. If someone asks "which one is bigger?", a bar chart answers it instantly.

The code

import matplotlib.pyplot as plt

regions = ["North", "South", "East", "West"]
revenue = [420, 380, 510, 290]

fig, ax = plt.subplots(figsize=(7, 5))
ax.bar(regions, revenue, color="teal")

ax.set_title("Revenue by Region")
ax.set_xlabel("Region")
ax.set_ylabel("Revenue ($K)")

plt.show()
Enter fullscreen mode Exit fullscreen mode

A useful variant: horizontal bars

When category names are long, flip the chart with barh() — it's far easier to read than squeezing labels sideways:

fig, ax = plt.subplots(figsize=(7, 5))
ax.barh(regions, revenue, color="darkorange")
ax.set_title("Revenue by Region")
ax.set_xlabel("Revenue ($K)")
plt.show()
Enter fullscreen mode Exit fullscreen mode

Rule of thumb: categories on the x-axis → bar(). Long labels or many categories → barh().


2. Histograms: Understanding Distributions

Bar chart vs. histogram — don't mix them up

This trips up almost every beginner: a bar chart compares separate categories. A histogram shows how continuous numeric data is distributed by grouping values into ranges called bins. There are no gaps between histogram bars by convention, because the x-axis is continuous, not categorical.

The code

import matplotlib.pyplot as plt

ages = [22, 25, 25, 28, 30, 31, 31, 31, 35, 36, 38, 40, 42, 45, 45, 48, 50, 52, 55, 60]

fig, ax = plt.subplots(figsize=(7, 5))
ax.hist(ages, bins=6, color="steelblue", edgecolor="black")

ax.set_title("Customer Age Distribution")
ax.set_xlabel("Age")
ax.set_ylabel("Number of Customers")

plt.show()
Enter fullscreen mode Exit fullscreen mode

Why bins matters

Too few bins hides detail; too many creates noise. bins=6 groups your 20 data points into 6 age ranges. Try changing it to bins=3 and bins=15 and watch the story the chart tells actually change — this is a great instinct to build early.

Use case: salary bands, order sizes, response times, test scores — anywhere you want to see the shape of the data (skewed? normal? clustered?).


3. Scatter Plots: Spotting Relationships

When to use one

Scatter plots answer "does X affect Y?" — like advertising spend vs. sales, or hours studied vs. exam score. Each point is one observation with two numeric values.

The code

import matplotlib.pyplot as plt

ad_spend = [10, 15, 20, 25, 30, 35, 40, 45]
sales = [22, 25, 33, 38, 44, 50, 58, 63]

fig, ax = plt.subplots(figsize=(7, 5))
ax.scatter(ad_spend, sales, color="crimson")

ax.set_title("Ad Spend vs Sales")
ax.set_xlabel("Ad Spend ($K)")
ax.set_ylabel("Sales ($K)")

plt.show()
Enter fullscreen mode Exit fullscreen mode

Bonus: a third dimension with size or color

Scatter plots can secretly show a third variable by varying marker size (s=) or color (c=):

customer_count = [5, 8, 12, 15, 18, 22, 27, 30]

fig, ax = plt.subplots(figsize=(7, 5))
scatter = ax.scatter(ad_spend, sales, s=[c*10 for c in customer_count],
                      c=customer_count, cmap="viridis")
ax.set_title("Ad Spend vs Sales (bubble size = customers)")
ax.set_xlabel("Ad Spend ($K)")
ax.set_ylabel("Sales ($K)")
plt.colorbar(scatter, label="Customer Count")
plt.show()
Enter fullscreen mode Exit fullscreen mode

This is called a bubble chart — a nice trick to have once you're comfortable with the basics.


4. Subplots: Multiple Charts, One Figure

Why you need this

Reports rarely show just one chart. Subplots let you lay out several plots in a grid inside a single figure — perfect for dashboards or side-by-side comparisons.

The code

import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(12, 5))   # 1 row, 2 columns

# Left chart
axes[0].bar(regions, revenue, color="teal")
axes[0].set_title("Revenue by Region")

# Right chart
axes[1].hist(ages, bins=6, color="steelblue", edgecolor="black")
axes[1].set_title("Customer Age Distribution")

plt.tight_layout()
plt.show()
Enter fullscreen mode Exit fullscreen mode

The pattern to remember

plt.subplots(rows, cols) gives you back an array of axesaxes[0], axes[1], etc. (or axes[0][0], axes[0][1]... for a 2D grid). Each one behaves exactly like the single ax you've been using — just call .bar(), .hist(), .scatter() on whichever one you want.

plt.tight_layout() is a small habit worth building now — it auto-adjusts spacing so titles and labels don't overlap.


5. Plotting Directly from a Pandas DataFrame

The analyst's real workflow

In practice, you're rarely typing out lists by hand — your data lives in a DataFrame. Pandas has a built-in .plot() method that calls Matplotlib for you, so you can skip a lot of boilerplate.

The code

import pandas as pd
import matplotlib.pyplot as plt

data = {
    "Month": ["Jan", "Feb", "Mar", "Apr", "May"],
    "Revenue": [45, 50, 47, 53, 60],
    "Expenses": [30, 32, 31, 35, 38]
}
df = pd.DataFrame(data)

# Quick line plot straight from the DataFrame
df.plot(x="Month", y=["Revenue", "Expenses"], kind="line",
        figsize=(8, 5), title="Revenue vs Expenses")
plt.ylabel("Amount ($K)")
plt.show()
Enter fullscreen mode Exit fullscreen mode

Other kind values worth knowing

df.plot(x="Month", y="Revenue", kind="bar", figsize=(8, 5), color="seagreen")
plt.show()
Enter fullscreen mode Exit fullscreen mode

kind accepts "line", "bar", "barh", "hist", "scatter", and more — one method, most of the charts you already learned today.

Key insight: df.plot() still returns a Matplotlib Axes object under the hood, which is why plt.ylabel(), plt.title(), etc. still work on it afterward. Everything you learned on Day 1 still applies.


6. Hands-On: From CSV to Chart

Here's a realistic mini-workflow — read tabular data and produce a combo chart:

import pandas as pd
import matplotlib.pyplot as plt

# In real use: df = pd.read_csv("sales_data.csv")
# Simulating that CSV here for practice:
data = {
    "Month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
    "Units_Sold": [120, 135, 128, 150, 170, 165],
    "Revenue": [45, 50, 47, 53, 60, 58]
}
df = pd.DataFrame(data)

fig, ax1 = plt.subplots(figsize=(9, 5))

# Bar chart: units sold
ax1.bar(df["Month"], df["Units_Sold"], color="lightsteelblue", label="Units Sold")
ax1.set_xlabel("Month")
ax1.set_ylabel("Units Sold")

# Line chart: revenue, on a second y-axis
ax2 = ax1.twinx()
ax2.plot(df["Month"], df["Revenue"], color="darkred", marker="o", label="Revenue ($K)")
ax2.set_ylabel("Revenue ($K)")

fig.suptitle("Units Sold vs Revenue")
plt.savefig("units_vs_revenue.png", dpi=300, bbox_inches="tight")
plt.show()
Enter fullscreen mode Exit fullscreen mode

ax1.twinx() is the trick here — it creates a second y-axis sharing the same x-axis, so you can combine a bar chart and line chart with different scales in one clean visual. This is a genuinely common real-world pattern (think "volume vs. price" charts).


Wrapping Up

In we've gone from a single line plot to:

  • Comparing categories with bar charts
  • Understanding data spread with histograms
  • Spotting relationships with scatter plots
  • Building dashboards with subplots
  • Working the way real analysts do, straight from a pandas DataFrame

Where to go from here

Matplotlib is the foundation — but once it feels natural, two libraries are worth exploring next:

  • Seaborn — built on Matplotlib, gives you polished statistical charts (correlation heatmaps, box plots) with less code
  • Plotly — for interactive, hover-able charts, especially useful for dashboards and presentations

But don't rush there. Everything in Seaborn and Plotly still assumes you understand the figure/axes fundamentals you now have. That foundation is the real win from these two days.

Top comments (0)