Plotly 是一个开源交互式数据可视化库,由加拿大公司 Plotly Technologies 开发。Python 版本提供高层 API Plotly Express(惯用别名 px)实现「一行代码出交互图」,底层 graph_objects(go)则用于对图形细节做完全控制。与 Matplotlib 输出静态 PNG 不同,Plotly 图表天然自带悬浮提示、缩放、平移、框选和图例开关,可导出为独立的 HTML 文件,也可嵌入 Dash 构建 Web 数据分析应用。在 AI 工程中,模型评估曲线、RAG 检索效果分析、特征分布探查等场景,Plotly 是 Jupyter 生态里最常用的交互图表方案之一。本文按「速览—安装—上手—核心能力—生产部署—选型对比—常见误区—面试题」组织,建议直接跳到部署与避坑部分解决实际问题。
掌握 Plotly,AI 从业者可以把模型指标、评估结果和数据分布直接交付为可交互的 HTML 或 Dash 看板,是打通分析到交付链路的核心技能之一。
目录
速览卡是工具类内容的固定首屏模块:30 秒判断「这工具是什么、能不能商用、适不适合我」。
为什么需要 Plotly:从静态图到可交互交付
传统 Matplotlib 出的是静态图,探索数据时看某个点的具体数值要靠 print 或坐标目测;想局部放大、隐藏某个类别的点,必须改代码重跑;汇报交付只能贴图片,读者无法自己下钻。这些痛点在做 AI 工程时尤其明显:一次 RAG 评估可能有几百上千个样本,静态散点图上点与点互相遮挡,无法悬停查看对应的查询语句和文档来源。
Plotly 把渲染前移到浏览器端(底层是 JavaScript 库 Plotly.js),图本身就是交互界面:鼠标悬停显示数值、滚轮缩放、拖拽平移、框选局部、点击图例隐藏或恢复某个系列。探索过程不再需要「改参数—重跑—看图」的循环,直接在图内完成。交付时一行 fig.write_html() 即得到独立 HTML 文件,对方无需安装 Python 或任何依赖,浏览器打开即可交互浏览。
与同类工具的分工差异:Plotly 的设计贴近分析工作流——数据结构直接来自 pandas DataFrame,列名即参数;在 Jupyter、VS Code 中内联渲染;Dash、Streamlit 等应用框架中常作为图表层。它并不全场景替代 Matplotlib:论文出版级的静态排版精细控制仍是 Matplotlib 的强项,二者通常是共存关系,而非二选一。
安装与环境配置:3 步就绪
步骤一·安装主包。执行 pip install plotly。JupyterLab 3+ 和 VS Code 通常开箱即用;经典 Jupyter Notebook 建议补装 ipywidgets 以启用内联渲染。
步骤二·安装静态图导出引擎(可选)。若需要把图保存为 PNG/SVG/PDF 等静态文件,执行 pip install kaleido。kaleido 是独立于 plotly 的渲染引擎,plotly 主包不会自动携带。
步骤三·验证安装。在终端执行 python -c "import plotly; print(plotly.__version__)",能输出版本号(如 5.24.1)即安装成功;在 Notebook 中执行 import plotly.express as px; px.scatter(x=[1,2], y=[3,4]),无报错即可。
pip install plotly# 经典 Jupyter Notebook 如需内联渲染,补装 ipywidgetspip install "ipywidgets>=7.6"# 静态图导出(PNG/SVG/PDF 等)依赖pip install kaleido # 验证版本python -c "import plotly; print(plotly.__version__)"
快速上手:10 分钟跑通第一个交互散点图
思路:利用 plotly 内置的鸢尾花(iris)经典数据集,用 px 高层 API 一行出图,验证交互操作和 HTML 交付。px 是 plotly.express 的惯用别名,是 Plotly 的高层封装;trace 指图中的一条「图形轨迹」,一个 Figure 由多条 trace 和 layout(布局)组成。
1. 打开 Jupyter Notebook 或 VS Code 新建 .ipynb;没有 Notebook 环境也可直接用 Python 脚本,最后导出 HTML 查看。
2. 在单元格中输入 import plotly.express as px,然后执行 df = px.data.iris() 加载内置数据集(150 条样本、5 个字段)。
3. 执行 fig = px.scatter(df, x="sepal_length", y="sepal_width", color="species", hover_name="species"),按物种给点着色,悬停时显示物种名。
4. 让 fig 作为单元格最后一行自动渲染(或调用 fig.show())。在图上移动鼠标悬停查看数值、滚轮缩放、拖拽平移,点击图例可开关某个物种的点。
5. 执行 fig.write_html("iris.html"),双击生成的 HTML 文件即可在浏览器中交互使用,可发给任何人。
以下为完整可运行示例:
进阶技巧:在 px.scatter 中加 size="petal_length" 可把花瓣长度映射为点大小;时间序列改用 px.line;多子图对比可用 px 的 facet_col 分面参数,或直接叠加 trace。探索阶段用 px 快速出图,精细修改再用 go 底层 API 处理。
import plotly.express as px # 内置数据集:150 条鸢尾花样本df = px.data.iris() fig = px.scatter( df, x="sepal_length", y="sepal_width", color="species", hover_name="species",)fig.update_layout(title="Iris 花萼维度分布", template="plotly_white")fig.show() # 交付为独立 HTML 文件,双击即可在浏览器中打开fig.write_html("iris.html")
核心能力详解:5 大支柱
支柱一·双 API:px 高层封装与 go 底层对象。px 接受 DataFrame 加列名,自动完成颜色、尺寸、分面等图形属性映射,适合快速探索;go(graph_objects)用 go.Scatter、go.Bar、go.Heatmap 等 trace 对象手工叠加,适合精细控制。二者不是两套引擎:px 创建的正是 go.Figure 实例,px 出图后仍可调用 fig.update_traces()、fig.update_layout()、fig.add_trace() 继续加工。实际工作流通常是 px 先行、go 精修。
支柱二·开箱即用的交互与悬浮定制。悬浮提示是 Plotly 的默认能力,hovertemplate 参数可用 %{x}、%{y} 等占位符自定义气泡内容,<extra></extra> 可关闭多余气泡;fig.update_layout(hovermode="x unified") 让同一横坐标下的多系列数值统一显示。图内工具栏提供缩放、平移、框选和下载 PNG 等交互入口,图例点击即可隐藏/恢复系列,这些交互无需写任何前端代码。
支柱三·布局、批注与子图。fig.update_layout() 是统一修改入口,可设置标题、坐标轴、template 主题(如 "plotly_dark"、"plotly_white");fig.add_hline() 和 fig.add_vrect() 可画阈值线和区间高亮,在模型评估看板里标注通过率线、延迟告警区间非常常用;make_subplots(rows=2, cols=2, specs=...) 来自 plotly.subplots 模块,支持把不同类型的 trace 组合在同一个图里。
支柱四·大数据量性能。普通 px.scatter 走 SVG 渲染,几万点尚可,几十万点会明显卡顿。应对方案:改用 WebGL 渲染的 go.Scattergl;或用密度聚合图(如 go.Histogram2dContour)把密集点区转化为等值面,数据量从几十万点降为几百个格子。同时控制 hover_data 的列数——把整张表塞进悬浮数据会让导出的 HTML 膨胀到几十 MB。
支柱五·多端交付矩阵。Jupyter 内联渲染适合开发态;fig.write_html() 生成独立交互文件,适合分发与静态托管;fig.write_image()(依赖 kaleido)输出静态图,适合论文、邮件和自动化报表;Dash 把多个 Plotly 图组合成带回调的 Web 应用,适合长期运行的业务看板。
生产部署与监控:从上线到运维
部署方式一·静态 HTML 交付。fig.write_html("report.html", include_plotlyjs=True) 生成自包含文件后,当作普通静态资源放到对象存储、CDN 或 Nginx 静态目录即可。零服务端依赖,适合日报、周报和单次分析结论的交付。注意 5.x 默认从 CDN 加载 Plotly.js,内网环境必须显式传入 include_plotlyjs=True 把渲染库内嵌进 HTML。
部署方式二·Dash 应用。Dash 是 Plotly 官方开源 Web 框架,把多个图表和下拉框、滑块等控件绑定到回调函数上,实现多图联动和数据更新。生产环境用 gunicorn 等 WSGI 服务器承载,Docker 打包部署,Nginx 反向代理;离线环境需将 plotly.js 内嵌或放到本地静态目录。Dash 本身开源免费,Dash Enterprise 是面向企业的商业部署平台,两者需区分。
可观测性。Plotly 图表本身不含服务端埋点:静态 HTML 的交互行为全部发生在用户浏览器中,若要统计「哪些图被打开、交互频率」,需在 HTML 中自行注入页面事件上报脚本;Dash 应用底层是 Flask,可通过访问日志或 before_request 钩子记录请求路径和来源,统计看板使用量。批量调用 fig.write_image() 导出静态图时,kaleido 会启动独立进程,建议用队列限制并发,避免内存峰值。部署前重点检查两项指标:HTML 文件体积(影响首屏加载)和目标网络环境下 Plotly.js 是否可达。
<p class="para-label">避坑清单:</p>
<ul class="dash-list"><li>write_html 在 5.x 默认从 CDN 加载 Plotly.js,内网或离线环境必须传 include_plotlyjs=True 内嵌渲染库,否则打开只有空白页面。</li><li>几十万点直接 px.scatter 会走 SVG 渲染拖垮浏览器,应改用 go.Scattergl(WebGL)或密度聚合图;hover_data 不要塞全表列,否则导出 HTML 可达几十 MB,首屏加载缓慢。</li><li>fig.write_image() 依赖额外安装的 kaleido 引擎,且 kaleido 版本需与 Python 版本匹配;Notebook 里 fig.show() 正常不代表静态导出可用,部署前要实测一次。</li><li>无头服务器(CI、定时任务)中 fig.show() 会尝试拉起浏览器而阻塞进程,统一改用 fig.write_html() 或 fig.write_image() 输出到文件。</li></ul>
| 维度 | Plotly | Matplotlib | Seaborn | Bokeh |
|---|---|---|---|---|
| 定位 | 交互可视化库(高层+底层双 API) | 静态图表基础库 | 统计图形库(基于 Matplotlib) | 交互可视化库(面向 Web 场景) |
| 编排范式 | px 传入 DataFrame 列名出图,go 对象叠加 trace | pyplot 面向过程状态机 | 函数式统计绘图,data=df 绑定 | figure 对象 + ColumnDataSource 数据源 + 回调 |
| 类型约束 | px 自动推断图形属性映射,go 提供全量 trace 类型 | 需手动设置轴、标签、刻度 | 内置回归、分布、聚类等统计变换 | 以数据源为中心,图表与数据分离 |
| 学习曲线 | 低-中:px 极低;go 需理解 trace/layout 概念 | 中-高:配置项多且依赖状态机行为 | 低-中:语法简洁但局限于统计图形 | 中-高:交互回调机制需要额外学习 |
| 生态集成 | pandas/Jupyter 无缝,可接 Dash/Streamlit,输出 HTML | pandas/NumPy 生态标准,学术出版主力 | pandas 直接支持,统计场景丰富 | pandas 支持,可与 Tornado/Bokeh Server 集成 |
| 生产部署 | write_html 零服务端依赖;Dash 建 Web 应用;kaleido 静态导出 | savefig 静态图,无交互 Web 能力 | 同 Matplotlib,输出静态图 | bokeh serve 独立服务,支持实时推送 |
| License | MIT | PSF 兼容(可商用) | BSD-3 | BSD-3 |
| 适合谁 | 需要交互分析、HTML 交付或 Web 看板的团队 | 论文出版级静态图、需要最底层控制的场景 | 统计分析先行、快速探索数据分布 | 实时流数据、服务端推送类交互应用 |
选型建议:论文与精细排版选 Matplotlib,统计建模前期的分布/回归分析用 Seaborn 更高效;需要交互探索、HTML 交付或 Web 看板的场景选 Plotly;实时数据流和大规模服务端推送场景再考虑 Bokeh。四者不互斥,实际项目中常混用。
版本迭代
plotly.py 在 2019 年 4.0 版本将曾需单独安装的 Plotly Express 并入主包,同时引入模板主题系统和 kaleido 静态图导出,确立了「高层快速出图 + 底层精细控制」的双 API 形态;2021 年起进入 5.x 系列,以默认行为调整、依赖适配和缺陷修复为主;4.0+ 的 API 在 5.x 中保持兼容,升级成本低。(截至训练数据,可能已有更新版本)
| 版本 | 时间 | 变化 | 提升 |
|---|---|---|---|
| 4.0.0 | 2019-10 | Plotly Express 并入主包 | 高层 API 一体化,无需单独安装 plotly-express;新增模板主题系统;kaleido 取代 orca 作为静态图导出引擎 |
| 5.0.0 | 2021-05 | 版本主线跃升至 5.x | 默认渲染与导出行为调整(write_html 默认走 CDN);API 清理与整体性能优化 |
| 5.9.0 | 2022-09 | 增量迭代 | 同步上游 Plotly.js 功能与缺陷修复,补充图类型与配置项 |
| 5.15.0 | 2023-06 | 增量迭代 | 适配新版本依赖,修复跨 Python 版本兼容问题 |
| 5.24.1 | 2024-10 | 维护版 | 截至训练数据的最新稳定版,持续修复报告缺陷 |
Plotly 是图形库而非模型,没有 MMLU 一类标准化量化榜单。社区实测的关注点集中在三处:大数据量交互流畅度(Scattergl 显著优于普通 Scatter)、导出 HTML 的体积控制、以及 write_html 默认 CDN 行为带来的离线适配成本。选型建议:直接使用 5.x 最新稳定版;网上旧教程中「先安装 plotly-express 再导入」的步骤已作废,4.x 项目可平滑升级。
AI 应用场景
RAG 效果评估与失败模式定位
阶段:模型评估 / RAG 管道构建
解决的问题:RAG 评测结果散落在日志和表格中,静态图无法按查询下钻;交互式散点和箱线图让每个样本的评分、延迟、检索命中数悬停可见,配合 add_hline 画阈值线定位低分聚集区。
具体案例:某 RAG 项目用 px.scatter 以「检索命中数」为 x 轴、「答案得分」为 y 轴,按文档来源着色,悬停直接显示查询原文。定位失败模式(低分聚集区)从逐个翻日志的 1-2 小时缩短到 30 分钟,Prompt 优化方向得以量化验证。
训练过程与多实验对比监控
阶段:模型训练 / MLOps 监控
解决的问题:多组实验的 loss/acc 曲线叠在静态图上互相遮挡,无法缩放查看收敛细节;交互式折线图支持同横坐标多系列对比和局部放大。
具体案例:训练 3 组配置各 5 次(共 15 条曲线),用 px.line 按实验配置着色绘制 loss 曲线,开启 hovermode="x unified" 在同一横坐标下对比各配置的收敛值,配置差异 10 分钟内即可判断。
特征工程与数据质量探查
阶段:数据预处理 / 特征工程
解决的问题:高维特征之间的两两关系靠手动逐张画子图效率低;并行坐标图和散点矩阵能快速观察分布形态与类别可分性。
具体案例:用 px.scatter_matrix 一次查看 6 个数值特征的两两相关性,并按目标类别着色,替代原先手动生成 15 张子图的流程,探查耗时下降约 70%,同时还发现两个高相关冗余特征。
常见误区
误区以为 Plotly 是 Notebook 插件,离开 Jupyter 就没有意义,最多只能在本地弹个浏览器窗口。
正解Notebook 只是开发态。fig.write_html() 生成自含交互的 HTML 文件,放到任意静态托管即可访问;fig.write_image() 输出 PNG/SVG/PDF 用于文档;Dash 把 Plotly 图变成带数据更新能力的 Web 应用。渲染器会自动适配环境,但交付手段远多于 Notebook。
为何常见:绝大多数教程以 Jupyter 演示,fig.show() 在其中最方便,容易让人忽略 write_html 这条生产路径。
误区认为 plotly.express 和 plotly.graph_objects 是两个并列的库,学习时只学高层或只学底层。
正解px 是高层封装,任何 px 调用返回的都是 go.Figure 实例,可继续用 update_layout、update_traces、add_trace 等底层方法加工。推荐工作流是 px 快速出图、go 精修细节,两者是同一对象的不同操作层级。
为何常见:官方文档把 px 与 go 分章教学,且两者语法风格差异大(一句话传参 vs 对象式叠加),容易误判为两套体系。
误区以为 `pip install plotly` 之后 `fig.write_image()` 开箱即用,报错时怀疑是代码写错。
正解静态图导出由独立引擎 kaleido 负责,必须另外 pip install kaleido 才能使用 write_image() 和 to_image()。Notebook 里 fig.show() 正常不代表静态导出可用,两者走的是不同的渲染链路。
为何常见:kaleido 因体积原因不随 plotly 主包安装,官方文档把两者分开列出,很多人没注意到安装小节。
误区以为 HTML 文件里已打包全部 JavaScript,拖到内网或离线环境就能正常显示。
正解plotly.py 5.x 起 write_html() 默认从 CDN 加载 Plotly.js,无外网环境需传 include_plotlyjs=True 把渲染库内嵌进文件(体积增大),或把 plotly.js 放到本地静态目录。部署到目标网络前必须实测一次。
为何常见:4.x 时期默认行为是内嵌,5.0 调整默认值后,网上大量旧教程仍按旧行为描述。
面试题
Q1. plotly 的高层 API(传入 DataFrame 与列名即可出图)位于哪个模块?
- A.plotly.graph_objects
- B.plotly.express← 正确答案
- C.plotly.offline
- D.plotly.subplots
答案:B。plotly.express(惯用别名 px)是高层 API,传入 DataFrame 与列名即可出图;graph_objects 提供 go.Scatter 等底层对象用于精细控制;offline 是 4.0 之前的旧离线渲染模块;subplots(make_subplots)只负责子图布局,不是高层绘图 API。
Q2. 关于 plotly.express(px)与 plotly.graph_objects(go)的关系,正确的是?
- A.两套完全独立的渲染引擎
- B.同一 Figure 对象的不同层级 API← 正确答案
- C.go 是 px 的旧版名称
- D.px 只能绘制散点图
答案:B。px 是高层封装,任何 px 调用返回的都是 go.Figure 实例,可继续用 update_layout、update_traces、add_trace 等底层方法加工,因此是同一对象的不同层级 API,不存在两套引擎或二选一的问题。go 不是 px 旧名,px 也支持线图、柱图等数十种图形。
Q3. 在 Jupyter Notebook 中创建 px 图后,正确的显示方式是?
- A.必须显式调用 fig.show()
- B.需要调用 fig.render() 方法
- C.只能导出 HTML 后查看
- D.Notebook 中默认自动渲染← 正确答案
答案:D。Plotly Figure 实现了 Notebook 的富文本展示协议,单元格最后一行是 fig 或 px 表达式时自动内联渲染;fig.show() 主要用于非 Notebook 环境或强制刷新场景。不存在 fig.render() 方法,导出 HTML 也只是多种交付方式之一。
Q4. 将 Figure 导出为独立 HTML 文件的正确方法是?
- A.fig.display()
- B.fig.write_html()← 正确答案
- C.fig.export_html()
- D.plotly.io.save()
答案:B。fig.write_html(path) 是导出独立交互 HTML 的标准方法,内部把 figure 的 JSON 描述与 Plotly.js 按 include_plotlyjs 参数组合进单文件。fig.display 和 fig.export_html 均不存在,plotly.io 模块也没有 save 方法。
Q5. 关于 plotly.py 5.x 中 write_html 的默认行为,正确的是?
- A.默认将 Plotly.js 完整内嵌
- B.默认从 CDN 加载,内嵌需指定参数← 正确答案
- C.默认要求安装本地 Node.js
- D.默认文件依赖外网才能渲染
答案:B。plotly.py 5.x 起 write_html 默认 include_plotlyjs="cdn",即从 CDN 拉取渲染库,因此离线环境需传 include_plotlyjs=True 内嵌。节点上的渲染在浏览器完成,不依赖 Node.js;联网时文件在浏览器直接可用,但完全离线时默认文件会白屏。
Q6. 使用 fig.write_image() 导出 PNG 静态图,需要额外安装?
- A.Pillow 图像库
- B.Kaleido 渲染引擎← 正确答案
- C.Selenium 浏览器
- D.Orca 旧版工具
答案:B。静态图导出由独立引擎 kaleido 负责,需单独 pip install kaleido。Orca 是 kaleido 之前使用的旧方案,官方已弃用;Selenium 是浏览器自动化工具,Pillow 是图像处理库,均与 Plotly 静态导出无关。
Q7. 面对数十万数据点的散点图,哪些措施能有效提升渲染性能?
- A.改用 go.Scattergl 走 WebGL 渲染← 正确答案
- B.继续保持 px.scatter 绘制全部原始点
- C.用 go.Histogram2dContour 做密度聚合← 正确答案
- D.hover_data 中塞入全表所有列
答案:AC。WebGL 渲染的 Scattergl 是处理几万到几十万点散点的标准手段;Histogram2dContour 把点密集区转为等值面,数据量从几十万点降为几百个格子。B 会让 SVG 渲染卡顿,D 会使 HTML 文件膨胀到几十 MB,均不是优化手段。
Q8. 以下哪些是 Plotly 图表的合规生产部署方式?
- A.write_html 生成静态文件挂 CDN← 正确答案
- B.用 Dash 构建交互式 Web 应用← 正确答案
- C.依赖用户本地 Jupyter 服务渲染
- D.write_image 导出 PNG 嵌入报表← 正确答案
答案:ABD。静态 HTML 零服务端依赖、Dash 提供回调与数据更新、静态图片适合论文和邮件场景,三者都是主流交付方式。C 把 Notebook 进程当作生产服务不可靠且存在安全风险,交互渲染也不应由终端用户侧承担。
Q9. 关于 Plotly Figure 的内部结构,正确的说法有?
- A.figure 由 data 与 layout 两部分组成← 正确答案
- B.一个 figure 只能包含同一种 trace 类型
- C.update_layout 可统一修改标题与模板← 正确答案
- D.可通过 fig.to_json() 序列化完整图形← 正确答案
答案:ACD。Figure 的 JSON 结构即 data(trace 列表)+ layout(标题、坐标轴、模板等),还可含 frames(动画)。单个 figure 可混排 scatter、bar、heatmap 等多种 trace。to_json()/from_json() 用于完整序列化与还原图形,是跨环境传输的标准手段。
Q10. 关于 Plotly Express 的版本历史,正确的是?
- A.需单独 pip install plotly-express
- B.自 4.0 起已并入 plotly 主包← 正确答案
- C.它是 R 语言版本的组件
- D.已被 Seaborn 完全取代
答案:B。4.0 之前 Plotly Express 是独立包,自 4.0 起并入主包,px 开箱即用,网上「先安装 plotly-express」的旧教程已过时。R 语言对应的是 plotly 的 R 包,与 px 无关;Seaborn 基于 Matplotlib,与 px 没有取代关系。
参考来源
- webpageplotly.py GitHub源码、Issue 与 Changelog