Plotly 交互式图表
Plotly 是 Python 数据可视化的"终极武器",一行代码就能生成交互式图表(悬停、缩放、导出),支持 35+ 种图表类型,配合 Dash 还能做完整的数据仪表盘,是 matplotlib 的最佳交互式替代。
核心知识点
| 知识点 | 说明 |
|---|
| 工具定位 | Python/R/JS 交互式图表库 |
| 最新版本 | Plotly.py v6.7.0(2026 年 4 月) |
| 核心优势 | 一行代码出交互图、35+ 图表类型、Jupyter 友好 |
| 底层引擎 | Plotly.js(JavaScript,SVG + WebGL) |
| 配套框架 | Dash(Python Web 仪表盘框架) |
| 许可证 | MIT 开源 |
安装配置
# pip 安装
pip install plotly # 安装 Plotly
pip install kaleido # 静态图片导出(PNG/PDF/SVG)
# conda 安装
conda install -c conda-forge plotly
# Jupyter 支持(自动内联显示)
pip install nbformat # Notebook 格式支持
基本使用
1. Plotly Express(推荐入口)
import plotly.express as px # 导入 Plotly Express(高层 API)
import pandas as pd # 导入 Pandas
# 示例数据
df = pd.DataFrame({
"物种": ["Bacteroidetes", "Firmicutes", "Proteobacteria",
"Actinobacteria", "Fusobacteria"],
"丰度": [35, 28, 15, 12, 10], # 丰度百分比
"组别": ["健康", "疾病", "健康", "疾病", "健康"]
})
# 柱状图(一行代码!)
fig = px.bar(df, x="物种", y="丰度", # X 轴和 Y 轴
color="组别", # 按组别着色
title="物种丰度分布") # 标题
fig.show() # 显示交互式图表
2. 散点图
# 散点图(带悬停信息)
fig = px.scatter(df, x="Shannon", y="Simpson", # 双指数散点
color="Group", # 按组着色
size="SampleSize", # 点大小映射
hover_data=["SampleID"], # 悬停显示样本ID
title="Alpha 多样性")
fig.show()
3. 箱线图
# 箱线图(常用于组间比较)
fig = px.box(df, x="Group", y="Shannon", # 按组画箱线图
color="Group", # 颜色区分
points="all", # 显示所有数据点
title="Shannon 指数组间比较")
fig.update_layout(showlegend=False) # 隐藏图例(已有 X 轴标签)
fig.show()
4. 饼图 / 环形图
# 环形饼图
fig = px.pie(df, values="丰度", names="物种", # 数值和标签
hole=0.4, # 中间空洞 = 环形图
title="菌群组成")
fig.show()
5. 热力图
import numpy as np # 导入 NumPy
# 模拟基因表达矩阵
genes = ["Gene_" + str(i) for i in range(1, 11)] # 10 个基因
samples = ["S" + str(i) for i in range(1, 6)] # 5 个样本
matrix = np.random.rand(10, 5) # 随机表达值
fig = px.imshow(matrix, # 热力图
labels=dict(x="样本", y="基因", color="表达量"),
x=samples, y=genes, # 轴标签
color_continuous_scale="RdBu_r", # 红蓝配色
title="基因表达热图")
fig.show()
高级用法
1. Graph Objects(底层 API,精细控制)
import plotly.graph_objects as go # 底层 API
# 多系列叠加
fig = go.Figure() # 创建空图
fig.add_trace(go.Bar( # 添加柱状图
name="健康组",
x=["Bacteroidetes", "Firmicutes"],
y=[40, 25],
marker_color="steelblue" # 柱子颜色
))
fig.add_trace(go.Bar( # 再添加一组
name="疾病组",
x=["Bacteroidetes", "Firmicutes"],
y=[30, 35],
marker_color="indianred"
))
fig.update_layout(
barmode="group", # 分组柱状图
title="健康 vs 疾病组物种丰度",
xaxis_title="物种",
yaxis_title="相对丰度 (%)"
)
fig.show()
2. 子图(多图组合)
from plotly.subplots import make_subplots # 子图工具
fig = make_subplots(rows=1, cols=2, # 1 行 2 列
subplot_titles=("散点图", "箱线图"))
fig.add_trace(go.Scatter(x=[1,2,3], y=[4,5,6], mode="markers"),
row=1, col=1) # 左边散点图
fig.add_trace(go.Box(y=[1,2,3,4,5], name="A"),
row=1, col=2) # 右边箱线图
fig.update_layout(title_text="多图组合", showlegend=False)
fig.show()
3. 导出图片
# 导出为静态图片(需要 kaleido)
fig.write_image("figure.png", width=800, height=600, scale=2) # PNG
fig.write_image("figure.svg") # SVG 矢量图
fig.write_image("figure.pdf") # PDF
# 导出为交互式 HTML
fig.write_html("figure.html") # 可在浏览器打开的交互式图表
4. 3D 散点图
# PCoA / PCA 三维可视化
fig = px.scatter_3d(df, x="PC1", y="PC2", z="PC3", # 三个主成分
color="Group", # 按组着色
symbol="Timepoint", # 不同时间点用不同符号
title="PCoA 三维可视化")
fig.show()
5. 动画图表
# 带时间滑块的动画
fig = px.scatter(df, x="Shannon", y="Simpson",
animation_frame="Timepoint", # 按时间点动画
animation_group="SampleID", # 每个样本是一个动画对象
color="Group",
size="Abundance",
range_x=[0, 5], range_y=[0, 1], # 固定坐标范围
title="多样性随时间变化")
fig.show()
常见报错与解决
| 报错信息 | 原因 | 解决方法 |
|---|
| 图表不显示 | Jupyter 渲染问题 | fig.show(renderer="notebook") |
ValueError: Invalid color | 颜色格式错误 | 用 "rgb(255,0,0)" 或 CSS 颜色名 |
| 导出图片失败 | kaleido 未装 | pip install kaleido |
| 大数据卡顿 | 数据点太多 | 用 px.scatter(render_mode="webgl") |
速查表
# ===== Plotly 速查表 =====
import plotly.express as px # 高层 API(推荐)
import plotly.graph_objects as go # 底层 API
# Plotly Express 一行出图
px.bar(df, x, y, color) # 柱状图
px.scatter(df, x, y, color, size) # 散点图
px.line(df, x, y, color) # 折线图
px.box(df, x, y, color) # 箱线图
px.violin(df, x, y, color) # 小提琴图
px.pie(df, values, names) # 饼图
px.histogram(df, x, color) # 直方图
px.imshow(matrix) # 热力图
px.scatter_3d(df, x, y, z) # 3D 散点
px.density_heatmap(df, x, y) # 密度热图
# 导出
fig.write_image("fig.png") # PNG
fig.write_image("fig.svg") # SVG
fig.write_html("fig.html") # 交互式 HTML
# Plotly vs Matplotlib
# Plotly: 交互式、Web 友好、Dash 集成
# Matplotlib: 静态图、论文级出版、更多定制
# 建议:探索数据用 Plotly,发论文用 Matplotlib