2026-06-14-数据可视化 Vol.3 可视化库

8762 个字
44 分钟
2026-06-14-数据可视化 Vol.3 可视化库

matplotlib / Seaborn#


一、全局配置#

字体配置:通过 rcParams 字典全局修改 matplotlib 的运行时配置参数。 font.sans-serif 指定无衬线字体族的回退列表,matplotlib 按列表顺序查找第一个系统中已安装的字体。 axes.unicode_minus 设为 False 是为了让 matplotlib 使用 ASCII 连字符 - 替代 Unicode 负号 , 因为很多中文字体缺这个 Unicode 字符,会显示为方块 □。 这些配置放在 import 之后、任何绘图之前,对所有后续图表生效。

import matplotlib.pyplot as plt # 导入 pyplot 模块,约定别名为 plt
# ===== 字体配置 =====
plt.rcParams['font.sans-serif'] = ['SimHei'] # 【字体配置】无衬线字体族列表,SimHei=黑体(Windows自带),
# 也可用 'Microsoft YaHei'(微软雅黑)、'WenQuanYi Micro Hei'(Linux文泉驿)、
# 'PingFang SC'(macOS苹方);matplotlib 按列表顺序查找第一个可用字体
plt.rcParams['axes.unicode_minus'] = False # 【字体配置】关闭 Unicode 负号,用 ASCII '-' 替代 Unicode '−',
# 避免中文字体缺失该字符导致负号显示为方块 □
# ===== 画布默认值 =====
plt.rcParams['figure.figsize'] = (8, 5) # 全局默认画布尺寸:宽8英寸、高5英寸(所有未显式指定 figsize 的图都用这个)
plt.rcParams['figure.dpi'] = 100 # 全局默认分辨率:100 dots per inch,控制屏幕上图片的像素密度
# 最终像素数 = figsize × dpi,如 8×100=800px 宽

二、Figure / Axes 创建区#

子图: API 是 plt.subplots(),它一次性创建 Figure(画布容器)和 Axes(坐标轴/子图区域)对象。 nrowsncols 定义子图网格的行列数,返回的 axes 是一个二维 NumPy 数组,通过 axes[row, col] 索引操作每个子图。 这是"面向对象"写法,比老的 plt.subplot() 更灵活——你可以对每个子图单独设置标题、刻度、图例等,互不干扰。 最后用 plt.tight_layout() 自动计算并调整子图之间的间距,防止标签文字重叠/被裁切。

单图

fig, ax = plt.subplots(figsize=(8, 5), dpi=100)
# 【子图】创建一个包含单个 Axes 的 Figure;fig 是整张画布,ax 是画布上的唯一坐标轴区域
# figsize 参数会覆盖全局 rcParams 中的默认值,单位是英寸 (width, height)
# dpi=100 表示该图的分辨率为 100 像素/英寸,最终像素 = 800×500

多子图(网格布局)

fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8))
# 【子图】创建 2行×2列 共4个子图的网格,axes 是 shape=(2,2) 的 ndarray
# figsize=(10,8) 指定整个画布的大小(宽10,高8英寸),每个子图自动均分画布空间
axes[0, 0].plot(x1, y1, color='blue') # 【子图】通过行列索引 [行, 列] 访问第1个子图,在上面画折线图
axes[0, 1].bar(x2, y2, color='orange') # 【子图】访问第2个子图(第0行第1列),在上面画柱状图
axes[1, 0].scatter(x3, y3, color='green') # 【子图】访问第3个子图(第1行第0列),在上面画散点图
axes[1, 1].hist(data, bins=20) # 【子图】访问第4个子图(第1行第1列),在上面画直方图
# 遍历所有子图做统一设置(如添加标题、去边框)
for i, row in enumerate(axes): # 遍历行
for j, ax in enumerate(row): # 遍历列
ax.set_title(f'子图 {i+1},{j+1}') # 【子图】给每个子图分别设置标题
ax.spines['top'].set_visible(False) # 去顶边框
ax.spines['right'].set_visible(False) # 去右边框
plt.tight_layout() # 【子图】自动调整子图间距(padding),
# 防止相邻子图的标签/标题重叠,是最后一步布局操作

plt.subplots 解包规则(易错点)

# nrows=1, ncols=1 时,axes 是单个对象,直接赋值
fig, ax = plt.subplots(1, 1) # ✅ ax 是 Axes 对象,可直接 .plot()
# nrows=1, ncols>1 时,axes 是一维数组
fig, axes = plt.subplots(1, 3) # ✅ axes 是 shape=(3,) 的一维数组
axes[0].plot(x, y) # ✅ 用一维索引访问
# nrows>1, ncols>1 时,axes 是二维数组
fig, axes = plt.subplots(2, 3) # ✅ axes 是 shape=(2,3) 的二维数组
axes[0, 1].plot(x, y) # ✅ 用二维索引 [行, 列] 访问

不规则子图布局(使用 subplot_mosaic,matplotlib 3.3+)

# 用字符串定义布局:每个字母代表一个子图,同一字母跨越多格表示合并
fig, axes = plt.subplot_mosaic([
['A', 'A', 'B'], # 第1行:A 占2列,B 占1列
['A', 'A', 'C'], # 第2行:A 继续占2列,C 占1列
['D', 'E', 'F'], # 第3行:D、E、F 各占1列
], figsize=(10, 8))
# axes 是 dict,key 是布局字母:{'A': ax_A, 'B': ax_B, ...}
axes['A'].plot(x1, y1) # 【子图】A 是合并了2行×2列的大子图
axes['B'].bar(x2, y2) # 【子图】B 是右上角单格
axes['D'].scatter(x3, y3) # 【子图】D 是左下角单格

其他写法

plt.figure(figsize=(8, 5)) # 先创建 Figure
plt.subplot(2, 2, 1) # 再逐个添加子图:(行数, 列数, 序号),序号从1开始
plt.plot(x, y)
plt.subplot(2, 2, 2) # 切换到第2个子图
plt.bar(x, y)
# 缺点:状态机写法,难以精确控制每个子图的属性

三、坐标轴与刻度区#

刻度配置:刻度分为"刻度位置"(ticks,即数据坐标系中刻度线出现的位置)和"刻度标签"(tick labels, 即刻度线上方/旁边的文字)。配置分为四个层次:

set_xticks() / set_yticks() — 设定刻度在数据轴上的位置(数值列表);

set_xticklabels() / set_yticklabels() — 覆盖刻度标签文字(与刻度位置一一对应);

tick_params() — 统一控制所有刻度的视觉样式(旋转角度、字体大小、颜色、刻度线长度等);

set_xlim() / set_ylim() — 设定坐标轴的数值范围,超出范围的刻度不会显示。

# ===== 轴标签 =====
ax.set_xlabel('时间', fontsize=12)
# 【刻度配置】设置 x 轴标签文字为"时间",字号12pt;该标签显示在 x 轴下方居中位置
ax.set_ylabel('数值', fontsize=12)
# 【刻度配置】设置 y 轴标签文字为"数值",字号12pt;该标签显示在 y 轴左侧居中位置
# ===== 图表标题 =====
ax.set_title('图表标题', fontsize=14, fontweight='bold')
# 【刻度配置】设置图表标题,fontweight='bold' 加粗,标题显示在坐标轴顶部居中
# ===== 坐标轴范围 =====
ax.set_xlim(0, 100)
# 【刻度配置】锁定 x 轴显示范围从 0 到 100,超出范围的数据点不会被裁剪但不可见
# 参数等价于 ax.set_xlim(left=0, right=100)
ax.set_ylim(0, 1)
# 【刻度配置】锁定 y 轴显示范围从 0 到 1
# ===== 刻度位置(ticks 在哪里) =====
ax.set_xticks([0, 25, 50, 75, 100])
# 【刻度配置】在 x 轴的 0、25、50、75、100 这5个位置放置刻度线和标签
# 刻度位置是数据坐标,必须落在 set_xlim 范围内才能显示
ax.set_yticks([0, 0.2, 0.4, 0.6, 0.8, 1.0])
# 【刻度配置】在 y 轴的这些位置放置刻度线;如果不调此参数,matplotlib 会自动选择合适的刻度位置
# ===== 刻度标签(ticks 上显示什么文字) =====
ax.set_xticklabels(['一月', '二月', '三月', '四月', '五月'])
# 【刻度配置】用自定义文字覆盖刻度标签,与 set_xticks 的位置一一对应
# 第1个位置(0)显示"一月",第2个位置(25)显示"二月"...
# 必须先调 set_xticks 再调 set_xticklabels,否则标签数量和位置可能不匹配
# ===== 刻度样式(tick_params 统一控制外观) =====
ax.tick_params(axis='x', rotation=45, labelsize=10, colors='gray')
# 【刻度配置】axis='x' 只作用于 x 轴刻度(也可设为 'y' 或 'both')
# rotation=45:刻度标签文字逆时针旋转45度,用于标签文字过长时防止重叠
# labelsize=10:刻度标签字号设为10pt
# colors='gray':刻度标签和刻度线颜色设为灰色
ax.tick_params(axis='both', which='major', length=6, width=1.5)
# 【刻度配置】which='major' 控制主刻度线长度和宽度(which='minor' 控制次刻度线)
# length=6 刻度线向外延伸6点;width=1.5 刻度线宽度1.5点
# ===== 坐标轴脊线(spines)美化 =====
ax.spines['top'].set_visible(False) # 【刻度配置】隐藏顶部边框脊线,实现"开口式"坐标轴风格
ax.spines['right'].set_visible(False) # 【刻度配置】隐藏右侧边框脊线(Edward Tufte 推荐的数据-墨水比优化)
# spines 的 key 有4个:'top', 'bottom', 'left', 'right'
# 还可调 spine 位置:ax.spines['left'].set_position(('data', 0)) 将 y 轴移到 x=0 处
# ===== 网格线 =====
ax.grid(True, linestyle='--', alpha=0.3)
# 【刻度配置】显示网格线,linestyle='--' 虚线风格,alpha=0.3 透明度30%(降低视觉干扰)
# 网格线的位置与刻度位置对齐,帮助读者从数据标记点对到坐标轴数值
# ===== 图例 =====
ax.legend(loc='upper right', frameon=False)
# 【刻度配置】显示图例,loc='upper right' 放在右上角;
# frameon=False 取消图例的边框矩形(更简洁)
# 图例的每一项对应之前 plot/bar/scatter 时设置的 label 参数

四、常见图型#

# 1. 柱形图
ax.bar(x, y, color='#3A86FF', width=0.6, edgecolor='black')
# x: 每个柱子的 x 轴位置(类别标签的数值映射)
# y: 每个柱子的高度
# width=0.6: 柱宽(默认0.8),值越小柱子越窄、间距越大
# edgecolor='black': 柱子边框颜色,使柱子边界清晰
# 2. 横向条形图
ax.barh(y, x, height=0.6, color='#FF6B6B')
# barh = horizontal bar,y 是类别位置,x 是对应数值(与 bar 的 x,y 互换)
# height 控制条形的"厚度"(在横向图中相当于柱宽)
# 3. 直方图
ax.hist(data, bins=20, density=False, edgecolor='black')
# data: 一维原始数据数组,matplotlib 自动分箱统计频数
# bins=20: 分成20个区间(柱子数量),bins 越大直方图越精细
# density=False: y 轴显示频数(计数);density=True 则显示概率密度(总面积=1)
# 4. 箱线图
ax.boxplot(data, labels=['A','B','C'], showfliers=True, notch=False)
# data: 列表的列表,每个子列表是一组数据
# showfliers=True: 显示离群点(用小圆圈标记超出1.5倍IQR的点)
# notch=True: 中位数处做凹槽,凹槽不重叠表示中位数差异显著
# 5. 散点图
ax.scatter(x, y, c=colors, s=sizes, alpha=0.6, cmap='viridis')
# c: 每个点的颜色值(可以是单色字符串或数值数组,数值时配合 cmap 映射颜色)
# s: 每个点的大小(标量或数组),单位是点的平方
# alpha=0.6: 透明度,点重叠时能看出密度分布
# 【cmap】cmap='viridis':将 c 的数值映射到 viridis 色带(蓝→绿→黄),是默认推荐的色盲友好 colormap
# 6. 气泡图(散点的s参数映射第三维)
ax.scatter(x, y, s=z*100, c=z, cmap='coolwarm', alpha=0.7)
# s=z*100: 用第三维 z 控制气泡大小,*100 是为了让点可见(z 值可能太小)
# c=z: 同一维 z 也映射为颜色,实现"大小+颜色"双通道编码第三维
# 【cmap】cmap='coolwarm':双向色带(蓝→白→红),适合有正负对比的数据(如相关系数)
# 7. 折线图
ax.plot(x, y, color='red', linestyle='--', linewidth=2, marker='o', label='系列A')
# linestyle='--': 虚线('-'实线, '-.'点划线, ':'点线)
# marker='o': 数据点处画实心圆标记('s'方块, '^'三角, 'd'菱形, 'x'叉号)
# label='系列A': 图例中显示的系列名称,需配合 ax.legend() 才能显示
# 8. 面积图
ax.fill_between(x, y1, y2, alpha=0.3, color='skyblue')
# y1 和 y2 之间的区域被填充颜色(y1 可以是全0数组,实现从x轴向上的填充)
# alpha=0.3: 填充区域半透明,避免遮挡背后的线条或网格
# 9. 主题河流图
ax.stackplot(x, y1, y2, y3, labels=['A','B','C'], baseline='wiggle')
# stackplot: 堆叠面积图,y1,y2,y3 依次堆叠在彼此的顶部
# baseline='wiggle': 关键参数!使整体围绕中心轴波动,形成"河流"的视觉效果
# baseline='zero' 是从 y=0 向上堆叠(默认),baseline='sym' 是对称堆叠
# 10. 玫瑰图 / 雷达图(极坐标)
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
# subplot_kw={'projection': 'polar'}:在创建子图时传入,将坐标系从直角坐标转为极坐标
# 极坐标下 x 轴变成角度(弧度),y 轴变成半径
ax.bar(theta, r, width=2*np.pi/N)
# 玫瑰图:在极坐标上画柱状图,theta 是角度(弧度制),r 是半径长度
# width 控制每个扇形的弧宽,N 是扇形数量,2π/N 让扇形刚好铺满360°
ax.fill(angles, values, alpha=0.25)
# 雷达图填充:angles 是各轴的角度,values 是各轴的数据值
# fill 将多边形内部填充颜色,alpha 控制透明度以显示网格

五、颜色与 colormap#

cmap 怎么使用的:colormap(颜色映射表,简称 cmap)是一种将数值映射到颜色的查找表。 c=数值数组 + cmap='映射表名',matplotlib 自动完成映射:最小值→cmap最左颜色,最大值→cmap最右颜色。

  • 顺序数据(温度、人口):viridis(默认,色盲友好)、plasmahot
  • 双向数据(相关系数、增长率,有正有负):coolwarmRdBu(红蓝)、bwr
  • 分类数据(离散类别):Set1tab10Pastel1
  • _r 后缀反转颜色顺序(如 viridis_r:黄→绿→蓝)

cmap 配合 plt.colorbar() 添加颜色条(图例),让读者知道颜色和数值的对应关系。

# ===== 三种颜色写法 =====
color='red' # 命名颜色:matplotlib 内置140+种命名颜色('red','blue','green','orange'等)
color='#FF5733' # 十六进制 HEX:6位,每2位分别表示 R G B (00-FF),与 CSS/Web 通用
color=(0.2, 0.4, 0.6) # RGB 元组:每个通道 0.0~1.0 的浮点数(0.2=20%红, 0.4=40%绿, 0.6=60%蓝)
# ===== 常用 cmap 及选择场景 =====
cmap='viridis' # 默认推荐,从蓝渐变到绿到黄,色盲友好(红绿色盲也能分辨),适合连续数值的默认选择
cmap='coolwarm' # 双向色带:冷色(蓝)→ 中性(白/灰)→ 暖色(红),适合有正负值的数据如相关系数矩阵
cmap='RdYlBu_r' # 红→黄→蓝 的反转(_r = reversed),适合降水量、风险等级等"红=高"直觉的数据
cmap='hot' # 黑→红→黄→白,模仿热辐射,适合热力图、密度图
cmap='plasma' # 深紫→粉→黄,替代 jet 的现代选择,感知均匀(perceptually uniform)
cmap='Set1' # 9种鲜明颜色的离散色板,适合分类数据(柱状图多类别着色)
cmap='tab10' # Tableau 的10色离散色板,比默认色更美观,适合折线图多系列区分
# ===== 添加 colorbar(颜色条/色阶图例) =====
sc = ax.scatter(x, y, c=z, cmap='viridis', s=50)
# 【cmap】scatter 返回一个 PathCollection 对象,它是 colorbar 的"数据源"
# c=z:将数值数组 z 映射到 viridis 色带;z 的最小值→紫色,最大值→黄色
cbar = plt.colorbar(sc, ax=ax, label='强度', shrink=0.8)
# 【cmap】colorbar 必须传入一个 mappable 对象(如 scatter/contourf/imshow 的返回值)
# ax=ax:指定 colorbar 与哪个 Axes 对齐(宽度自动匹配该 Axes)
# label='强度':colorbar 旁边显示的标签文字
# shrink=0.8:缩小 colorbar 高度到80%,避免顶部超出图表
cbar.ax.tick_params(labelsize=8) # 【cmap】调整 colorbar 刻度标签字体大小
cbar.set_ticks([0, 0.5, 1.0]) # 【cmap】手动设置 colorbar 的刻度位置
cbar.set_ticklabels(['低', '中', '高']) # 【cmap】用中文覆盖 colorbar 刻度标签
# ===== 热力图的 cmap(imshow / pcolormesh) =====
im = ax.imshow(matrix, cmap='coolwarm', aspect='auto', origin='upper')
# 【cmap】imshow 显示二维矩阵作为图片,每个像素的颜色由 matrix[i,j] 经 cmap 映射
# aspect='auto':自动拉伸填充 Axes;origin='upper':矩阵 [0,0] 在左上角
plt.colorbar(im, ax=ax, label='值')
# ===== 等高线图的 cmap =====
contour = ax.contourf(X, Y, Z, levels=20, cmap='viridis')
# 【cmap】contourf 绘制填充等高线图,levels=20 表示20个层级,每层颜色由 cmap 映射 Z 值
# 每个等高线区间对应 cmap 中的一段颜色,颜色过渡越平滑越好
# ===== 颜色归一化(控制 cmap 映射范围) =====
from matplotlib.colors import Normalize, LogNorm
norm = Normalize(vmin=0, vmax=100) # 线性映射:将 [0,100] 映射到 cmap 的 [起点, 终点]
sc = ax.scatter(x, y, c=z, cmap='viridis', norm=norm)
# vmin/vmax 直接在 scatter 中传也行:ax.scatter(..., vmin=0, vmax=100)
log_norm = LogNorm(vmin=1, vmax=1000) # 对数映射:适合数据跨度几个数量级的情况
# 使用场景:数据从 1 到 1000,用线性映射时小值全挤到 cmap 一端,对数映射让低值区间也有颜色区分

六、Seaborn#

6.1 定义、加载与优势#

Seaborn 是什么:Seaborn 是基于 matplotlib 构建的 Python 高级统计可视化库,由 Michael Waskom 开发。 它封装了 matplotlib 的底层绘图 API,提供面向 DataFrame 的高级接口,让统计图表能用一行代码完成。

import seaborn as sns # 加载 Seaborn,约定别名 sns(取自电视剧《白宫风云》角色 Samuel Norman Seaborn)

Seaborn 相比裸 matplotlib 的优势

优势说明对比 matplotlib
① DataFrame 原生支持直接传列名字符串(x='col1'),无需手动提取数组plt.plot(df['col1'], df['col2']) 需手动取列
② 自动分组着色hue='类别列' 一个参数完成分组+配色+图例需手动循环分组、选色、拼图例
③ 统计功能内置箱线图/小提琴图自动计算分位数;回归图自动拟合+置信区间需手动调用 numpy/scipy 计算
④ 默认美观自带精心设计的调色板和主题样式,开箱即用默认配色朴素,需大量手动美化
⑤ Figure-level APIpairplotclustermapcatplot 等自动创建多子图布局需手动 subplots + 循环填充每个子图

6.2 风格特点#

Seaborn 提供五大内置主题,通过 sns.set_theme() 一键切换整体视觉风格。 主题控制的是背景色、网格线、刻度线等"画布层面"的样式,不改变数据本身的绘制逻辑。

import seaborn as sns
# ===== 主题风格(style) =====
sns.set_theme(style='whitegrid') # 白底+灰色网格线(最常用,商务图表首选)
sns.set_theme(style='darkgrid') # 灰底+白色网格线(适合深色背景的演示文稿)
sns.set_theme(style='white') # 纯白底无网格(极简风格,适合海报/信息图)
sns.set_theme(style='dark') # 纯灰底无网格(与 darkgrid 类似但无网格)
sns.set_theme(style='ticks') # 白底+刻度短线(Edward Tufte 推荐风格,最小化非数据元素)
# ===== 调色板(palette) =====
sns.set_theme(palette='deep') # 默认10色,饱和度高,适合分类数据
sns.set_theme(palette='muted') # 低饱和度版本,视觉更柔和(推荐用于论文)
sns.set_theme(palette='pastel') # 粉彩色系,适合浅色背景
sns.set_theme(palette='bright') # 高亮度色系,适合深色背景
sns.set_theme(palette='dark') # 深色系
sns.set_theme(palette='colorblind')# 色盲友好色板(约8%男性色盲,学术/公开报告推荐)
# ===== 上下文缩放(context) =====
sns.set_context('paper') # 论文用:小字体,适合嵌入 LaTeX/Word
sns.set_context('notebook') # 默认:适中字体,适合 Jupyter Notebook
sns.set_context('talk') # 演讲用:大字体,适合投影演示
sns.set_context('poster') # 海报用:超大字体,适合打印展板
# context 会自动缩放所有文字元素(标签、刻度、图例)的字体大小
# ===== 一行设置全部 =====
sns.set_theme(style='whitegrid', palette='muted', context='notebook', font='SimHei')
# 同时设定:主题样式 + 调色板 + 上下文缩放 + 中文字体

6.3 与 Matplotlib 的关系#

关系:Seaborn 是 matplotlib 的高级封装,不是替代品。 Seaborn 内部所有绘图最终都调用 matplotlib 的底层 API,返回的仍然是 matplotlib 的 Axes 对象。 这意味着:你可以用 Seaborn 快速出图,再用 matplotlib 的 API 做精细微调。

Seaborn(高层:DataFrame 直传、自动统计、默认美观)
↓ 调用
Matplotlib(底层:像素级控制、坐标轴定制、图表保存)

三种典型的协作模式

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
df = pd.DataFrame({'x': range(5), 'y': [3,7,2,5,8]})
# ===== 模式1:Seaborn 画图 + Matplotlib 美化 =====
fig, ax = plt.subplots(figsize=(8, 5)) # matplotlib 创建画布
sns.barplot(x='x', y='y', data=df, ax=ax) # Seaborn 在指定 ax 上绘图
ax.set_title('Seaborn画+Matplotlib美', fontsize=14) # matplotlib 微调标题
ax.spines['top'].set_visible(False) # matplotlib 去边框
ax.tick_params(labelsize=10) # matplotlib 调刻度
plt.tight_layout() # matplotlib 调布局
# ===== 模式2:纯 Seaborn Figure-level 函数(自动管理画布) =====
g = sns.pairplot(df) # pairplot 返回 PairGrid 对象
g.fig.suptitle('散点矩阵', y=1.02) # 通过 .fig 访问底层 Figure 加总标题
# PairGrid / FacetGrid 是 Seaborn 独有的高级对象,.fig 是底层的 matplotlib Figure
# .axes 是底层的 matplotlib Axes 数组,可逐个微调
# ===== 模式3:Matplotlib 全局设置影响 Seaborn =====
plt.rcParams['font.sans-serif'] = ['SimHei'] # matplotlib 的 rcParams 对 Seaborn 同样生效
plt.rcParams['axes.unicode_minus'] = False
sns.set_theme(style='whitegrid') # Seaborn 主题覆盖部分 rcParams
# Seaborn 的 set_theme() 内部也是修改 rcParams,两者可混用但注意调用顺序:
# 先设 rcParams(字体等),再设 set_theme(主题),后者会覆盖前者冲突的键

API 层级对比

层级matplotlibSeaborn何时用
Figure-levelplt.subplots() 手动创建sns.pairplot(), sns.catplot(), sns.displot(), sns.jointplot(), sns.clustermap()需要自动多子图布局时
Axes-levelax.plot(), ax.bar()sns.barplot(), sns.boxplot(), sns.heatmap(), sns.lineplot(), sns.scatterplot(), sns.histplot()画到指定 ax,嵌入自定义布局时
样式层plt.rcParamssns.set_theme(), sns.set_context()全局外观设置

6.4 相关图表 API#

import seaborn as sns
import pandas as pd
# 假设 df 是一个包含多列的 DataFrame
df = pd.DataFrame({
'cat': ['A','A','B','B','C','C'],
'val': [23, 45, 56, 78, 32, 47],
'group': ['G1','G2','G1','G2','G1','G2'],
'gender': ['M','F','M','F','M','F'],
'x': [1,2,3,4,5,6],
'y': [3,7,2,5,8,4],
'z': [10,30,20,50,40,60],
'time': pd.date_range('2024-01-01', periods=6, freq='D'),
})
# 1. 柱状图(自动计算均值+误差棒)
sns.barplot(x='cat', y='val', data=df, ax=ax, palette='deep')
# 自动对每个 cat 类别的 val 求均值,误差棒默认显示95%置信区间
# 2. 箱线图(自动计算四分位数)
sns.boxplot(x='group', y='val', data=df, hue='gender', palette='Set2')
# hue='gender':按性别分组,同一 x 位置并排显示两个箱线图
# 3. 小提琴图(箱线图 + 密度曲线)
sns.violinplot(x='group', y='val', data=df, hue='gender', split=True)
# split=True:两半各一组,便于直接对比分布形状
# 4. 直方图 + KDE 密度曲线
sns.histplot(data=df, x='val', bins=20, kde=True, hue='gender', alpha=0.5)
# kde=True:叠加核密度估计平滑曲线;hue 分组后透明叠加便于对比
# 5. 散点图(支持 size/hue/style 三维编码)
sns.scatterplot(x='x', y='y', size='z', hue='cat', style='gender', data=df, sizes=(20, 200))
# size='z':z 列控制点大小;hue='cat':类别列着色;style='gender':不同标记形状
# 6. 热力图
corr = df.select_dtypes('number').corr() # 计算数值列的相关系数矩阵
sns.heatmap(corr, annot=True, fmt='.2f', cmap='coolwarm',
vmin=-1, vmax=1, square=True, linewidths=0.5,
cbar_kws={'shrink': 0.8, 'label': '相关系数'})
# 【cmap】cmap='coolwarm':蓝(-1)→白(0)→红(+1),相关系数黄金配色
# 7. 折线图(自动按 hue 分组,带置信区间)
sns.lineplot(x='time', y='val', hue='cat', data=df, style='cat', markers=True)
# 默认显示各时间点的均值±95%置信区间半透明带
# 8. 散点矩阵图(Figure-level,自动创建 N×N 子图网格)
sns.pairplot(df, hue='cat', diag_kind='kde', corner=True, palette='deep')
# 【子图】自动为每对数值列创建散点图矩阵;对角线显示 KDE 密度曲线
# corner=True:只显示左下三角,去重+省空间

七、Pyecharts#

7.1 定义、加载与特点#

Pyecharts 是什么:Pyecharts 是百度开源 JavaScript 图表库 Apache ECharts 的 Python 封装, 由陈键冬等人开发维护。它将 ECharts 的配置项映射为 Python 的链式 API,让你用纯 Python 代码生成交互式网页图表。 与 matplotlib/Seaborn 生成静态图片不同,Pyecharts 输出的是 HTML 文件,内嵌 JavaScript,支持缩放、悬停提示、数据筛选等交互。

Terminal window
pip install pyecharts # 安装 Pyecharts(库,包含常用图表)
# ===== 加载方式:按需导入,不导入整个库 =====
from pyecharts.charts import Bar # 柱状图
from pyecharts.charts import Line # 折线图
from pyecharts.charts import Pie # 饼图
from pyecharts.charts import Scatter # 散点图
from pyecharts.charts import HeatMap # 热力图
from pyecharts.charts import Map # 地图
from pyecharts.charts import Geo # 地理坐标系图
from pyecharts.charts import Graph # 关系图/网络图
from pyecharts.charts import Sankey # 桑基图
from pyecharts.charts import Radar # 雷达图
from pyecharts.charts import Funnel # 漏斗图
from pyecharts.charts import Gauge # 仪表盘
from pyecharts.charts import Liquid # 水球图
from pyecharts.charts import WordCloud # 词云图
from pyecharts.charts import TreeMap # 矩形树图
from pyecharts.charts import Sunburst # 旭日图
from pyecharts.charts import Timeline # 时间线轮播(容器)
from pyecharts import options as opts # 全局配置项模块(标题、图例、工具箱、提示框等)
# opts 是最关键的模块,几乎所有图表属性都通过 opts.XXXOpts 类来配置

Pyecharts 的特点

特点说明对比 matplotlib/Seaborn
① 交互式输出 HTML,支持鼠标悬停查看数值、缩放、拖拽、图例点击过滤matplotlib 生成静态图片,无交互
② 图表类型丰富覆盖 30+ 种图表类型,包括地图、桑基图、仪表盘、3D 图等matplotlib 偏基础统计图,地图/桑基图需额外库
③ 链式调用.add_xaxis().add_yaxis().set_global_opts() 流式 API 链式配置matplotlib 是函数调用式,每个属性单独设置
④ 配置项体系全局配置 set_global_opts() + 系列配置 set_series_opts(),分层清晰matplotlib 所有属性都在 ax 上调,层级扁平
⑤ 网页嵌入生成的 HTML 可在浏览器中独立运行,也可嵌入 Flask/Django/Jupytermatplotlib 图片需嵌入 <img> 标签

7.2 生成图表的主要步骤#

Pyecharts 的图表创建遵循五步流程:初始化图表 → 添加数据 → 设置全局配置 → 设置系列配置 → 渲染输出。 所有图表类型共享相同的配置模式,学会一个就等于学会全部。

from pyecharts.charts import Bar
from pyecharts import options as opts
# ===== 第1步:初始化图表对象 =====
bar = Bar() # 创建柱状图实例(无参数,或传入 init_opts 设定宽高/主题)
# 也可在初始化时指定画布大小和主题:
bar = Bar(init_opts=opts.InitOpts(
width='900px', # 画布宽度(支持 px / %)
height='500px', # 画布高度
theme='light', # 内置主题:'light','dark','white','chalk','essos'等
# 更多主题需安装:pip install pyecharts-snapshot
))
# ===== 第2步:添加数据 =====
bar.add_xaxis(['苹果', '香蕉', '橙子', '葡萄', '西瓜'])
# 设置 x 轴类别标签(所有系列共享同一 x 轴)
bar.add_yaxis('2024年销量', [120, 200, 150, 80, 70])
# 添加一个系列:series_name='2024年销量',数据列表与 x 轴一一对应
# 可多次调用 add_yaxis 添加多个系列,实现分组对比
bar.add_yaxis('2025年销量', [150, 220, 180, 90, 85])
# 第二个系列:自动并排显示
# ===== 第3步:设置全局配置(标题、图例、工具箱、提示框、坐标轴等) =====
bar.set_global_opts(
title_opts=opts.TitleOpts(
title='水果销量对比', # 主标题文字
subtitle='2024 vs 2025', # 副标题
pos_left='center', # 标题水平位置:'center' / 'left' / 'right' / 百分比
),
legend_opts=opts.LegendOpts(
pos_top='8%', # 图例距顶部的距离
orient='horizontal', # 横向排列('vertical' 纵向)
),
toolbox_opts=opts.ToolboxOpts(
is_show=True, # 显示右上角工具箱(下载图片、数据视图、缩放等)
feature={
'saveAsImage': {}, # 启用"保存为图片"按钮
'dataView': {'readOnly': False}, # 启用"数据视图"按钮(可编辑)
'restore': {}, # 启用"还原"按钮
'dataZoom': {}, # 启用"区域缩放"按钮
},
),
tooltip_opts=opts.TooltipOpts(
trigger='axis', # 触发方式:'axis'(坐标轴触发,显示所有系列) / 'item'(数据项触发)
axis_pointer_type='shadow', # 指示器类型:'line','shadow','cross'
),
xaxis_opts=opts.AxisOpts(
name='水果种类', # x 轴名称
axislabel_opts=opts.LabelOpts(rotate=30),# x 轴标签旋转30°
),
yaxis_opts=opts.AxisOpts(
name='销量(吨)', # y 轴名称
splitline_opts=opts.SplitLineOpts(is_show=True), # 显示水平分割线
),
)
# ===== 第4步:设置系列配置(标签、标记点、颜色等——作用于数据系列层面) =====
bar.set_series_opts(
label_opts=opts.LabelOpts(
is_show=True, # 在柱顶显示数值标签
position='top', # 标签位置:'top','inside','bottom'
font_size=12,
),
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_='max', name='最大值'), # 标记最大值点
opts.MarkPointItem(type_='min', name='最小值'), # 标记最小值点
],
),
markline_opts=opts.MarkLineOpts(
data=[
opts.MarkLineItem(type_='average', name='平均值'), # 标记平均值线
],
),
)
# ===== 第5步:渲染输出 =====
bar.render('bar_chart.html') # 生成独立 HTML 文件,浏览器打开即可查看交互图表
# 在 Jupyter Notebook 中可直接用 bar.render_notebook() 内嵌显示
# bar 对象本身在 Jupyter 中也会自动渲染

五步流程总结

① Bar() / Line() / Pie() ...
② .add_xaxis() + .add_yaxis()
③ .set_global_opts() ← 标题/图例/工具箱/提示框/坐标轴(跨系列共用)
④ .set_series_opts() ← 标签/标记点/标记线(按系列设置)
⑤ .render('output.html')

7.3 可生成的图表类型#

Pyecharts 继承 ECharts 的全部图表能力,分为以下几大类。

一类:基础统计图(与 matplotlib/Seaborn 重叠,但交互式)#

from pyecharts.charts import Bar, Line, Pie, Scatter, Boxplot, HeatMap
# ===== 柱状图 =====
bar = Bar()
bar.add_xaxis(['Q1', 'Q2', 'Q3', 'Q4'])
bar.add_yaxis('营收', [120, 200, 150, 180])
bar.set_global_opts(title_opts=opts.TitleOpts(title='柱状图'))
# 支持:普通柱状图、堆叠柱状图(stack_='stack1')、条形图(.reversal_axis())
# ===== 折线图(自带平滑和面积填充) =====
line = Line()
line.add_xaxis(['1月', '2月', '3月', '4月', '5月'])
line.add_yaxis('温度', [5, 12, 18, 25, 30], is_smooth=True, areastyle_opts=opts.AreaStyleOpts(opacity=0.3))
# is_smooth=True:贝塞尔曲线平滑;areastyle_opts 填充折线下方区域成为面积图
# ===== 饼图/环形图 =====
pie = Pie()
pie.add('品类占比', [list(z) for z in zip(['A','B','C','D'], [335, 310, 234, 135])],
radius=['40%', '75%']) # 内半径40%、外半径75% → 环形图;radius='70%' → 普通饼图
# 数据格式必须是 [(key1, val1), (key2, val2), ...]
# ===== 散点图(支持视觉映射 visualmap) =====
scatter = Scatter()
scatter.add_xaxis([10, 20, 30, 40, 50])
scatter.add_yaxis('系列A', [5, 20, 36, 10, 75], symbol_size=20)
scatter.set_global_opts(
visualmap_opts=opts.VisualMapOpts(max_=100), # 视觉映射组件,类似 matplotlib 的 colorbar
)
# ===== 箱线图 =====
box = Boxplot()
box.add_xaxis(['对照组', '实验组'])
box.add_yaxis('', box.prepare_data([[10,20,30,40,50,60], [15,25,35,45,55,65]]))
# 注意:数据需用 .prepare_data() 预处理
# ===== 热力图 =====
heat = HeatMap()
heat.add_xaxis(['周一','周二','周三','周四','周五'])
heat.add_yaxis('上午', [0,1,2,3,4],
[[i, j, np.random.randint(0, 100)] for i in range(5) for j in range(5)])
# 数据格式必须是 [[x_idx, y_idx, value], ...]

二类:地理可视化(Pyecharts 最大亮点之一)#

from pyecharts.charts import Map, Geo
# ===== 中国地图(内置中国省级/市级地理数据) =====
map_chart = Map()
map_chart.add('确诊人数',
[['广东', 1200], ['浙江', 1100], ['河南', 980], ['四川', 850], ['北京', 600]],
maptype='china') # maptype='china' 中国地图;也可填省份名如 '广东'
map_chart.set_global_opts(
title_opts=opts.TitleOpts(title='中国疫情地图'),
visualmap_opts=opts.VisualMapOpts(
max_=1500, # 颜色映射的最大值
is_piecewise=True, # 分段型视觉映射(离散色块)
pieces=[
{'min': 1000, 'label': '>1000', 'color': '#B40404'},
{'min': 500, 'max': 999, 'label': '500-999', 'color': '#E41A1C'},
{'min': 100, 'max': 499, 'label': '100-499', 'color': '#FC8D59'},
{'min': 0, 'max': 99, 'label': '<100', 'color': '#FEE5D9'},
],
),
)
# ===== Geo 地理坐标系(散点+涟漪效果在地图上) =====
geo = Geo()
geo.add_schema(maptype='china') # 加载中国地图底图
geo.add('城市分布',
[('北京', 120), ('上海', 110), ('广州', 90), ('深圳', 85), ('杭州', 70)],
type_='effectScatter', # 涟漪散点效果
symbol_size=15,
)
geo.set_global_opts(
title_opts=opts.TitleOpts(title='Geo 地理散点'),
visualmap_opts=opts.VisualMapOpts(is_show=False), # 不显示视觉映射条
)
# type_ 可选:'scatter'(散点), 'effectScatter'(涟漪), 'heatmap'(热力)

三类:关系与流程类#

from pyecharts.charts import Graph, Sankey, TreeMap, Sunburst
# ===== 关系图/网络图 =====
graph = Graph()
graph.add('人物关系',
nodes=[{'name': 'A', 'symbolSize': 50}, {'name': 'B', 'symbolSize': 30},
{'name': 'C', 'symbolSize': 40}],
links=[{'source': 'A', 'target': 'B'}, {'source': 'A', 'target': 'C'},
{'source': 'B', 'target': 'C'}],
layout='force', # 力引导布局('circular' 环形布局)
repulsion=8000, # 节点斥力(力布局参数)
)
# ===== 桑基图(流向图) =====
sankey = Sankey()
sankey.add('能量流向',
nodes=[{'name': '煤炭'}, {'name': '发电'}, {'name': '居民用电'},
{'name': '工业用电'}, {'name': '损耗'}],
links=[{'source': '煤炭', 'target': '发电', 'value': 100},
{'source': '发电', 'target': '居民用电', 'value': 40},
{'source': '发电', 'target': '工业用电', 'value': 50},
{'source': '发电', 'target': '损耗', 'value': 10}],
linestyle_opt=opts.LineStyleOpts(opacity=0.5, curve=0.5),
)
# ===== 矩形树图(层级占比) =====
treemap = TreeMap()
treemap.add('市场份额',
[{'value': 40, 'name': '品牌A'},
{'value': 30, 'name': '品牌B'},
{'value': 20, 'name': '品牌C'},
{'value': 10, 'name': '其他'}],
)
# ===== 旭日图(多层级的饼图) =====
sunburst = Sunburst()
sunburst.add('部门结构',
[{'name': 'CEO', 'children': [
{'name': '技术部', 'children': [
{'name': '前端', 'value': 20},
{'name': '后端', 'value': 30}]},
{'name': '市场部', 'value': 50}]}],
)

四类:特殊图表#

from pyecharts.charts import Gauge, Liquid, WordCloud, Radar, Timeline
# ===== 仪表盘 =====
gauge = Gauge()
gauge.add('完成率', [('完成率', 78.5)],
min_=0, max_=100,
detail_label_opts=opts.LabelOpts(formatter='{value}%'))
# 适合 KPI 看板
# ===== 水球图(进度球) =====
liquid = Liquid()
liquid.add('完成度', [0.68, 0.55], # 多圈叠加(可从外到内显示多圈)
shape='circle') # 'circle','diamond','rect','roundRect','triangle'
# 适合展示百分比指标
# ===== 词云图 =====
wordcloud = WordCloud()
wordcloud.add('关键词',
[('数据可视化', 100), ('Python', 80), ('matplotlib', 60),
('Seaborn', 50), ('Pyecharts', 70)],
shape='circle', # 词云形状:'circle','cardioid','diamond','triangle'
word_size_range=[20, 100], # 字号范围
)
# ===== 雷达图 =====
radar = Radar()
radar.add_schema(schema=[
opts.RadarIndicatorItem(name='速度', max_=100),
opts.RadarIndicatorItem(name='力量', max_=100),
opts.RadarIndicatorItem(name='技巧', max_=100),
opts.RadarIndicatorItem(name='防守', max_=100),
opts.RadarIndicatorItem(name='体能', max_=100),
])
radar.add('球员A', [[85, 70, 90, 60, 80]]) # 数据需两层列表
radar.add('球员B', [[70, 90, 65, 85, 75]])
# ===== 时间线轮播(将多个图表串联成动画) =====
timeline = Timeline()
for year in ['2020', '2021', '2022', '2023']:
bar = Bar()
bar.add_xaxis(['A', 'B', 'C'])
bar.add_yaxis(year, [np.random.randint(100) for _ in range(3)])
timeline.add(bar, year) # 每年一个图表帧
timeline.add_schema(is_auto_play=True, play_interval=1500) # 自动播放,每帧1.5秒
# Timeline 是一个容器,可以将任何图表作为帧放入

7.4 Pyecharts 图表类型速查总表#

分类图表导入路径典型场景
基础柱状图from pyecharts.charts import Bar类别对比
基础折线图from pyecharts.charts import Line趋势变化
基础饼图/环形图from pyecharts.charts import Pie占比分布
基础散点图from pyecharts.charts import Scatter相关性
基础箱线图from pyecharts.charts import Boxplot分布对比
基础热力图from pyecharts.charts import HeatMap矩阵数据
地理地图from pyecharts.charts import Map区域数据
地理地理坐标系from pyecharts.charts import Geo地理散点
关系关系图from pyecharts.charts import Graph网络拓扑
关系桑基图from pyecharts.charts import Sankey流量流向
关系漏斗图from pyecharts.charts import Funnel转化率
层级矩形树图from pyecharts.charts import TreeMap层级占比
层级旭日图from pyecharts.charts import Sunburst多层饼图
特殊仪表盘from pyecharts.charts import GaugeKPI 指标
特殊水球图from pyecharts.charts import Liquid进度百分比
特殊词云图from pyecharts.charts import WordCloud文本权重
特殊雷达图from pyecharts.charts import Radar多维对比
容器时间线轮播from pyecharts.charts import Timeline动态播放

7.5 Pyecharts vs Matplotlib/Seaborn 对比#

维度PyechartsMatplotlib/Seaborn
输出格式HTML(交互式)PNG/SVG/PDF(静态)
交互性悬停、缩放、拖拽、图例筛选无(除非用 %matplotlib widget)
学习曲线中等(需理解 opts 配置体系)中等(需理解 figure/axes 对象)
图表类型30+ 种,含地图/桑基/仪表等基础统计图为主
中文支持原生完美支持需额外配置字体
网页嵌入天然适配,一个 HTML 搞定需先保存图片再嵌入
论文/出版不支持(无法导出矢量图)完美支持(PDF/SVG 矢量输出)
适用场景Web 看板、数据分析报告、交互仪表盘学术论文、出版物、静态报告

八、收尾区#

plt.tight_layout(pad=1.5, h_pad=1.0, w_pad=1.0)
# 【子图】自动调整子图间距和边距;pad 控制 Figure 边缘与子图间的距离(英寸)
# h_pad/w_pad 控制子图之间的垂直/水平间距
plt.savefig('out.png', dpi=300, bbox_inches='tight', facecolor='white', transparent=False)
# dpi=300:输出分辨率300 DPI(出版级),图片像素 = figsize × dpi
# bbox_inches='tight':自动裁剪多余的空白边缘,让图片内容紧凑(最常用)
# bbox_inches=None 则保留完整画布(含白边);也可手动指定 bbox_inches=(-0.5,-0.5,8.5,5.5)
# facecolor='white':图片背景色设为白色;transparent=True 则背景透明(适合叠加到海报/网页)
plt.show()
# 显示所有已创建的 Figure;在 Jupyter 中通常自动显示,脚本中必须显式调用

九、模板#

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# ===== 1. 全局配置 =====
plt.rcParams['font.sans-serif'] = ['SimHei'] # 【字体配置】全局中文字体
plt.rcParams['axes.unicode_minus'] = False # 【字体配置】负号正常显示
plt.rcParams['figure.dpi'] = 100 # 全局分辨率
# ===== 2. 数据 =====
np.random.seed(42)
x = np.arange(10)
y1 = np.random.rand(10) * 100
y2 = np.random.rand(10) * 100
z_color = np.random.rand(10) # 用于 cmap 映射的第三维数据
z_size = np.random.rand(10) * 500 # 用于气泡大小的第三维数据
# ===== 3. 画布与子图 =====
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 10))
# 【子图】创建2行2列共4个子图,axes[0,0]~axes[1,1]
# ===== 4. 子图1:折线图(演示刻度配置) =====
ax1 = axes[0, 0]
ax1.plot(x, y1, color='#3A86FF', marker='o', linewidth=2, label='系列A')
ax1.set_xlabel('时间', fontsize=12) # 【刻度配置】x轴标签
ax1.set_ylabel('数值', fontsize=12) # 【刻度配置】y轴标签
ax1.set_title('折线图示例', fontsize=14, fontweight='bold')
ax1.set_xticks(x) # 【刻度配置】每个数据点都有刻度
ax1.set_xticklabels([f'第{i}天' for i in range(10)], rotation=45)
# 【刻度配置】自定义中文刻度标签+旋转45°防止重叠
ax1.tick_params(axis='both', labelsize=9) # 【刻度配置】统一调整刻度字号
ax1.spines['top'].set_visible(False) # 去顶边框
ax1.spines['right'].set_visible(False) # 去右边框
ax1.legend(loc='best', frameon=False)
ax1.grid(True, linestyle='--', alpha=0.3)
# ===== 5. 子图2:柱状图(演示字体配置) =====
ax2 = axes[0, 1]
bars = ax2.bar(x, y2, color='#FF6B6B', width=0.6, edgecolor='white')
ax2.set_title('柱状图 - 中文字体测试', fontsize=14) # 【字体配置】标题用 SimHei 中文显示
ax2.set_xlabel('类别', fontsize=12) # 【字体配置】轴标签中文显示
ax2.set_ylabel('销售额(万元)', fontsize=12) # 【字体配置】y轴标签含中文+特殊符号
ax2.spines['top'].set_visible(False)
ax2.spines['right'].set_visible(False)
# 在柱顶加数值标签
for bar in bars:
height = bar.get_height()
ax2.text(bar.get_x() + bar.get_width()/2., height + 1,
f'{height:.1f}', ha='center', va='bottom', fontsize=9)
# 【字体配置】ax.text 的 fontsize 控制标注文字大小
# ===== 6. 子图3:气泡图(演示 cmap 使用) =====
ax3 = axes[1, 0]
sc = ax3.scatter(x, y1, c=z_color, s=z_size, cmap='viridis', alpha=0.7, edgecolors='gray', linewidth=0.5)
# 【cmap】c=z_color:z_color 数组的每个值通过 cmap='viridis' 映射为颜色
# 【cmap】s=z_size:z_size 控制每个气泡的大小,实现"大小+颜色"双通道第三维编码
ax3.set_title('气泡图 - cmap 演示', fontsize=14)
ax3.set_xlabel('X 轴')
ax3.set_ylabel('Y 轴')
cbar = plt.colorbar(sc, ax=ax3, label='颜色强度', shrink=0.85)
# 【cmap】colorbar 将数值→颜色的映射关系可视化,shrink 缩小高度避免超出
cbar.ax.tick_params(labelsize=8)
# ===== 7. 子图4:热力图(演示 cmap 双向映射) =====
ax4 = axes[1, 1]
corr = np.corrcoef(np.random.randn(5, 100)) # 5×5 相关系数矩阵(-1到1)
sns.heatmap(corr, annot=True, fmt='.2f', cmap='coolwarm',
vmin=-1, vmax=1, square=True, linewidths=0.5,
cbar_kws={'shrink': 0.8, 'label': '相关系数'}, ax=ax4)
# 【cmap】cmap='coolwarm':蓝(-1)→白(0)→红(+1),正向暖色负向冷色,相关系数可视化的黄金选择
# 【cmap】vmin=-1, vmax=1:锁定 cmap 映射范围,确保0始终映射到白色
ax4.set_title('相关系数热力图', fontsize=14)
# ===== 8. 收尾 =====
plt.tight_layout(pad=2.0) # 【子图】统一调整所有子图间距
plt.savefig('demo.png', dpi=300, bbox_inches='tight')
plt.show()

分享到社交平台

将本文分享给你的朋友们

2026-06-14-数据可视化 Vol.3 可视化库
https://zhongye1.github.io/posts/数据可视化/2026-06-15-数据可视化-可视化库/
作者
Zhongye
发布于
2026-06-15
版权声明
CC BY-NC-SA 4.0

评论

Profile Image of the Author
Zhongye
南漂中
公告
新的博客站!旧站点传送门 👇
音乐
专辑封面

音乐

暂无播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章数
144
分类数
14
标签数
205
总字数
433,478
运行天数
0
最后更新
0 天前
总访问量
42296
访客数
29212

目录