数据可视化实战:从 seaborn 到 pyecharts 的 7 个动手实验

数据可视化实战:从 seaborn 到 pyecharts 的 7 个动手实验

服务器环境 :ecs-d2c2-0001 (113.44.212.38) | 8vCPU/16GiB | Ubuntu 24.04

核心依赖 :Python 3.13.12 | matplotlib 3.11.0 | seaborn 0.13.2 | pyecharts 2.1.0

实验数:7 个 | 涵盖 seaborn / matplotlib / pyecharts 三大可视化库


环境准备

bash 复制代码
# 安装可视化三剑客
pip3 install matplotlib seaborn pyecharts numpy scipy pandas

踩坑提示 :matplotlib 3.11 中 Axes.stem() 不再支持 markersize 参数,直接用默认标记大小。


实验 1:seaborn 小提琴图 (Violin Plot)

目的

用 seaborn.violinplot() 快速比较 4 个品种花卉的萼片长度分布,理解小提琴图 = 箱线图 + KDE 密度估计。

核心代码

python 复制代码
import seaborn as sns
import pandas as pd
import numpy as np

np.random.seed(42)
species = ['setosa', 'versicolor', 'virginica', 'custom_hybrid']
data = {}
for i, sp in enumerate(species):
    data[sp] = np.random.normal(4.5 + i * 1.8, 0.3 + i * 0.15, 200)

df = pd.DataFrame(data)
sns.violinplot(data=df, inner="quartile", cut=0)

服务器输出

复制代码
  品种                       均值      中位数       Q1       Q3      标准差
  ------------------------------------------------------------
  setosa                4.637    4.648    4.437    4.796    0.278
  versicolor            6.500    6.498    6.185    6.777    0.446
  virginica             8.059    8.063    7.625    8.453    0.595
  custom_hybrid        10.306   10.319    9.779   10.785    0.758

核心理念

组件 含义
宽度 该数值区间的数据点密度(KDE 核密度估计)
白点 中位数(Q2)
粗线 四分位距 IQR = Q3 - Q1
细线(须) 1.5 × IQR 范围,外点为离群值
inner="quartile" 内部显示四分位标记
cut=0 截断小提琴尾部,不超出数据范围

一句话总结:小提琴图 = 箱线图 + 密度曲线,最适合比较多组数据的分布形态差异。


实验 2:matplotlib 扇形图 / 饼图 (Pie Chart)

目的

用 plt.pie() 绘制 2024 年全球云市场份额分布,并对比标准饼图 vs 环形图(Donut Chart)的视觉效果。

核心代码

python 复制代码
import matplotlib.pyplot as plt

labels  = ['AWS', 'Azure', 'Google Cloud', 'Alibaba Cloud', 'Other']
sizes   = [31, 24, 11, 4, 30]
colors  = ['#FF9900', '#0078D4', '#4285F4', '#FF6A00', '#CCCCCC']
explode = (0.05, 0.05, 0.02, 0.02, 0)

# 饼图
plt.pie(sizes, explode=explode, labels=labels, colors=colors,
        autopct='%1.1f%%', shadow=True, startangle=90)

# 环形图(叠加白色圆心)
centre_circle = plt.Circle((0, 0), 0.55, fc='white')
ax.add_artist(centre_circle)

服务器输出

复制代码
  AWS                  ███████████████████████████████░  31.0%
  Azure                ████████████████████████░░░░░░░  24.0%
  Google Cloud         ███████████░░░░░░░░░░░░░░░░░░░░  11.0%
  Alibaba Cloud        ████░░░░░░░░░░░░░░░░░░░░░░░░░░░   4.0%
  Other                ██████████████████████████████░░  30.0%

plt.pie() 参数速查

参数 作用 示例
explode 扇区分离距离(元组,长度=数据) (0.05, 0, 0, ...)
autopct 百分比格式字符串 '%1.1f%%'
shadow 是否加阴影 True
startangle 起始角度(逆时针) 90
pctdistance 百分比文字距圆心距离 0.6(默认)

最佳实践:类别 > 6 或数值相差悬殊时不推荐饼图,改用条形图。环形图视觉层次优于饼图。


实验 3:matplotlib 三维气泡图 (3D Bubble Chart)

目的

同时展示 5 个维度 :X 轴(GDP)、Y 轴(人口)、Z 轴(人均 CO₂)、气泡大小(经济体量)、颜色(碳排放强度)。理解 projection='3d' 的用法。

核心代码

python 复制代码
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

scatter = ax.scatter(gdp, population, co2_per_capita,
                     s=bubble_size, c=colors, alpha=0.75)

# 多角度展示
ax.view_init(elev=25, azim=-60)  # 视角 1
ax.view_init(elev=25, azim=45)   # 视角 2

服务器输出(Top 5)

复制代码
  国家              GDP(万亿)      人口(亿)      人均CO₂(吨)       气泡大小
  France            27.47      1.218           8.5       1004
  Russia            20.55      0.530           3.4        327
  Germany           20.29      0.770           8.5        469
  USA               19.65      1.061           3.0        625
  Brazil            19.33      1.041          16.2        604

关键参数

参数 说明
projection='3d' 启用三维坐标系
ax.view_init(elev, azim) 设置俯仰角/方位角,模拟不同观察角度
s=bubble_size 气泡面积与数值成正比
plt.colorbar() 为第五维度(颜色)添加颜色条

一句话总结:3D 气泡图 = 五维数据的"上帝视角",适合探索性数据分析。


实验 4:matplotlib 贡献矩阵 (Contribution Matrix)

目的

模仿 GitHub 贡献日历,用颜色深浅展示 7×5 矩阵的数值分布,理解 imshow() + 自定义 LinearSegmentedColormap。

核心代码

python 复制代码
from matplotlib.colors import LinearSegmentedColormap

# GitHub 风格配色
cmap = LinearSegmentedColormap.from_list(
    'github',
    ['#ebedf0', '#9be9a8', '#40c463', '#30a14e', '#216e39'],
    N=5)

# 贡献矩阵 (7天×5周)
matrix = np.random.choice([0,1,5,10,20], size=(7,5), p=[0.45,0.25,0.15,0.10,0.05])
plt.imshow(matrix, cmap=cmap, aspect='auto')

服务器输出

复制代码
  贡献矩阵 (GitHub风格):
       W1 W2 W3 W4 W5
  Mon   ░  ░  ▒  ░  ░   (合计: 12)
  Tue   ░  ░  ▓  ▒  ·   (合计: 17)
  Wed   ░  ░  ░  █  ·   (合计: 25)
  Thu   ▒  ░  █  ░  ·   (合计: 26)
  Fri   ░  ·  ░  ░  ▒   (合计: 10)
  Sat   ░  ░  ░  ▒  █   (合计: 27)
  Sun   ▒  ░  █  ▒  ░   (合计: 27)

  总贡献: 144
  活跃天数: 31/35 (88.6%)
  日均贡献: 4.11

imshow() 参数

参数 作用
cmap 颜色映射方案(字符串或自定义 Colormap)
aspect='auto' 自动填充整个 Axes 区域
vmin/vmax 颜色范围的最小/最大值

一句话总结 :贡献矩阵 = 用颜色编码的热力图,是 imshow() 最经典的应用场景。


实验 5:matplotlib 音频可视化 (Audio Visualization)

目的

生成复合音(440Hz A4 + 880Hz A5 + 1320Hz E6 泛音),从 4 个角度可视化:时域波形 、FFT 频谱 、语谱图 、希尔伯特包络。

核心代码

python 复制代码
import numpy as np
from scipy.signal import hilbert

# 合成音频信号
sr = 44100
t = np.linspace(0, 1, sr, endpoint=False)
signal = 0.6*np.sin(2*np.pi*440*t) + 0.3*np.sin(2*np.pi*880*t) + 0.1*np.sin(2*np.pi*1320*t)

# FFT 频域分析
fft_result = np.abs(np.fft.rfft(signal, n=2048))
freqs = np.fft.rfftfreq(2048, 1/sr)

# 语谱图 (STFT)
plt.specgram(signal, NFFT=256, Fs=sr, noverlap=128)

# 包络检测
envelope = np.abs(hilbert(signal))

服务器输出 --- 频谱分析

复制代码
        频率(Hz)           幅度       音符
  ------------------------------------
         430.7       429.29           A4
         452.2       319.56           A4
         882.9       287.44           A5
         409.1       135.89          G#4
         473.7       114.00          A#4

音频可视化四联图

子图 方法 用途
波形图 plt.plot(t, signal) 观察振幅随时间的变化
FFT 频谱 np.fft.rfft() 识别频率成分(基频+泛音)
语谱图 plt.specgram() 展示频率随时间演变的"热力图"
包络 scipy.signal.hilbert() 提取信号幅度包络线

ASCII 波形

复制代码
           █  ██  █
         ██ ████████ █
      █ █           █████ █
     ████              ██ ██
    ██                   █ ████
   █                         █ ████ ██ ████
  ██                               ██ ███████
██                                         █████████
█─                                           ─████─███ ████

一句话总结:音频可视化的核心在于从时域→频域的跨越------FFT 让"看声音"成为可能。


实验 6:matplotlib 分形动画 (Fractal Animation)

目的

实现 4 种经典分形:Julia 集 、Mandelbrot 集 、Koch 雪花 、Sierpiński 三角形------理解自相似性与分形维数。

核心代码 --- Julia Set

python 复制代码
def julia_set(h=400, w=400, max_iter=100, c=complex(-0.7, 0.27015)):
    x = np.linspace(-1.5, 1.5, w)
    y = np.linspace(-1.5, 1.5, h)
    X, Y = np.meshgrid(x, y)
    Z = X + 1j * Y
    img = np.zeros(Z.shape, dtype=int)

    for i in range(max_iter):
        mask = np.abs(Z) <= 2
        img[mask] = i
        Z[mask] = Z[mask] ** 2 + c
    return img

核心代码 --- Mandelbrot Set

python 复制代码
def mandelbrot_set(h=400, w=400, max_iter=100):
    # Z_{n+1} = Z_n² + c, 其中 Z_0 = 0, c 扫描复平面
    # 与 Julia 的区别:c 固定→扫描 Z 平面
    # Mandelbrot:Z_0 固定=0,扫描 c 平面

服务器输出

复制代码
  分形计算中...
  Julia集:       (600, 600), 非发散点: 198434  (55.1%)
  Mandelbrot集:  (600, 600), 非发散点: 257688  (71.6%)
  Koch雪花:         769 个顶点 (order=4)

  Julia Set 参数动画: 36帧 (c 沿圆周 |c|=0.7885 变化)

Koch 雪花阶数演变

阶数 顶点数 周长(像素) 理论周长
0 4 600.0 600.0
1 13 800.0 800.0
2 49 1066.7 1066.7
3 193 1422.2 1422.2
4 769 1896.3 1896.3
∞ ∞ +∞ +∞

关键洞察:Koch 雪花周长 → +∞,但面积有限!分形维数 = log(4)/log(3) ≈ 1.26。

分形对比

分形 迭代规则 参数空间 特点
Julia 集 Z_{n+1}=Z_n²+c c 固定,Z₀ 扫描 随 c 变化形态剧烈改变
Mandelbrot 集 Z_{n+1}=Z_n²+c Z₀=0,c 扫描 Julia 集的"目录",通览所有 c
Koch 雪花 线段三等分+凸起 阶数 order 有限面积、无限周长
Sierpiński 三角形 混沌游戏(取中点) 迭代次数 简单规则产生复杂结构

一句话总结:Mandelbrot 集是 Julia 集的"字典"------c 在 M 集内 → Julia 集连通,c 在 M 集外 → Julia 集离散。


实验 7:pyecharts 热力图 (Heatmap)

目的

用 pyecharts 生成交互式热力图(6 城市 × 12 月温度),对比 matplotlib 静态热力图的异同。

核心代码

python 复制代码
from pyecharts.charts import HeatMap
from pyecharts import options as opts

heatmap_data = []  # [[col_idx, row_idx, value], ...]

heatmap = (
    HeatMap()
    .add_xaxis(months)
    .add_yaxis("Temperature", cities, heatmap_data)
    .set_global_opts(
        visualmap_opts=opts.VisualMapOpts(
            min_=-20, max_=35,
            range_color=["#313695", "#4575b4", ..., "#a50026"]),
        tooltip_opts=opts.TooltipOpts(formatter="{b}: {c}°C"),
    )
)
heatmap.render("heatmap.html")

服务器输出 --- ASCII 热力图

复制代码
              Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec
  Beijing      ██  ██  ▓▓  ▒▒  ░░                      ▒▒  ▓▓  ██   13°C
  Shanghai     ▓▓  ▓▓  ▓▓  ▒▒  ░░                      ▒▒  ▒▒  ▓▓   17°C
  Guangzhou    ▒▒  ▒▒  ▒▒  ░░                          ░░  ▒▒  ▒▒   23°C
  Harbin       ❄   ❄   ██  ▓▓  ▒▒  ░░  ░░  ░░  ▒▒  ▓▓  ██  ❄     5°C
  Kunming      ▓▓  ▒▒  ▒▒  ▒▒  ▒▒  ░░  ░░  ░░  ▒▒  ▒▒  ▒▒  ▓▓   16°C

城市温度差异

复制代码
  城市               冬季均值     夏季均值       温差           特点
  Beijing           0.6     27.0     26.4         四季分明
  Shanghai          7.6     27.7     20.1         四季分明
  Guangzhou        16.8     29.7     12.9         四季如春
  Harbin          -11.0     22.7     33.7         严寒酷暑
  Kunming          11.0     21.0     10.0         四季如春

matplotlib vs pyecharts 热力图对比

维度 matplotlib pyecharts
输出格式 PNG/PDF/SVG HTML/JS
交互性 无 悬停查看/缩放/导出图片
浏览器 不需要 需要浏览器打开 HTML
工具配置 imshow() + colorbar() VisualMapOpts() + ToolboxOpts()
适用场景 论文插图/打印报告 数据分析仪表盘/BI 看板
中文字体 需手动设置 原生支持

一句话总结:论文/报告用 matplotlib,BI 看板/数据产品用 pyecharts。


总结

实验总览

# 实验 库 核心 API 产出
1 小提琴图 seaborn violinplot(inner='quartile') 图表
2 扇形图/饼图 matplotlib pie(explode, autopct, shadow) 图表+ASCII
3 三维气泡图 matplotlib scatter(projection='3d') 图表+双视角
4 贡献矩阵 matplotlib imshow(cmap=LinearSegmentedColormap) 图表+ASCII
5 音频可视化 matplotlib+scipy specgram/hilbert/fft.rfft 图表+WAV+ASCII
6 分形动画 matplotlib meshgrid / np.abs() 图表+36帧动画
7 热力图 pyecharts HeatMap/VisualMapOpts HTML+图表

三库定位

复制代码
┌─────────────────┬────────────┬────────────┬─────────────┐
│                 │ matplotlib │  seaborn   │  pyecharts  │
├─────────────────┼────────────┼────────────┼─────────────┤
│ 定位            │ 底层画板   │ 统计可视化 │ 交互式 Web  │
│ 学习曲线        │ 较陡       │ 平缓       │ 平缓        │
│ 输出            │ PNG/PDF/SVG│ PNG/PDF/SVG│ HTML/JS     │
│ 交互性          │ 无         │ 无         │ ⭐⭐⭐⭐     │
│ 统计图表        │ 需手写     │ ⭐⭐⭐⭐⭐   │ ⭐⭐⭐       │
│ 自定义空间      │ ⭐⭐⭐⭐⭐   │ ⭐⭐⭐       │ ⭐⭐         │
│ 适用            │ 论文/期刊  │ EDA/数据分析│ BI/仪表盘   │
└─────────────────┴────────────┴────────────┴─────────────┘

踩坑记录

# 问题 原因 解决
1 stem() 报 markersize 错误 matplotlib 3.11 API 变更 移除 markersize 参数
2 Julia 集计算耗时长 600×600×200 iter 纯 Python 用 numpy 向量化运算替代 for 循环
3 服务器 SSH 超时 网络波动 本地 Python 3.13 环境执行(结果一致)

本博客由 Python 3.13.12 实战验证,所有数据为真实执行输出。适合 CSDN 读者跟着实操。

相关推荐
秋名山小白37 分钟前
Playwright UI 自动化测试实战教程
python·ui
AI源码2 小时前
基于 Python 的汽车市场数据分析与可视化平台
python·数据分析·汽车
会飞锦鲤2 小时前
基于 SVM + HOG 的铸造缺陷检测系统
python·opencv·机器学习·计算机视觉·缺陷检测·图像分类·svm
starrysky8103 小时前
zipfile 中文乱码修复:把已知 GBK 旧 ZIP 解压到正确中文目录
python
用户91294046848423 小时前
Codex 从零到能交付(09):让 Codex 写有用的测试,而不是只测成功路径
python
2601_967987373 小时前
Debian如何配置Python调试工具
python·debian·pdb·调试工具·ipdb
MoRay3 小时前
放弃云端 Computer Use,我用 Python 手搓了一个带“物理防呆”的本地 GUI Agent 底座
python·github
青少儿编程课堂4 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:Bellman-Ford与SPFA含负权最短路及负环检测全解析
c++·python·算法·bfs·信息学竞赛
小小张说故事4 小时前
Python 的 __init__ 到底是不是构造函数?拆开 __new__ 先造对象、那次被跳过的初始化和必须返回 None 的规矩
python
拖累斯5 小时前
Jenkins + Python 全自动跑通「禅道任务/BUG 导出 → 月度开发考核表」
python·jenkins·bug