📊 Section 3 · Data Viz 🟡 Intermediate MODULE 15

Seaborn — Statistical Visualization

⏱️ 27 min read
📖 Theory + Code
🧩 5 Quiz Questions
🏗️ 1 Challenge
Your progress in Section 340%
🎯 What you'll learn: Seaborn is built directly on top of Matplotlib — every chart it draws is still a Matplotlib figure underneath — but it ships with nicer defaults and, more importantly, works natively with pandas DataFrames: you point it at column names instead of manually pulling out arrays. You'll build a distribution chart with sns.histplot(), compare groups with sns.boxplot(), color points by category with sns.scatterplot()'s hue, visualize a correlation matrix with sns.heatmap(), and get every pairwise relationship at once with sns.pairplot().

Why Seaborn?

Matplotlib gives you total control, but that control comes at a cost — every color, gridline, and axis label is something you set by hand. Seaborn wraps Matplotlib with sensible statistical defaults and a data= argument that takes a DataFrame directly, so most calls look like sns.something(data=df, x="col_a", y="col_b") instead of manually slicing out NumPy arrays first.

🎨
Nicer defaults
Sensible colors, gridlines and spacing out of the box
🐼
DataFrame-native
Pass column names as strings — no manual array extraction
📐
Built on Matplotlib
Every sns chart is still a Matplotlib Figure/Axes underneath
setup.py
PYTHON
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

sns.set_theme(style="darkgrid")  # applies Seaborn's styling to every chart from here on

df = pd.DataFrame({
    "product": ["Laptop", "Mouse", "Monitor", "Keyboard", "Laptop", "Mouse", "Monitor", "Keyboard"],
    "price": [1200, 45, 890, 65, 1150, 40, 910, 70],
    "rating": [4.5, 4.0, 4.2, 3.8, 4.6, 4.1, 4.3, 3.9],
    "region": ["West", "West", "East", "South", "East", "North", "West", "East"],
})
📝
Seaborn functions still take Matplotlib arguments
Every Seaborn plotting function returns an Axes object (or a whole grid, for figure-level functions like pairplot), so plt.show(), ax.set_title(), and everything else from the Matplotlib lesson still works exactly the same way here.

sns.histplot() — Distributions

sns.histplot() is Seaborn's version of a histogram, with an optional smoothed density curve (a KDE — kernel density estimate) layered on top to make the overall shape of the distribution easier to see.

histplot.py
PYTHON
sns.histplot(data=df, x="price", bins=6, kde=True, color="#4f9eff")
plt.title("Distribution of Product Prices")
plt.show()
kde=True adds a smoothed curve
The raw histogram bars can look choppy with a small dataset. The KDE line traces an estimated smooth curve over the same distribution, which is often easier to describe in one sentence — "prices cluster around two price bands" — than a jagged bar chart.

sns.boxplot() — Comparing Groups

A box plot summarizes a numeric column's spread — median, quartiles, and outliers — for each category in another column, all side by side. It's the fast way to compare distributions across groups instead of just their averages.

boxplot.py
PYTHON
sns.boxplot(data=df, x="region", y="price", hue="region", legend=False)
plt.title("Price Spread by Region")
plt.show()
📝
Reading a box plot
The box spans the interquartile range (25th to 75th percentile), the line inside it marks the median, the "whiskers" extend to the typical range of the data, and individual points beyond the whiskers are flagged as potential outliers. A tall box means that group's values are spread wide; a short box means they're tightly clustered.

sns.scatterplot() with hue

sns.scatterplot() works like Matplotlib's scatter, but the hue parameter automatically colors each point by a categorical column and adds a matching legend — no manual color-mapping loop required.

scatterplot_hue.py
PYTHON
sns.scatterplot(data=df, x="price", y="rating", hue="region", s=100)
plt.title("Price vs. Rating, by Region")
plt.show()
🖼️ What plt.show() displays
Eight points scattered across the chart, each colored by its region — West points in one color, East in another, and so on — with a legend on the side mapping each color back to a region name, generated automatically from the unique values in the "region" column.
hue also works on histplot and boxplot
hue isn't unique to scatterplot — sns.histplot(data=df, x="price", hue="region") overlays a separate distribution per region, and sns.boxplot(..., hue="region") further splits each x-axis category by region. It's one of the most-used arguments in the whole library.

sns.heatmap() — Correlation Matrices

A correlation matrix, produced by pandas' .corr(), is itself just a grid of numbers between -1 and 1 — hard to scan as a table once you have more than a few columns. sns.heatmap() colors that grid, so strong positive or negative relationships jump out visually.

heatmap.py
PYTHON
numeric_df = df[["price", "rating"]]
corr = numeric_df.corr()

print(corr)
#            price    rating
# price    1.000000  0.968... 
# rating   0.968...  1.000000

sns.heatmap(corr, annot=True, cmap="coolwarm", vmin=-1, vmax=1)
plt.title("Correlation Matrix")
plt.show()
⚠️
.corr() only works on numeric columns
Pandas' .corr() silently ignores non-numeric columns like product or region — it's why numeric_df is sliced down to just price and rating first. Passing a mixed-type DataFrame straight into .corr() without selecting numeric columns can raise an error or drop columns unexpectedly depending on the pandas version, so it's best to select the numeric columns explicitly before calling it.
📝
annot, cmap, vmin/vmax
annot=True prints each correlation value directly on its cell. cmap="coolwarm" picks a diverging color scale — blue for negative, red for positive. vmin=-1, vmax=1 pins the color scale to correlation's actual range, so a heatmap of a mostly-weak-correlation dataset isn't misleadingly stretched to look strong.

sns.pairplot() — Every Relationship at Once

sns.pairplot() builds a grid of scatter plots for every pair of numeric columns in a DataFrame, with a histogram (or KDE) on the diagonal for each column against itself — a fast way to eyeball every relationship in a dataset in one call, without writing a chart for each pair by hand.

pairplot.py
PYTHON
sns.pairplot(df, hue="region", vars=["price", "rating"])
plt.show()
📝
pairplot returns a whole grid, not one Axes
pairplot() is a "figure-level" function — it returns a PairGrid object managing multiple subplots at once, unlike the "axes-level" functions earlier in this lesson (histplot, boxplot, scatterplot, heatmap), which each draw into a single Axes and can be placed inside a Matplotlib subplot grid alongside other charts.

Lesson Summary

Let's recap everything you learned in this lesson:

Seaborn is built on Matplotlib — it adds statistical defaults and native DataFrame support via data=.
sns.histplot() shows a distribution, optionally with a smoothed kde=True curve.
sns.boxplot() compares a numeric column's spread across categories.
hue= colors points/bars/boxes by a category, with an automatic legend.
sns.heatmap() visualizes a correlation matrix from .corr().
sns.pairplot() plots every numeric pair at once, in a single call.
🧩 Knowledge Check — Lesson 15
Answer all 5 questions to test your understanding. Instant feedback on every answer.
1. What is Seaborn built on top of?
2. Which function shows a distribution, with an optional smoothed density curve via kde=True?
3. Which parameter colors points or bars by a categorical column, adding an automatic legend?
4. What does sns.heatmap() most commonly visualize?
5. What does sns.pairplot(df, vars=["price", "rating"]) produce?
💪
Coding Challenge — Lesson 15
Apply what you learned · Intermediate Level

Build a small statistical report on the df from Section 1.

Challenge: Product Price Report 📊

Using the df from Section 1 (product, price, rating, region), write code that: (1) draws a sns.boxplot() of price grouped by region, (2) draws a sns.scatterplot() of price vs. rating with hue="region", and (3) computes df[["price", "rating"]].corr() and visualizes it with sns.heatmap(annot=True).

Rules: Call plt.show() after each chart, and give each one a plt.title() describing what it shows.
💡 Show hints if you're stuck
  • Step 1: sns.boxplot(data=df, x="region", y="price")
  • Step 2: sns.scatterplot(data=df, x="price", y="rating", hue="region")
  • Step 3: sns.heatmap(df[["price", "rating"]].corr(), annot=True, cmap="coolwarm")
Finished this lesson?
Mark it complete to track your progress.
🎉

Lesson 15 Complete!

You can build distribution, comparison, relationship, and correlation charts with Seaborn, straight from a DataFrame. Next up: Plotly — turning charts into interactive, web-ready visualizations.

Module 15 of 18 Section 3 — Data Visualization: Matplotlib & Seaborn