自学教程 学编程从这里开始

Pandas 进阶可视化

Pandas 与 Matplotlib / Seaborn 进阶可视化

承接《Pandas 与 NumPy 结合使用》,本篇聚焦进阶可视化,不再只讲基础绘图,重点讲解 Pandas 数据对接 Matplotlib、Seaborn 的工作流、多子图、样式美化、分组绘图、双轴、中文、导出、图表联动、大数据绘图优化,保持系列教程统一风格。
前置导入

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

# 示例数据
df = pd.DataFrame({
    "region": ["华东","华东","华南","华南","华北","华北","华东","华南","华北","华东"],
    "cate": ["手机","电脑","手机","电脑","手机","电脑","手机","电脑","手机","电脑"],
    "sales": [1200, 800, 1500, 950, 1100, 780, 1350, 1020, 960, 1420],
    "profit": [180, 120, 220, 140, 160, 110, 195, 150, 132, 176]
})
print(df)

一、基础协作关系

  1. Pandas 内置 .plot():底层封装 Matplotlib,语法极简,适合快速探索;
  2. Seaborn:专门面向统计图表,接收 Pandas DataFrame 作为 data 参数,自动处理分组、调色;
  3. Matplotlib:底层画布、坐标轴、子图、字体、布局、导出控制;

标准工作流:Pandas 做数据清洗、分组、透视 → 传给 seaborn / plt 绘图 → matplotlib 精细调整样式。

统一设置(中文、负号,必加)

plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
sns.set_style("whitegrid") # seaborn全局样式

二、Pandas plot 进阶用法(基于matplotlib)

df.plot() 返回 Axes 对象,可以继续用 matplotlib 接口修改,这是进阶关键。

# 基础,返回ax
ax = df.plot(kind="bar", x="region", y="sales", figsize=(10,4))
ax.set_title("区域销售额")
ax.set_xlabel("区域")
ax.set_ylabel("销售额")
plt.show()

2.1 多子图 subplots

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
df.groupby("region")["sales"].sum().plot(kind="bar", ax=ax1, title="销售额")
df.groupby("region")["profit"].sum().plot(kind="line", marker="o", ax=ax2, title="利润")
plt.tight_layout() # 自动调整间距,防止标签重叠
plt.show()

重点:ax=ax1 把绘图绑定到指定子图,是多图排版核心。

2.2 双Y轴(twinx)

适合量级差距很大的两个指标,销售额&利润率

g_df = df.groupby("region").agg(sales=("sales","sum"), profit_rate=("profit","sum"))
ax1 = g_df["sales"].plot(kind="bar", color="#4472C4", figsize=(10,5))
ax2 = ax1.twinx()
g_df["profit_rate"].plot(kind="line", color="#ED7D31", marker="o", ax=ax2)
ax1.set_ylabel("销售额")
ax2.set_ylabel("利润")
plt.show()

2.3 分组绘图 + 堆叠柱状图

pivot_df = df.pivot_table(index="region", columns="cate", values="sales", aggfunc="sum")
ax = pivot_df.plot(kind="bar", stacked=True, figsize=(9,5))
ax.legend(title="品类")
plt.show()

三、Seaborn 进阶:接收Pandas DataFrame

seaborn 优势:直接传入 data=df,通过 x/y/hue 指定字段,不用手动整理透视表。

3.1 分组柱状图 hue

plt.figure(figsize=(10,5))
sns.barplot(data=df, x="region", y="sales", hue="cate", errorbar=None)
plt.title("各区域分品类销售额")
plt.show()
  • hue:分组配色,对应Pandas的分类字段
  • errorbar=None:关闭默认误差棒(业务报表常用)

3.2 箱线图 boxplot(分布探查)

plt.figure(figsize=(8,5))
sns.boxplot(data=df, x="region", y="sales", hue="cate")
plt.show()

3.3 热力图 heatmap(相关性矩阵/透视表)

corr = df[["sales","profit"]].corr()
plt.figure(figsize=(5,4))
sns.heatmap(corr, annot=True, cmap="Blues", fmt=".2f")
plt.show()

透视表热力图(业务高频)

pivot = df.pivot_table(index="region", columns="cate", values="sales", aggfunc="sum")
plt.figure(figsize=(6,4))
sns.heatmap(pivot, annot=True, fmt="g", cmap="OrRd")
plt.show()

3.4 散点图 + 拟合线 regplot

plt.figure(figsize=(7,5))
sns.regplot(data=df, x="sales", y="profit")
plt.show()

四、FacetGrid 分面绘图(Seaborn高阶)

自动按字段切分多个子图,等价循环分组绘图,适合做多维度对比

g = sns.FacetGrid(data=df, col="cate", height=4)
g.map(sns.barplot, "region", "sales", errorbar=None)
g.set_titles("品类:{col_name}")
plt.show()
  • col 按列分面;row 按行分面;hue 颜色分组

五、图表美化进阶

  1. 调色盘
# seaborn调色板
sns.set_palette("Set2")
# 自定义颜色列表
colors = ["#1f77b4","#ff7f0e"]
  1. 图例、网格、边框
ax.legend(loc="upper right", bbox_to_anchor=(1.2,1)) # 图例放到图外侧
ax.grid(axis="y", alpha=0.3)
sns.despine() # 移除上、右边框
  1. 刻度旋转,防止文字重叠
plt.xticks(rotation=30)

六、导出高清图片

plt.savefig("chart.png", dpi=300, bbox_inches="tight")
# bbox_inches="tight" 自动裁掉多余空白,避免图例被截断
plt.close() # 释放画布,循环绘图必须加,防止内存暴涨

支持格式:png、jpg、pdf、svg矢量图

七、大数据绘图优化(非常重要)

当数据上万行以上,直接绘图卡顿、内存高:

  1. 采样:df.sample(frac=0.1, random_state=42) 抽样后再画散点图
  2. 聚合:先 groupby 汇总,再绘图,不要直接画原始明细
  3. 避免 sns.scatterplot 画百万点,改用 hexbin 热力分箱图
# 示例:hexbin 替代海量散点
fig, ax = plt.subplots()
ax.hexbin(df["sales"], df["profit"], gridsize=15, cmap="Blues")
plt.colorbar(ax.collections[0])
plt.show()

八、循环批量绘图模板(业务报表)

region_list = df["region"].unique()
for r in region_list:
    sub_df = df[df["region"] == r]
    plt.figure(figsize=(7,4))
    sns.barplot(data=sub_df, x="cate", y="sales", errorbar=None)
    plt.title(f"{r} 销售明细")
    plt.savefig(f"{r}_sale.png", dpi=300, bbox_inches="tight")
    plt.close()

九、Pandas + Matplotlib + Seaborn 选型建议

  • 快速看趋势、简单折线/柱状:Pandas .plot()
  • 统计分布、箱线、分组对比、热力图:Seaborn
  • 精细排版、复杂多子图、自定义标注、双轴:Matplotlib底层控制

十、高频坑清单

  1. 中文乱码:忘记设置 font.sans-serif;Linux服务器字体缺失,需要预装中文字体
  2. 循环绘图不写 plt.close(),画布堆积,内存泄漏
  3. 图例、标题被截断:保存时不加 bbox_inches="tight"
  4. seaborn 传入数组,不使用data参数,hue不方便绑定字段
  5. 大数据直接绘制散点图,渲染极慢,优先聚合/抽样/hexbin
  6. 多个子图忘记 tight_layout(),标签重叠
  7. twinx 双轴图例默认分开,需要手动合并图例

十一、综合实战模板

def plot_region_sales(df, save_path=None):
    plt.rcParams["font.sans-serif"] = ["SimHei"]
    plt.rcParams["axes.unicode_minus"] = False
    sns.set_style("whitegrid")
    fig, ax = plt.subplots(figsize=(10,5))
    sns.barplot(data=df, x="region", y="sales", hue="cate", ax=ax, errorbar=None)
    ax.set_title("区域-品类销售额")
    ax.set_xlabel("区域")
    ax.set_ylabel("销售额")
    sns.despine()
    if save_path:
        plt.savefig(save_path, dpi=300, bbox_inches="tight")
        plt.close()
    else:
        plt.show()

plot_region_sales(df)

十二、速查表

需求方案
快速绘图,少代码df.plot(kind=”xxx”, ax=ax)
分组统计图表、hue配色seaborn barplot / boxplot
相关性矩阵sns.heatmap
按维度自动切分多图FacetGrid
双Y轴ax.twinx()
高清导出savefig(dpi=300, bbox_inches=”tight”)
百万级散点hexbin 分箱热力图
标签:

0 条笔记