Machine Learning: Matplotlib与Seaborn可视化 — 数据模式可视化完全指南

一张好图胜过千行数据——可视化是发现数据模式的第一步。

1. 你将学到


2. 一个产品经理的真实故事

(1) 痛点:表格数据看不出趋势和异常

Bob把SalesPredict的月度销售报表发给团队——50行Excel数据,没人能快速看出哪个品类在下滑、哪些月份有异常波动。Alice的美国数据趋势和中国数据完全不同,但只看数字很难发现。数据埋在表格里,关键洞察被淹没。

(2) 可视化的解法

一张折线图立刻暴露:Electronics品类Q3有明显下滑趋势;一张热力图揭示广告费和销售额的相关性远超预期。

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) 收益:5分钟发现关键业务洞察

Bob用可视化替代纯表格后,5分钟就发现了Q3 Electronics品类15%的下滑趋势,及时调整了广告策略挽回约200 thousand USD的潜在损失。


3. Matplotlib基础

(1) Figure/Axes体系

Matplotlib采用两层结构:Figure(画布)包含一个或多个Axes(绘图区)。

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]

▶ 示例:创建基础折线图

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)

输出:

TEXT 📖 仅展示
# 执行成功

(2) 常用图表类型

▶ 示例:柱状图与散点图

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)

输出:

TEXT 📖 仅展示
# 执行成功
图表类型 最佳场景 Matplotlib函数
折线图 时间趋势 ax.plot()
柱状图 类别比较 ax.bar() / ax.barh()
散点图 两变量关系 ax.scatter()
饼图 占比分布 ax.pie()
直方图 单变量分布 ax.hist()

4. Seaborn高级图表

Seaborn构建在Matplotlib之上,提供更高级的统计图表和更美观的默认样式。

(1) 分布图

▶ 示例:订单金额分布分析

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)

输出:

TEXT 📖 仅展示
# 执行成功

(2) 热力图

▶ 示例:特征相关性热力图

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)

输出:

TEXT 📖 仅展示
# 执行成功

(3) 多子图布局

▶ 示例:SalesPredict 4维度分析面板

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)

输出:

TEXT 📖 仅展示
# 执行成功

5. 样式定制与图表选择

(1) Seaborn主题与调色板

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
主题 背景 网格 适用场景
darkgrid 深色 数据密集型
whitegrid 白色 学术报告
dark 深色 演示文稿
white 白色 论文
ticks 白色 极简风格

(2) 图表选择决策

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]

▶ 示例:中文显示配置

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)")

输出:

TEXT 📖 仅展示
# 执行成功

❓ 常见问题

Q Matplotlib和Seaborn该用哪个?
A 日常分析用Seaborn(更简洁美观),需要精细控制用Matplotlib。Seaborn的底层就是Matplotlib,两者可以混用。
Q 图表中文乱码怎么解决?
A 设置plt.rcParams["font.sans-serif"]为中文字体。但推荐用英文标签,避免跨平台字体问题。
Q savefig保存图片模糊怎么办?
A 设置dpi参数:plt.savefig("fig.png", dpi=150)。论文用300+,网页用100-150。矢量图用.svg.pdf格式。
Q 如何选择合适的图表类型?
A 看数据类型和目的——时间趋势用折线图,类别比较用柱状图,分布用直方图/箱线图,两变量关系用散点图/热力图。
Q Seaborn的hue参数是什么?
A hue按指定列分组着色。如sns.scatterplot(data=df, x="ad_spend", y="revenue", hue="category")会为每个品类用不同颜色。
Q 子图间距太紧怎么办?
Aplt.tight_layout()自动调整,或用plt.subplots_adjust(hspace=0.3, wspace=0.3)手动控制间距。

📖 小节


📝 作业

  1. 基础题(难度⭐):用Matplotlib绘制一条折线图,展示12个月的销售额趋势,添加标题和轴标签。提示:参考第3节的折线图示例。
  2. 进阶题(难度⭐⭐):用Seaborn绘制一个2x2子图:折线图(趋势)、柱状图(品类比较)、箱线图(分布)、热力图(相关性),使用SalesPredict模拟数据。提示:plt.subplots(2,2) + sns.xxx(ax=axes[i,j])
  3. 挑战题(难度⭐⭐⭐):创建一个交互式仪表盘概念——绘制月度Revenue趋势图,在图上用不同颜色标注"促销月"和"普通月",并添加注释说明促销效果。提示:用ax.axvspan()标注区间,ax.annotate()添加注释。

← 上一课:Pandas数据处理 | 下一课:Scikit-learn入门 →

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

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

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