📊 Python 数据可视化知识点汇总

从 Matplotlib 基础到 Plotly 交互图表 —— 一页掌握 Python 可视化核心技能

MatplotlibSeabornPlotly Pandas PlotPyecharts图表选型

目录导航

  • 1Matplotlib 基础:架构、画布与坐标系、常用配置
  • 2常用图表:折线、柱状、散点、饼图、直方图、箱线图、热力图、子图
  • 3样式美化:颜色、图例、注释、刻度、中文字体
  • 4Seaborn:统计图表、调色板、FacetGrid、样式主题
  • 5Pandas 绘图:一行代码画图、多 DataFrame 叠加
  • 6Plotly 交互图表:交互式折线/散点/3D、Express 快速绘图
  • 7图表选型指南:什么数据用什么图
  • 8实战技巧与常见坑:中文乱码、保存 DPI、动画、大屏配色

一、Matplotlib 基础

Matplotlib 是 Python 最基础的绑图库,其他库(Seaborn、Pandas.plot)都基于它构建。

两种绘图方式

① pyplot 状态机接口:类似 MATLAB,快速上手。
② 面向对象接口(推荐):通过 fig / ax 对象操作,结构清晰,适合多子图。

核心概念

概念含义
Figure画布(整个窗口)
Axes坐标系(一张子图)
Axis坐标轴(x/y 轴对象)
Artist一切可见元素(文字、线、图例…)

基本绘图流程(面向对象方式)

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi, 100)

# 1. 创建画布与坐标系
fig, ax = plt.subplots(figsize=(8, 5), dpi=100)

# 2. 绘制数据
ax.plot(x, np.sin(x), label='sin(x)', color='tab:blue', linewidth=2, linestyle='--')
ax.plot(x, np.cos(x), label='cos(x)', color='tab:red',  linewidth=2)

# 3. 添加图表元素
ax.set_title('三角函数曲线', fontsize=14)
ax.set_xlabel('x 弧度'); ax.set_ylabel('y 值')
ax.legend(loc='upper right')        # 图例
ax.grid(True, alpha=0.3)             # 网格线
ax.set_xlim(0, 2*np.pi)              # 坐标范围

# 4. 显示 / 保存
plt.tight_layout()                    # 自动调整布局防重叠
plt.savefig('fig.png', dpi=300, bbox_inches='tight')
plt.show()

常用 rcParams 全局配置

# 解决中文乱码 + 负号显示问题(必备!)
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']  # Windows
# Mac 用 ['PingFang SC', 'Heiti TC'];Linux 可用 'WenQuanYi Micro Hei'
plt.rcParams['axes.unicode_minus'] = False

plt.rcParams['figure.dpi'] = 100        # 全局分辨率
plt.rcParams['font.size'] = 11          # 全局字号
plt.rcParams['axes.grid'] = True        # 默认显示网格
提示:查看系统可用中文字体:[f.name for f in plt.font_manager.fontManager.ttflist]

二、常用图表类型

Matplotlib 八大常用图表速查,含关键参数。

📈 折线图 plot()

ax.plot(x, y,
    color='red',        # 颜色
    linewidth=2,        # 线宽
    linestyle='--',     # 线型 '-' '--' '-.' ':'
    marker='o',         # 标记 o s ^ * D v
    markersize=6,
    alpha=0.8,          # 透明度
    label='图例名')

📊 柱状图 bar() / 横向 barh()

ax.bar(categories, values,
    width=0.6,           # 柱宽
    color='steelblue',
    edgecolor='black',
    hatch='//')          # 填充纹理
ax.bar_label(bars, padding=3)  # 柱顶标数值

# 分组柱状图:错开 x 位置
ax.bar(x - w/2, g1, width=w, label='A')
ax.bar(x + w/2, g2, width=w, label='B')

🔵 散点图 scatter()

sc = ax.scatter(x, y,
    s= sizes,          # 点面积(可传数组)
    c= values,         # 颜色映射值
    cmap='viridis',    # 颜色映射方案
    alpha=0.6,         # 半透明防遮挡
    edgecolors='w')
fig.colorbar(sc, label='数值')

🥧 饼图 pie()

ax.pie(values, labels=labels,
    autopct='%.1f%%',  # 显示百分比
    startangle=90,     # 起始角度
    explode=[0.1, 0, 0, 0], # 突出某块
    shadow=True,
    colors=colors)
ax.axis('equal')      # 保证是正圆

📶 直方图 hist()

ax.hist(data, bins=30,       # 分箱数
    density=True,      # 归一化为概率密度
    cumulative=True,   # 累积分布
    color='skyblue',
    edgecolor='white')

📦 箱线图 boxplot() / 小提琴图

ax.boxplot(data_list, labels=names,
    patch_artist=True,   # 填充颜色
    showmeans=True,      # 显示均值
    vert=True)
# 小提琴图(分布+密度)
ax.violinplot(data_list, showmedians=True)

🌡️ 热力图 imshow()

im = ax.imshow(corr_matrix,
    cmap='RdBu_r', vmin=-1, vmax=1)
fig.colorbar(im)
ax.set_xticks(range(n), labels, rotation=45)
ax.set_yticks(range(n), labels)
# 在格子里写数值
for i in range(n):
    for j in range(n):
        ax.text(j, i, f'{corr[i,j]:.2f}',
                ha='center', va='center')

🔲 填充图 fill_between()

# 两曲线间填充(常用于置信区间)
ax.fill_between(x, y1, y2,
    color='blue', alpha=0.2)
# 曲线下面积
ax.fill_between(x, y, 0,
    where=(y > 0),
    interpolate=True)

子图布局(重点)

# 方式1:subplots 一次创建多个坐标系(推荐)
fig, axes = plt.subplots(2, 2, figsize=(10, 8))   # 2行2列
axes[0,0].plot(x, y)       # 注意 axes 是二维数组
axes[0,1].bar(cx, cy)
axes[1,0].scatter(sx, sy)
axes[1,1].hist(h)
fig.suptitle('多子图总标题')
plt.tight_layout()

# 方式2:add_gridspec 不规则布局
fig = plt.figure(figsize=(8, 6))
gs = fig.add_gridspec(2, 3)
ax1 = fig.add_subplot(gs[0, :])   # 第一行占满3列
ax2 = fig.add_subplot(gs[1, 0])
ax3 = fig.add_subplot(gs[1, 1:])
fig.subplots_adjust(hspace=0.4, wspace=0.3)

# 方式3:共享坐标轴
fig, axes = plt.subplots(2, 1, sharex=True, sharey=False)

# 方式4:双 y 轴
ax2 = ax1.twinx()      # 共用x轴、独立y轴

三、样式美化

让图表更专业的关键配置。

常用颜色写法

# 单色
'r' 'g' 'b' 'k'              # 缩写
'tab:blue' 'tab:orange'       # 官方默认10色
'#FF5733'                      # 十六进制
'steelblue' 'crimson'          # CSS色名
(0.2, 0.4, 0.6)                # RGB元组

# 颜色循环
plt.rcParams['axes.prop_cycle'] = plt.cycler(
    color=plt.cm.Set2.colors)

常用 cmap 色图

场景推荐 cmap
顺序数据viridis / Blues / YlOrRd
发散数据(有正负)RdBu_r / coolwarm / seismic
分类数据Set2 / tab10 / Paired
注意:热力图勿用彩虹色 jet(视觉误导),推荐 viridis。

注释、图例与刻度

# 文字注释
ax.text(x, y, '文本', fontsize=10, color='gray', ha='center')

# 箭头注释(标注最大值点)
ax.annotate('最大值', xy=(xmax, ymax), xytext=(xmax, ymax+1),
    arrowprops=dict(arrowstyle='->', color='red'))

# 图例
ax.legend(loc='best', frameon=False, ncol=2, fontsize=9)
# loc: best upper/lower left/right/center

# 刻度控制
ax.tick_params(axis='x', rotation=45, labelsize=9)
ax.set_xticks([...], labels=[...])          # 自定义刻度
ax.xaxis.set_major_formatter('{x:.0f}')    # 格式化

# 数值千分位格式化
from matplotlib.ticker import FuncFormatter
ax.yaxis.set_major_formatter(
    FuncFormatter(lambda v, _: f'{v:,.0f}'))

内置风格主题

# 一行切换全局风格
plt.style.use('ggplot')
# 常用: ggplot, seaborn-v0_8, fivethirtyeight, dark_background,
#       bmh, solarized_light2, tableau-colorblind10

# 临时使用某风格
with plt.style.context('dark_background'):
    plt.plot(x, y)

# 查看所有可用风格
print(plt.style.available)

# 恢复默认
plt.rcdefaults()

四、Seaborn:统计可视化

基于 Matplotlib 的高级 API,与 DataFrame 深度集成,一行代码出统计图。

两套 API 的关系

函数级接口:sns.histplot() 等直接画图,简单快速。

对象级接口(新):sns.objects.Plot() 链式语法,更灵活。

通用参数约定

sns.xxxplot(data=df,        # DataFrame
    x='列名', y='列名',
    hue='分类列',      # 颜色分组
    size='数值列',      # 大小编码
    style='分类列',     # 标记形状
    palette='husl',     # 调色板
    ax=ax)              # 画到指定ax

核心图表速查

import seaborn as sns
df = sns.load_dataset('tips')

# ── 关系类 ──
sns.scatterplot(data=df, x='total_bill', y='tip', hue='day', ax=ax1)
sns.lineplot(data=df, x='size', y='tip', errorbar=('ci', 95), ax=ax2)
sns.regplot(data=df, x='total_bill', y='tip')          # 散点+回归线

# ── 分布类 ──
sns.histplot(data=df, x='total_bill', kde=True, hue='sex') # 直方+密度
sns.kdeplot(data=df, x='total_bill', fill=True)             # 密度曲线
sns.ecdfplot(data=df, x='total_bill')                        # 经验累积分布
sns.rugplot(data=df, x='total_bill')                         # 地毯图

# ── 分类类 ──
sns.boxplot(data=df, x='day', y='total_bill', hue='sex')    # 箱线
sns.violinplot(data=df, x='day', y='total_bill', split=True) # 小提琴
sns.stripplot(data=df, x='day', y='total_bill', jitter=True) # 散点抖动
sns.swarmplot(data=df, x='day', y='total_bill')              # 防重叠散点
sns.barplot(data=df, x='day', y='total_bill', estimator='mean') # 均值柱状+误差条
sns.countplot(data=df, x='day', hue='sex')                    # 计数柱状
sns.pointplot(data=df, x='day', y='total_bill')               # 点图(均值±CI)

# ── 矩阵类 ──
sns.heatmap(df.corr(numeric_only=True), annot=True, fmt='.2f',
    cmap='coolwarm', center=0, linewidths=0.5)          # 相关性热力图

# ── 回归类 ──
sns.lmplot(data=df, x='total_bill', y='tip', hue='smoker', col='time')

FacetGrid 分面(重点)

# 按类别拆成多个子图,同一张图逻辑
g = sns.FacetGrid(df, col='time', row='sex',
                  hue='smoker')
g.map_dataframe(sns.scatterplot,
                x='total_bill', y='tip')
g.add_legend()

# 便捷版:relplot / displot / catplot
sns.relplot(data=df, x='total_bill', y='tip',
    col='day', col_wrap=2, kind='scatter')

样式与调色板

# 全局主题: darkgrid whitegrid dark
# white ticks paper talk
sns.set_theme(style='whitegrid',
    context='notebook',  # paper notebook talk poster
    font='SimHei')

# 取消边框
sns.despine(left=True, top=True, right=True)

# 调色板
sns.color_palette('Set2')      # 分类: Set1/2, tab10, husl
sns.color_palette('Blues', 8)  # 顺序
sns.color_palette('RdBu_r')    # 发散
sns.palplot(sns.color_palette('husl'))  # 预览

五、Pandas 可视化

DataFrame 自带 .plot() 方法(底层是 Matplotlib),适合探索性分析快速出图。

import pandas as pd
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))

df.plot(kind='line')       # 折线;df.plot.line() 等价
df.plot(kind='bar')        # 柱状(多列自动分组)
df.plot(kind='barh', stacked=True)   # 堆叠条形图
df.plot(kind='hist', bins=30, alpha=0.5)  # 多列直方图叠加
df.plot(kind='box')        # 箱线图
df.plot(kind='kde')        # 核密度估计
df.plot(kind='area')       # 面积图
df.plot(kind='scatter', x='A', y='B', c='C', cmap='viridis')
df.plot(kind='hexbin', x='A', y='B', gridsize=20)  # 六边形密度图
df.plot(kind='pie', subplots=True, autopct='%.0f%%')

# 多子图 & 次坐标轴
df.plot(subplots=True, layout=(2,2), figsize=(10,6), sharex=True)
df.plot(secondary_y=['D'])          # D列用右轴

# 时间序列常用
ts.plot(figsize=(12,4), title='时序')
ts.rolling(30).mean().plot()         # 30日均线

# 单列/单值快速图
df['A'].value_counts().plot(kind='bar')
df.groupby('cat')['v'].sum().plot(kind='pie')
适用场景:Pandas.plot 胜在快,精细控制仍建议拿到 ax 后用 Matplotlib 定制:ax = df.plot(...)

六、Plotly:交互式可视化

生成的图表支持缩放、悬停提示、图例点击隐藏,可导出 HTML 网页。是数据大屏和网页报告的首选。

Plotly Express(推荐入门)

import plotly.express as px

df = px.data.gapminder()

# 折线
px.line(df, x='year', y='lifeExp',
    color='continent', line_group='country')

# 气泡散点(动画!)
px.scatter(df, x='gdpPercap', y='lifeExp',
    size='pop', color='continent',
    hover_name='country',
    log_x=True, animation_frame='year')

# 柱状 / 饼 / 箱线 / 直方
px.bar(df, x='continent', y='pop', color='continent')
px.pie(df, names='continent', values='pop', hole=0.4)
px.box(df, x='continent', y='lifeExp', points='all')
px.histogram(df, x='lifeExp', nbins=30)

# 热力图 / 3D散点
px.imshow(corr_matrix, text_auto=True)
px.scatter_3d(df, x='gdpPercap', y='pop', z='lifeExp', color='continent')

# 地图
px.choropleth(df, locations='iso_alpha', color='lifeExp',
    hover_name='country', animation_frame='year')

底层 Graph Objects(精细控制)

import plotly.graph_objects as go

fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode='lines+markers',
    name='系列A', line=dict(color='royalblue', width=2)))
fig.add_trace(go.Bar(x=cx, y=cy, name='系列B', yaxis='y2'))

fig.update_layout(
    title='标题',
    xaxis_title='X', yaxis_title='Y',
    template='plotly_dark',   # plotly / white / seaborn
    hovermode='x unified',
    legend=dict(orientation='h', y=1.05),
    yaxis2=dict(overlaying='y', side='right'))
fig.show()

# 保存为 HTML / 图片
fig.write_html('chart.html')
fig.write_image('chart.png', scale=2)  # 需 kaleido

# 在 Jupyter 中显示
fig.show()  # 自动渲染交互图

其他值得了解的库

库特点适用场景
pyecharts基于 ECharts,中文文档友好,图表华丽中文大屏、网页报表
bokeh浏览器端渲染,支持 Dash 应用交互式 Web 应用
altair声明式语法,Vega-Lite 内核快速探索、简洁语法
plotnineggplot2 语法移植熟悉 R 语言的用户
wordcloud词云生成文本关键词展示
folium / pygmt地图可视化地理数据

七、图表选型指南

选错图表 = 数据白讲。按下表对号入座。

分析目的推荐图表不推荐
看趋势(随时间变化)折线图、面积图饼图 ❌
比较类别大小柱状图、条形图3D柱状 ❌
看占比构成饼图/环形图(≤5类)、堆叠柱状图类别过多的饼图 ❌
看相关性散点图、热力图、气泡图折线图(无序数据)❌
看分布直方图、KDE、箱线图、小提琴图均值柱状图(丢信息)❌
多变量关系散点矩阵、平行坐标图、气泡图—
地理数据choropleth 地图、散点地图—
流程/层级桑基图、树状图、旭日图—
文本数据词云、条形词频图—

可视化设计原则

  • 数据墨水比:去掉一切不承载信息的元素(去边框、去网格线、去3D)
  • 颜色克制:同一图不超过 6~7 种颜色;用颜色突出重点而非装饰
  • 0 基线:柱状图必须从 0 开始,否则视觉夸大差异
  • 标注直接:重要数值直接标在图上,少让读者查坐标轴
  • 标题讲结论:用"销售额三年增长 40%"而不是"销售额柱状图"

色盲友好配色

# Matplotlib 色盲友好
plt.style.use('tableau-colorblind10')

# Seaborn 色盲友好调色板
sns.set_palette('colorblind')
# 或 'deep' / 'muted' / colorbrewer 主题

# 经典 Okabe-Ito 色板
okabe_ito = ['#E69F00', '#56B4E9',
    '#009E73', '#F0E442',
    '#0072B2', '#D55E00', '#CC79A7']

八、实战技巧与常见坑

⚠️ 常见问题速解

  • 中文乱码:设置 font.sans-serif + axes.unicode_minus=False
  • 图例乱码/缺字:字体不支持该字符,换完整中文字体
  • 柱状图 x 轴错位:用 ax.set_xticks(positions, labels) 而非传字符串给 bar
  • 保存后图被裁剪:加 bbox_inches='tight'
  • 图片模糊:dpi=300,或保存为 SVG/PDF 矢量格式
  • 标签重叠:plt.tight_layout() 或 rotation=45
  • Jupyter 不显示图:%matplotlib inline(新版本默认开启)
  • 内存累积:循环画图时用 plt.close(fig) 释放画布

🎨 高级技巧

# 1. 动画(FuncAnimation)
from matplotlib.animation import FuncAnimation
anim = FuncAnimation(fig, update, frames=100,
                     interval=50)
anim.save('a.gif', writer='pillow')

# 2. 3D 图
from mpl_toolkits.mplot3d import Axes3D
ax = fig.add_subplot(projection='3d')
ax.plot_surface(X, Y, Z, cmap='viridis')

# 3. 表格+图组合
ax.table(cellText=df.values,
         colLabels=df.columns, loc='bottom')

# 4. 水印背景图
ax.imshow(img, extent=[0,10,0,10],
          alpha=0.3, aspect='auto')

学习路线建议

阶段目标建议
入门Matplotlib 基础 + Pandas.plot能画出 8 种基本图表,理解 fig/ax
进阶Seaborn 统计图表 + 样式定制熟悉 hue/分面/调色板,出图美观
熟练Plotly 交互图 + 子图布局能做动态图表、导出 HTML 报告
精通面向对象 API 深入 + 自定义 Artist阅读官方源码,能复刻商业图表
资源:Matplotlib 官方 Gallery(matplotlib.org/stable/gallery)、Seaborn 官方 Tutorial、Plotly 官方 Examples —— 看图反查代码是最高效的学习方式。