Matplotlib & Seaborn Visualization

A good chart is worth a thousand rows of data — visualization is the first step in discovering patterns.

1. What You'll Learn


2. A Real Story from a Product Manager

Bob sent the SalesPredict monthly sales report to his team — 50 rows of Excel data, and nobody could quickly tell which category was declining or which months had abnormal fluctuations. Alice's US data trends were completely different from the China data, but staring at raw numbers made it nearly impossible to spot the difference. The data was buried in spreadsheets, and the key insights were drowned out.

(2) The Visualization Solution

A single line chart instantly revealed a clear downward trend in the Electronics category during Q3; a heatmap showed that the correlation between ad spend and revenue far exceeded expectations.

PYTHON
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

# Quick visualization reveals hidden patterns
df = pd.read_csv("monthly_sales.csv")
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
df.plot(x="month", y="revenue", ax=axes[0], title="Revenue Trend")
sns.heatmap(df.corr(numeric_only=True), annot=True, ax=axes[1])
plt.tight_layout()
plt.savefig("sales_overview.png", dpi=150)

(3) The Payoff: Key Business Insights in 5 Minutes

After replacing raw tables with visualizations, Bob spotted the 15% decline in the Electronics category during Q3 within 5 minutes. He adjusted the advertising strategy in time, recovering approximately 200 thousand USD in potential losses.


3. Matplotlib Fundamentals

(1) The Figure/Axes System

Matplotlib uses a two-layer architecture: a Figure (canvas) contains one or more Axes (plotting areas).

100%
graph TB
    FIG[Figure - Canvas] --> AX1[Axes 1<br/>Subplot 1]
    FIG --> AX2[Axes 2<br/>Subplot 2]
    AX1 --> LINE[Line Chart]
    AX2 --> BAR[Bar Chart]

▶ Example: Creating a Basic Line Chart

PYTHON
import matplotlib.pyplot as plt

# Monthly revenue data (thousand USD)
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
revenue = [120, 135, 150, 142, 160, 175, 180, 190, 195, 200, 220, 250]

fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(months, revenue, marker="o", linewidth=2, color="#2196F3")
ax.set_title("Monthly Revenue Trend", fontsize=14)
ax.set_xlabel("Month")
ax.set_ylabel("Revenue (thousand USD)")
ax.grid(True, alpha=0.3)
ax.fill_between(months, revenue, alpha=0.1, color="#2196F3")

# Annotate peak
peak_idx = revenue.index(max(revenue))
ax.annotate(f"Peak: {max(revenue)}k", xy=(peak_idx, max(revenue)),
            xytext=(peak_idx-2, max(revenue)+15),
            arrowprops=dict(arrowstyle="->", color="red"))

plt.tight_layout()
plt.savefig("revenue_trend.png", dpi=150)

Output:

TEXT
# Executed successfully

(2) Common Chart Types

▶ Example: Bar Chart and Scatter Plot

PYTHON
import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# Bar chart: category revenue
categories = ["Electronics", "Clothing", "Food", "Books", "Home"]
revenue = [2500, 1450, 900, 700, 4000]
colors = ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"]

axes[0].barh(categories, revenue, color=colors)
axes[0].set_title("Revenue by Category")
axes[0].set_xlabel("Revenue (thousand USD)")

# Scatter plot: ad spend vs revenue
np.random.seed(42)
ad_spend = np.random.uniform(10, 100, 50)
sales = 50 + 0.8 * ad_spend + np.random.normal(0, 10, 50)

axes[1].scatter(ad_spend, sales, alpha=0.6, color="#2196F3", edgecolors="white")
axes[1].set_title("Ad Spend vs Revenue")
axes[1].set_xlabel("Ad Spend (thousand USD)")
axes[1].set_ylabel("Revenue (thousand USD)")

# Add trend line
z = np.polyfit(ad_spend, sales, 1)
p = np.poly1d(z)
axes[1].plot(ad_spend, p(ad_spend), "r--", alpha=0.8, linewidth=2)

plt.tight_layout()
plt.savefig("bar_scatter.png", dpi=150)

Output:

TEXT
# Executed successfully
Chart Type Best Use Case Matplotlib Function
Line chart Time trends ax.plot()
Bar chart Category comparison ax.bar() / ax.barh()
Scatter plot Two-variable relationship ax.scatter()
Pie chart Proportional distribution ax.pie()
Histogram Single-variable distribution ax.hist()

4. Seaborn Advanced Charts

Seaborn is built on top of Matplotlib, providing higher-level statistical charts and more polished default styles.

(1) Distribution Plots

▶ Example: Order Amount Distribution Analysis

PYTHON
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# Generate order amount data
rng = np.random.default_rng(42)
orders_normal = rng.normal(150, 50, 1000)
orders_normal = orders_normal[orders_normal > 0]  # Remove negatives

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# Histogram with KDE
sns.histplot(orders_normal, bins=30, kde=True, ax=axes[0], color="#2196F3")
axes[0].set_title("Order Amount Distribution")
axes[0].set_xlabel("Amount (USD)")

# Box plot by category
categories = rng.choice(["Electronics", "Clothing", "Food"], 500)
amounts = np.where(categories == "Electronics",
                   rng.normal(300, 80, 500),
                   np.where(categories == "Clothing",
                            rng.normal(120, 40, 500),
                            rng.normal(50, 20, 500)))
amounts = np.clip(amounts, 1, None)
data = {"category": categories, "amount": amounts}

sns.boxplot(data=data, x="category", y="amount", ax=axes[1], palette="Set2")
axes[1].set_title("Order Amount by Category")

plt.tight_layout()
plt.savefig("distribution.png", dpi=150)

Output:

TEXT
# Executed successfully

(2) Heatmaps

▶ Example: Feature Correlation Heatmap

PYTHON
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# Simulate SalesPredict feature correlations
np.random.seed(42)
n = 200
ad_spend = np.random.uniform(10, 100, n)
traffic = ad_spend * 1.2 + np.random.normal(0, 15, n)
conversion = traffic * 0.03 + np.random.normal(0, 0.5, n)
revenue = conversion * 150 + np.random.normal(0, 500, n)
customer_age = np.random.uniform(18, 65, n)

df = pd.DataFrame({
    "ad_spend": ad_spend,
    "traffic": traffic,
    "conversion_rate": conversion,
    "revenue": revenue,
    "customer_age": customer_age,
})

corr = df.corr()

fig, ax = plt.subplots(figsize=(8, 6))
sns.heatmap(corr, annot=True, fmt=".2f", cmap="RdBu_r",
            center=0, vmin=-1, vmax=1, ax=ax,
            square=True, linewidths=0.5)
ax.set_title("Feature Correlation Heatmap")
plt.tight_layout()
plt.savefig("correlation_heatmap.png", dpi=150)

Output:

TEXT
# Executed successfully

(3) Multi-Subplot Layouts

▶ Example: SalesPredict 4-Dimension Analysis Panel

PYTHON
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

rng = np.random.default_rng(42)
df = pd.DataFrame({
    "date": pd.date_range("2024-01-01", periods=90),
    "revenue": rng.normal(5000, 1000, 90).cumsum(),
    "category": rng.choice(["Elec", "Cloth", "Food"], 90),
    "orders": rng.integers(50, 200, 90),
})

fig, axes = plt.subplots(2, 2, figsize=(14, 10))

# (1) Revenue trend
axes[0, 0].plot(df["date"], df["revenue"], color="#2196F3")
axes[0, 0].set_title("Daily Revenue Trend")

# (2) Category distribution
cat_rev = df.groupby("category")["revenue"].sum()
axes[0, 1].pie(cat_rev, labels=cat_rev.index, autopct="%1.1f%%")

# (3) Orders distribution
sns.histplot(df["orders"], bins=20, kde=True, ax=axes[1, 0], color="#4CAF50")
axes[1, 0].set_title("Orders Distribution")

# (4) Revenue vs Orders
axes[1, 1].scatter(df["orders"], df["revenue"], alpha=0.5, c="#FF5722")
axes[1, 1].set_title("Revenue vs Orders")

plt.tight_layout()
plt.savefig("dashboard.png", dpi=150)

Output:

TEXT
# Executed successfully

5. Style Customization and Chart Selection

(1) Seaborn Themes and Color Palettes

PYTHON
import seaborn as sns

# Set global theme
sns.set_theme(style="whitegrid", palette="muted", font_scale=1.2)

# Available themes: darkgrid, whitegrid, dark, white, ticks
# Available palettes: deep, muted, pastel, bright, dark, colorblind
Theme Background Grid Best For
darkgrid Dark Yes Data-dense displays
whitegrid White Yes Academic reports
dark Dark No Presentations
white White No Papers
ticks White No Minimalist style

(2) Chart Selection Decision Guide

100%
graph TB
    DATA[Data Type] --> CAT[Categorical]
    DATA --> NUM[Numerical]
    DATA --> TIME[Time Series]
    CAT --> COMP[Comparison<br/>Bar Chart]
    CAT --> PART[Part of Whole<br/>Pie / Stacked Bar]
    NUM --> DIST[Distribution<br/>Histogram / KDE / Box]
    NUM --> REL[Relationship<br/>Scatter / Heatmap]
    TIME --> TREND[Trend<br/>Line Chart]
    TIME --> SEA[Seasonality<br/>Seasonal Plot]

▶ Example: CJK Font Configuration

PYTHON
import matplotlib.pyplot as plt

# Method 1: Use SimHei font (Windows)
plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei"]
plt.rcParams["axes.unicode_minus"] = False

# Method 2: Use English labels (recommended for i18n)
# Keep all labels in English to avoid font issues across platforms
fig, ax = plt.subplots()
ax.set_title("Monthly Sales Report")  # English for compatibility
ax.set_xlabel("Month")
ax.set_ylabel("Revenue (thousand USD)")

Output:

TEXT
# Executed successfully

❓ FAQ

Q Should I use Matplotlib or Seaborn?
A Use Seaborn for everyday analysis (cleaner and more elegant), and Matplotlib when you need fine-grained control. Seaborn is built on top of Matplotlib, so you can mix and match freely.
Q How do I fix garbled CJK characters in charts?
A Set plt.rcParams["font.sans-serif"] to a CJK font. However, using English labels is recommended to avoid cross-platform font issues.
Q My saved figures look blurry. How do I fix this?
A Set the dpi parameter: plt.savefig("fig.png", dpi=150). Use 300+ for papers, 100–150 for web. For vector graphics, use .svg or .pdf format.
Q How do I choose the right chart type?
A It depends on your data type and goal — use line charts for time trends, bar charts for category comparison, histograms/box plots for distributions, and scatter plots/heatmaps for two-variable relationships.
Q What does the hue parameter in Seaborn do?
A hue groups and colors data by a specified column. For example, sns.scatterplot(data=df, x="ad_spend", y="revenue", hue="category") assigns a different color to each category.
Q How do I fix subplots that are too tightly spaced?
A Use plt.tight_layout() for automatic adjustment, or plt.subplots_adjust(hspace=0.3, wspace=0.3) for manual spacing control.

📖 Summary


📝 Exercises

  1. Basic (Difficulty ⭐): Use Matplotlib to draw a line chart showing 12 months of sales trends. Add a title and axis labels. Hint: refer to the line chart example in Section 3.
  2. Intermediate (Difficulty ⭐⭐): Use Seaborn to create a 2x2 subplot panel: line chart (trend), bar chart (category comparison), box plot (distribution), and heatmap (correlation), using simulated SalesPredict data. Hint: plt.subplots(2,2) + sns.xxx(ax=axes[i,j]).
  3. Challenge (Difficulty ⭐⭐⭐): Create an interactive dashboard concept — plot a monthly revenue trend chart, highlight "promotion months" and "regular months" in different colors, and add annotations explaining the promotion effects. Hint: use ax.axvspan() to shade regions and ax.annotate() to add annotations.

← Previous: Pandas Data Processing | Next: Getting Started with Scikit-learn →

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏