Plotly.js
开源 JavaScript 科学图表库,支持 40+ 交互式图表类型(含 3D、地图、金融图表),是 Plotly 和 Dash 生态的核心引擎。
Plotly.js 是面向科学计算和数据分析的全功能图表库,支持 40+ 种图表类型包括 3D、地理热力图、金融 K 线图等,基于 D3.js 和 WebGL 双引擎渲染,是 Jupyter、Dash 等数据科学工具的默认图表引擎。
Plotly.js
开源 JavaScript 科学图表库,支持 40+ 交互式图表类型(含 3D、地图、金融图表),是 Plotly 和 Dash 生态的核心引擎。
技术简介说明
Plotly.js 是由 Plotly 公司开发的开源 JavaScript 数据可视化库,最初发布于 2015 年。它的核心定位是服务于科学计算、数据分析和工程领域的"全功能"图表库——不同于 Chart.js 专注于常见商业图表,Plotly.js 从诞生之初就瞄准了科学可视化这个细分领域,提供包括 3D 曲面图、等高线图、金融 K 线图、统计分布图、地理热力图、点云图等高级图表类型。Plotly.js 基于 D3.js 进行数据驱动渲染,同时使用 regl(WebGL 绑定)实现大规模数据的高性能绘制,形成了"SVG + WebGL"双渲染引擎的独特架构。
Plotly.js 的核心价值在于"声明式 + 交互式 + 科学级"三位一体。开发者通过 JSON 配置对象描述图表结构(traces + layout),Plotly.js 负责渲染和交互。这种设计使得它与 Python(plotly.py)、R(plotly.R)、Julia(Plotly.jl)等语言天然互通——这也是为什么 Plotly.js 同时是 Plotly 和 Dash(Python Web 应用框架)的底层引擎。2025 年 2 月发布的 v3.0 是一次重大的 Breaking Change 版本,清除了大量历史遗留的废弃 API,统一了属性命名规范,并优化了现代化构建流程。
经过十年发展,Plotly.js 已成为科学可视化领域最流行的开源方案之一。GitHub Stars 约 18,200+,npm 周下载量约 32 万+,被全球数万个数据科学项目、企业数据看板、学术研究平台和教育系统使用。它是 Jupyter Notebook、Streamlit、Dash、JupyterLab 等数据科学工具链的默认图表引擎,在数据科学社区(Python、R)中的影响力甚至超过其在前端社区的影响力。
基本信息
- 官网:https://plotly.com/javascript/
- GitHub:https://github.com/plotly/plotly.js
- License:MIT
- 最新版本:v3.7.0(2026 年 7 月 3 日发布)
- 主要维护者/公司:Plotly, Inc.(加拿大多伦多,创始人 Chris Parmer)
- GitHub Stars:~18,200+(2026 年数据)
- npm 周下载量:~32 万+(plotly.js-dist-min)
- 语言构成:JavaScript 99.7%
- Forks:~2,000
- Watchers:~280
- 被依赖仓库数:~37,700
- 总提交数:28,726+
- 总 Release 数:276+
- Bundle 大小:~3.5MB(完整包,含所有图表类型);支持按模块打包(partial bundles)可大幅减小体积
快速上手
安装
# 推荐使用 dist 版本(预构建,开箱即用)
npm install plotly.js-dist-min
# 或安装完整源码版本(支持自定义构建)
npm install plotly.js
# 使用 CDN(推荐快速原型开发)
<script src="https://cdn.jsdelivr.net/npm/[email protected]/plotly.min.js"></script>
# 使用 unpkg CDN
<script src="https://unpkg.com/[email protected]/plotly.min.js"></script>
# React 项目安装
npm install react-plotly.js plotly.js
# Angular 项目安装
npm install angular-plotly.js plotly.js
# 按模块引入(Tree-shaking 优化,减小 bundle 体积)
# Plotly.js 提供多个预定义的 partial bundles:
npm install plotly.js-basic-dist-min # 基础图表(~190KB gzipped)
npm install plotly.js-cartesian-dist-min # 笛卡尔坐标系图表
npm install plotly.js-geo-dist-min # 地理图表
npm install plotly.js-gl3d-dist-min # 3D 图表
npm install plotly.js-finance-dist-min # 金融图表重要提示:Plotly 官方推荐在 npm 项目中使用
plotly.js-dist或plotly.js-dist-min,而不是直接安装plotly.js源码包。源码包体积大、构建复杂,适合需要自定义的高级场景。
基础配置
Plotly.js 不需要复杂的初始化配置。核心使用模式是通过 Plotly.newPlot() 传入数据(data)和布局(layout)对象:
// 数据配置(traces)
const data = [
{
x: [1, 2, 3, 4, 5],
y: [1, 4, 9, 16, 25],
type: 'scatter', // 图表类型
mode: 'lines+markers', // 显示模式
name: '示例数据',
marker: {
color: 'rgb(31, 119, 180)',
size: 8
},
line: {
width: 2
}
}
];
// 布局配置(layout)
const layout = {
title: {
text: '我的第一个 Plotly 图表',
font: { size: 18 }
},
xaxis: { title: { text: 'X 轴' } },
yaxis: { title: { text: 'Y 轴' } },
margin: { t: 40, r: 30, b: 40, l: 60 },
hovermode: 'closest' // 悬停模式
};
// 响应式配置
const config = {
responsive: true, // 自动响应容器尺寸变化
displayModeBar: true, // 显示工具栏
toImageButtonOptions: {
format: 'png',
filename: 'my_plot',
width: 1200,
height: 800,
scale: 2 // 2x 分辨率
}
};最小示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Plotly.js 最小示例</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/plotly.min.js"></script>
<style>
#myDiv { width: 100%; height: 500px; }
</style>
</head>
<body>
<div id="myDiv"></div>
<script>
const trace = {
x: [1, 2, 3, 4, 5],
y: [2, 4, 6, 8, 10],
type: 'scatter',
mode: 'lines+markers',
name: '线性数据'
};
const layout = {
title: { text: 'Plotly.js 快速开始' },
xaxis: { title: { text: 'X 值' } },
yaxis: { title: { text: 'Y 值' } }
};
Plotly.newPlot('myDiv', [trace], layout, { responsive: true });
</script>
</body>
</html>React 项目最小示例:
import Plot from 'react-plotly.js';
function MyChart() {
return (
<Plot
data={[
{
x: [1, 2, 3],
y: [2, 4, 6],
type: 'scatter',
mode: 'lines+markers',
marker: { color: 'red' },
},
]}
layout={{
title: { text: 'React + Plotly' },
width: 600,
height: 400,
}}
config={{ responsive: true }}
/>
);
}
export default MyChart;Next.js(App Router)集成示例:
// app/chart/page.jsx
'use client'; // 必须标记为客户端组件
import dynamic from 'next/dynamic';
const Plot = dynamic(() => import('react-plotly.js'), { ssr: false });
export default function ChartPage() {
return (
<Plot
data={[{ x: [1, 2, 3], y: [2, 4, 6], type: 'scatter' }]}
layout={{ width: 600, height: 400 }}
/>
);
}核心概念与架构
核心概念
Plotly.js 的架构围绕三个核心抽象构建:
-
Trace(数据轨迹):描述一组数据及其可视化方式。每个 trace 包含数据类型(
type)、数据值(x、y、z等)和视觉属性(颜色、大小、线型等)。一个图表可以包含多个 traces,它们共享同一个坐标系。 -
Layout(布局):描述图表的整体结构和外观,包括标题、坐标轴、图例、边距、注释、形状、滑块、下拉菜单等。Layout 是 traces 之外的全局配置。
-
Config(配置):控制图表的行为特性,如工具栏显示、响应式、导出选项、本地化设置等。Config 在创建图表时传入,之后不可修改。
┌─────────────────────────────────────────────────────────┐
│ Plotly.js 架构 │
├─────────────────────────────────────────────────────────┤
│ │
│ 输入层 │
│ ├── data[] (traces) ← 数据 + 可视化类型 │
│ ├── layout (object) ← 全局布局 + 样式 │
│ └── config (object) ← 行为配置 │
│ │
│ 处理层 │
│ ├── 数据归一化 & 验证 ← 属性校验、默认值填充 │
│ ├── 坐标计算 ← 轴映射、缩放、tick 生成 │
│ └── 布局计算 ← 尺寸分配、图例位置、边距计算 │
│ │
│ 渲染层 │
│ ├── SVG 渲染器 ← 标准图表(scatter、bar 等) │
│ ├── WebGL 渲染器 (regl) ← 大规模数据(scattergl 等) │
│ ├── Canvas 渲染器 ← 部分特定图表类型 │
│ └── DOM 层 ← 交互事件、tooltip、工具栏 │
│ │
│ 交互层 │
│ ├── 事件系统 ← click、hover、zoom、select │
│ ├── 工具栏 (modebar) ← 内置导出、缩放、旋转等操作 │
│ └── 动画系统 ← trace 过渡、layout 过渡 │
│ │
└─────────────────────────────────────────────────────────┘
渲染引擎选择
Plotly.js 的一大特色是自动或手动选择渲染引擎:
| 引擎 | 适用场景 | Trace 类型示例 | 数据量上限 |
|---|---|---|---|
| SVG | 标准图表、少量数据、需要 CSS 样式控制 | scatter、bar、pie、histogram | ~10K 点 |
| WebGL | 大规模数据、3D 图表、高性能需求 | scattergl、heatmapgl、mesh3d、surface | ~1M+ 点 |
| Canvas | 部分特定图表 | pointcloud(已废弃) | 极高 |
当数据量超过 ~10,000 点时,建议将 type: 'scatter' 替换为 type: 'scattergl',自动启用 WebGL 渲染。
模块化架构
Plotly.js 采用模块化设计,每个图表类型(trace type)是一个独立模块:
// 自定义构建——只包含需要的模块
const Plotly = require('plotly.js/lib/core');
// 按需注册 trace 类型
Plotly.register([
require('plotly.js/lib/scatter'),
require('plotly.js/lib/bar'),
require('plotly.js/lib/pie'),
require('plotly.js/lib/heatmap'),
]);
// 现在只支持 scatter、bar、pie、heatmap
// Bundle 大小从 ~3.5MB 减小到 ~800KB核心特性
-
40+ 图表类型:涵盖 scatter、bar、pie、heatmap、contour、histogram、box、violin、scatter3d、surface、mesh3d、choropleth、scattergeo、candlestick、ohlc、sunburst、treemap、funnel、waterfall、sankey、parcoords、table、indicator 等,几乎覆盖所有常见和高级可视化需求。
-
双渲染引擎(SVG + WebGL):SVG 提供高质量的矢量输出和 CSS 样式控制;WebGL(通过
regl)支持百万级数据点的流畅渲染,适用于科学计算和大规模数据分析场景。 -
原生 3D 支持:真正的 3D 散点图、曲面图、网格图,支持相机控制、光照、纹理映射,适合科学可视化和工程仿真。
-
丰富的统计图表:内置箱线图、小提琴图、直方图、密度图、误差棒、趋势线、相关性矩阵、等高线图等统计图表,无需额外计算库即可生成统计分析可视化。
-
完整的交互系统:缩放、平移、框选、套索选择、悬停提示、点击事件、双击重置、范围选择等交互能力全部内置,且支持自定义事件处理。
-
响应式设计:图表自动适应容器尺寸变化,支持
window.resize自动重绘,适合移动端和响应式 Web 布局。 -
声明式 API:通过 JSON 对象描述图表,与后端语言(Python、R、Julia、MATLAB)的数据结构天然兼容。同一份 JSON 配置可以在不同语言的 Plotly 实现中复用。
-
地图与地理可视化:内置 choropleth 地图、scattergeo、densitymapbox、scattermapbox,支持 GeoJSON、Mapbox tiles、自然地球数据,可创建出版级的地理可视化。
-
金融图表:专业的 K 线图(candlestick)、OHLC 图、漏斗图(funnel)、瀑布图(waterfall),内置时间轴处理和交易日历支持。
-
导出与打印:支持导出为 PNG、JPEG、SVG、PDF(通过 orca 或 kaleido)格式,适合报告生成和出版印刷。
-
动画与帧系统:通过
Plotly.animate()和frames配置,可以创建时间序列动画、数据过渡效果和交互式数据探索体验。 -
可访问性(A11y):v3.x 版本加强了无障碍支持,图表可通过屏幕阅读器读取,支持键盘导航。
生态图
生态系统概览
┌────────────────────────────┐
│ Plotly.js 核心 │
│ (plotly/plotly.js) │
│ JavaScript 图表引擎 │
└────────────┬───────────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────────┐ ┌───────────────────┐ ┌─────────────────────┐
│ 前端框架封装 │ │ 后端语言绑定 │ │ 应用框架 │
│ │ │ │ │ │
│ • react-plotly.js │ │ • plotly.py │ │ • Dash (Python) │
│ • angular-plotly │ │ • plotly.R │ │ • Dash Enterprise │
│ • vue-plotly │ │ • Plotly.jl │ │ • JupyterLab │
│ │ │ • plotly.rs │ │ • Streamlit │
│ │ │ │ │ • Panel (Python) │
└───────────────────┘ └───────────────────┘ └─────────────────────┘
┌────────────────────────────┐
│ 工具链与扩展 │
│ │
│ • kaleido (静态导出引擎) │
│ • orca (旧版导出引擎) │
│ • plotly.py (Python SDK) │
│ • chart-studio (在线编辑) │
└────────────────────────────┘
关键依赖
| 依赖 | 用途 | 说明 |
|---|---|---|
d3 | 数据驱动渲染 | 用于比例尺计算、坐标映射、SVG 生成 |
regl | WebGL 绑定 | 用于 scattergl、3D 图表等高性能渲染 |
gl-mat4 / gl-vec3 | 3D 数学运算 | 3D 场景的矩阵和向量变换 |
topojson-client | 地理数据 | 地图渲染中的 TopoJSON 解析 |
d3-geo | 地理投影 | 地图投影计算 |
框架封装
| 封装包 | 框架 | 维护状态 | npm 包名 |
|---|---|---|---|
| react-plotly.js | React | ✅ 官方维护 | react-plotly.js |
| angular-plotly.js | Angular | ✅ 官方维护 | angular-plotly.js |
| vue-plotly | Vue 2 | ⚠️ 社区维护(statnett) | vue-plotly |
| vue-plotly (Vue 3) | Vue 3 | ⚠️ 社区 fork 多个 | 多个非官方包 |
| plotly.py | Python | ✅ 官方维护 | pip install plotly |
| plotly.R | R | ✅ 官方维护 | CRAN |
| Plotly.jl | Julia | ✅ 官方维护 | Julia package |
社区生态
- Plotly Community Forum:https://community.plotly.com/ — 官方论坛,活跃的问答和展示社区
- Dash User Group:Dash 框架的用户社区,与 Plotly.js 密切相关
- Stack Overflow:
plotly和plotly.js标签下有大量问答 - GitHub Issues:活跃的 bug 追踪和 feature 讨论
- Plotly Blog:https://plotly.com/blog/ — 官方案例和技术文章
适用场景
-
科学计算与学术研究:Plotly.js 最核心的使用场景。3D 曲面图、等高线图、点云图、向量场图等科学可视化类型在开源图表库中几乎无出其右。物理、化学、生物、气象等领域的科研人员广泛使用。
-
数据科学与分析看板:与 Python 数据科学生态(pandas、numpy、scipy)深度集成,是 Jupyter Notebook、JupyterLab 的默认交互式图表库。统计分析图表(箱线图、小提琴图、直方图、热力图)开箱即用。
-
金融数据可视化:K 线图、OHLC 图、瀑布图、漏斗图等专业金融图表类型,加上时间轴处理和交互式缩放,适合金融分析应用和交易系统展示。
-
地理信息系统(GIS)展示: choropleth 地图、scattergeo、densitymapbox 等地理可视化能力,结合 Mapbox 或自然地球数据,可以创建高质量的空间数据展示。
-
交互式数据探索工具:内置的缩放、框选、悬停、筛选、降维等交互能力,配合 Dash 框架可以构建完整的数据探索 Web 应用,无需深厚的前端开发经验。
-
教育与教学平台:声明式 API 降低了可视化教学门槛,学生可以专注于数据本身而非渲染细节。Plotly 的在线编辑器 Chart Studio 也常用于教学演示。
-
报告与出版图表:支持导出为高分辨率 PNG、SVG、PDF,图表质量达到出版级别。学术论文、技术报告、商业报告中的图表可以直接用 Plotly.js 生成。
开发与工程化
开发流程
本地开发环境搭建:
# 克隆仓库
git clone https://github.com/plotly/plotly.js.git
cd plotly.js
# 安装依赖
npm install
# 启动开发服务器(带热重载)
npm start
# 运行测试
npm test
# 构建生产版本
npm run build自定义构建(减小 Bundle 体积)
Plotly.js 完整包体积较大(~3.5MB),生产环境强烈建议使用预定义的 partial bundles 或自定义构建:
# 预定义 partial bundles(推荐)
npm install plotly.js-basic-dist-min # 基础图表 ~190KB gzipped
npm install plotly.js-cartesian-dist-min # 笛卡尔坐标系图表
npm install plotly.js-geo-dist-min # 地理图表
npm install plotly.js-gl3d-dist-min # 3D 图表
npm install plotly.js-finance-dist-min # 金融图表
npm install plotly.js-mapbox-dist-min # Mapbox 地图// 自定义构建(高级)
// 创建 custom-plotly.js
const Plotly = require('plotly.js/lib/core');
Plotly.register([
require('plotly.js/lib/scatter'),
require('plotly.js/lib/bar'),
require('plotly.js/lib/pie'),
]);
module.exports = Plotly;与 React 集成最佳实践
// 推荐:使用 react-plotly.js 的工厂函数控制 Plotly.js 实例
import { createPlotlyComponent } from 'react-plotly.js/factory';
import Plotly from 'plotly.js-basic-dist-min'; // 使用 partial bundle
const Plot = createPlotlyComponent(Plotly);
function MyChart({ data, layout }) {
return (
<Plot
data={data}
layout={{
...layout,
autosize: true,
}}
useResizeHandler
style={{ width: '100%', height: '100%' }}
config={{
responsive: true,
displayModeBar: false, // 根据需求控制工具栏
}}
/>
);
}CI/CD 集成
# GitHub Actions 示例
name: Plotly.js CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm run test
- run: npm run build静态导出(图片 / PDF)
// 方式一:使用内置 toImage(浏览器环境)
Plotly.toImage(figureDiv, {
format: 'png',
width: 1200,
height: 800,
scale: 2
}).then(url => {
// url 是 data URI,可以下载或嵌入
const link = document.createElement('a');
link.href = url;
link.download = 'chart.png';
link.click();
});
// 方式二:使用 kaleido(Node.js 服务端导出)
// npm install kaleido
// 通过 Plotly.py 的 write_image 接口使用(推荐 Python 环境)性能与安全
性能特点
优势:
- WebGL 渲染引擎(
scattergl、surface、mesh3d等)可以流畅渲染百万级数据点 - 增量渲染:使用
Plotly.restyle()和Plotly.relayout()进行局部更新,避免全量重绘 - 支持
transforms(聚合、排序、过滤)在渲染前对数据进行预处理
瓶颈:
- 完整包体积大(~3.5MB),首次加载慢——必须使用 partial bundles 或 CDN
- SVG 模式下超过 ~10K 数据点后性能急剧下降
- 多 trace 场景(>50 traces)下交互可能出现卡顿
scattergl在某些情况下(v2.35.x)存在性能回退问题
性能优化建议
// 1. 大数据集使用 WebGL trace 类型
const trace = {
x: largeXArray, // 100K+ 数据点
y: largeYArray,
type: 'scattergl', // 而非 'scatter'
mode: 'markers', // 减少渲染复杂度
marker: {
size: 2, // 小标记提升平移性能
opacity: 0.5,
}
};
// 2. 使用增量更新 API
Plotly.restyle('div', 'marker.color', ['red'], [0]); // 只更新颜色
Plotly.relayout('div', 'xaxis.range', [0, 100]); // 只更新轴范围
// 3. 禁用不必要的功能
const layout = {
hovermode: false, // 禁用悬停(大数据集时显著提升性能)
dragmode: 'zoom', // 限制拖拽模式
};
// 4. 使用 frames 动画时控制帧率
Plotly.animate('div', frameName, {
frame: { duration: 100, redraw: false },
transition: { duration: 0 }
});
// 5. 对静态图表禁用交互
const config = {
interactive: false, // 禁用所有交互
staticPlot: true, // 静态模式(最小化事件监听)
};安全注意事项
已知 CVE:
| CVE 编号 | 严重程度 | 影响版本 | 描述 | 修复版本 |
|---|---|---|---|---|
| CVE-2023-46308 | 中等 (CVSS 6.5) | < 2.25.2 | 原型链污染(__proto__ pollution),通过 expandObjectPaths 或 nestedProperty 可能被远程利用 | ≥ 2.25.2 |
| CVE-2016-XXXX | 中等 | < 1.16.0 | SVG XSS 漏洞,恶意数据可注入脚本和 CSS | ≥ 1.16.0 |
安全最佳实践:
- 始终使用最新版本(至少 ≥ 2.25.2,推荐 ≥ 3.x)
- 验证用户输入数据:Plotly.js 会直接渲染传入的数据,如果数据来源不可信,需要在传入前进行清洗和校验
- 使用
staticPlot: true展示不可信数据的图表——禁用所有交互和事件 - CSP 配置:设置严格的 Content-Security-Policy,限制 Plotly.js 的资源加载范围
- 注意 SVG XSS:Plotly.js 生成的 SVG 中可能包含
<script>标签,嵌入到 HTML 时需注意上下文
供应链安全:
- Plotly.js 本身未发现重大供应链攻击事件
- 建议使用 lockfile(
package-lock.json/pnpm-lock.yaml)锁定依赖版本 - 使用
npm audit定期检查依赖链中的已知漏洞 - 建议使用
plotly.js-dist-min而非源码包,减少构建链攻击面
技术对比
与主流图表库对比
| 特性 | Plotly.js | Chart.js | D3.js | ECharts | Highcharts |
|---|---|---|---|---|---|
| 定位 | 科学 / 全功能图表 | 轻量商业图表 | 底层可视化原语 | 商业图表 | 商业图表 |
| 渲染 | SVG + WebGL | Canvas | SVG / Canvas | Canvas (zrender) | SVG |
| Bundle 大小 | ~3.5MB (partial 可优化) | ~65KB | ~90KB | ~400KB | 商业授权 |
| 3D 支持 | ✅ 原生 3D | ❌ | ⚠️ 需手动实现 | ⚠️ 有限 | ❌ |
| 统计图表 | ✅ 极丰富 | ⚠️ 基础 | ⚠️ 需手动实现 | ⚠️ 中等 | ✅ 丰富 |
| 地图 | ✅ 内置 choropleth + Mapbox | ❌ | ⚠️ d3-geo | ✅ 内置 | ✅ 地图扩展 |
| 金融图表 | ✅ K 线 / OHLC | ⚠️ 插件 | ⚠️ 需手动实现 | ✅ 内置 | ✅ 高级图表 |
| 学习曲线 | 中等 | 低 | 高 | 中等 | 中等 |
| 声明式 API | ✅ JSON 配置 | ✅ 配置对象 | ❌ 命令式 | ✅ 配置对象 | ✅ 配置对象 |
| Python/R 绑定 | ✅ 官方支持 | ❌ | ❌ | ⚠️ pyecharts | ❌ |
| 交互能力 | ✅ 丰富 | ✅ 良好 | ✅ 需手动实现 | ✅ 良好 | ✅ 良好 |
| License | MIT | MIT | ISC / BSD | Apache 2.0 | 商业(非免费) |
| GitHub Stars | ~18.2K | ~67K | ~110K | ~62K | N/A |
| 最佳场景 | 科学 / 数据科学 | 前端 Web 图表 | 定制可视化 | 大数据看板 | 企业商业项目 |
选型决策指南
需要 3D 图表?
├─ 是 → Plotly.js(最佳选择)
└─ 否 → 需要科学统计图表?
├─ 是 → Plotly.js / D3.js
└─ 否 → Bundle 大小敏感?
├─ 是 → Chart.js / ECharts
└─ 否 → 需要最大灵活性?
├─ 是 → D3.js
└─ 否 → Plotly.js / ECharts
最佳实践
生产环境建议
1. Bundle 优化是第一优先级
Plotly.js 完整包 ~3.5MB,直接引入会严重影响页面加载性能。必须采取以下措施之一:
// 方案 A:使用 partial bundle(最简单)
import Plotly from 'plotly.js-basic-dist-min';
// 方案 B:自定义构建(最灵活)
const Plotly = require('plotly.js/lib/core');
Plotly.register([
require('plotly.js/lib/scatter'),
require('plotly.js/lib/bar'),
]);
// 方案 C:CDN + async 加载(适合非首屏图表)
// HTML 中:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/plotly.min.js" async></script>2. 使用增量更新 API
// ❌ 避免:全量重绘
Plotly.newPlot('div', newData, newLayout);
// ✅ 推荐:增量更新
Plotly.restyle('div', { 'marker.color': ['red'] }, [0]); // 更新样式
Plotly.relayout('div', { 'xaxis.range': [0, 100] }); // 更新布局
Plotly.update('div', dataUpdate, layoutUpdate); // 批量更新3. 正确处理响应式
// React 中使用 useResizeHandler
<Plot
data={data}
layout={layout}
useResizeHandler // 自动监听容器尺寸变化
style={{ width: '100%', height: '100%' }}
/>
// 原生 JS 中使用 responsive config
Plotly.newPlot('div', data, layout, { responsive: true });4. 合理管理事件监听
// ✅ 添加事件监听
const div = document.getElementById('myDiv');
div.on('plotly_click', (eventData) => {
console.log('Clicked:', eventData.points);
});
// ✅ 移除事件监听(防止内存泄漏)
div.removeAllListeners('plotly_click');
// ✅ 图表销毁时清理
Plotly.purge('myDiv'); // 完全销毁图表,释放所有资源5. 大数据集的分页加载
// 使用 transforms 进行前端分页
const layout = {
transforms: [{
type: 'filter',
target: 'x',
operation: 'range',
value: [0, 100] // 只显示 x 在 0-100 范围内的数据
}]
};
// 配合 sliders 实现时间轴分页
const layout = {
sliders: [{
steps: [
{ args: ['x', [0, 100]], label: '0-100' },
{ args: ['x', [100, 200]], label: '100-200' },
// ...
]
}]
};常见陷阱
| 陷阱 | 问题 | 解决方案 |
|---|---|---|
| 引入完整包 | Bundle 过大,页面加载慢 | 使用 plotly.js-*-dist-min partial bundle |
用 scatter 画 100K 点 | 页面卡死 | 改用 scattergl + WebGL |
反复调用 newPlot | 性能浪费 | 使用 restyle / relayout / update |
忘记 responsive: true | 窗口缩放图表不跟随 | 在 config 中设置 responsive: true |
| 直接传用户输入为数据 | XSS 风险 | 数据清洗后再传入 |
未调用 purge() | 内存泄漏 | 组件卸载时调用 Plotly.purge() |
| v2 升级 v3 不迁移 | API 报错 | 按 version-3-changes 文档迁移 |
技术局限与边界
已知限制
-
Bundle 体积大:完整包 ~3.5MB,即使使用 partial bundle 也在 200KB-1MB 之间。对于 Bundle 敏感的消费级 Web 应用(如营销页面、移动端 H5),Plotly.js 可能不是最佳选择。
-
学习曲线较陡:虽然声明式 API 比 D3.js 简单,但 Plotly.js 的属性体系极其庞大(数百个配置项),掌握高级用法(annotations、shapes、sliders、transforms)需要投入相当的学习成本。
-
定制化能力有天花板:Plotly.js 是"配置驱动"的图表库,所有视觉效果必须在预定义的属性框架内实现。如果需要完全自定义的视觉设计(如品牌定制图表、特殊动画效果),D3.js 的灵活性远优于 Plotly.js。
-
大数据量性能瓶颈:虽然有 WebGL 支持,但
scattergl在某些版本存在性能问题(社区反馈 v2.35.x 有回退)。极端大规模数据(>500 万点)建议使用专业的高性能方案(如 uPlot、SciChart)。 -
服务端渲染困难:Plotly.js 依赖浏览器 DOM 和 WebGL 环境,服务端渲染(SSR)需要 headless browser(如 Puppeteer)配合,增加了部署复杂度。
-
地图功能需要外部 Token:Mapbox 地图需要 Mapbox Access Token,使用自然地球数据的 choropleth 则精度有限。复杂 GIS 需求建议使用专门的地图库。
不适用场景
| 场景 | 推荐替代方案 | 原因 |
|---|---|---|
| 简单商业图表(仪表盘、后台) | Chart.js / ECharts | 更轻量、API 更简单 |
| 完全自定义的艺术化可视化 | D3.js | Plotly.js 的定制化有天花板 |
| 营销页面 / 落地页图表 | Chart.js / ApexCharts | 需要极小 Bundle 和首屏性能 |
| 海量数据实时渲染(>500 万点) | uPlot / SciChart / Deck.gl | Plotly.js 不是为这种规模设计的 |
| 专业 GIS 地图应用 | Mapbox GL / Leaflet / deck.gl | Plotly.js 的地图功能偏展示,不适合交互 GIS |
| 服务端静态图片生成 | Plotly.py + kaleido | 直接在后端生成,避免 headless browser |
v2 → v3 迁移注意事项
Plotly.js v3.0 是一次 Breaking Change 版本,主要废弃了历史遗留属性:
| 废弃项 | 替代方案 |
|---|---|
annotation.ref | 使用 annotation.xref 和 annotation.yref |
tickmode: 'autotick' | 使用 tickmode: 'auto' 或 'linear' |
bardir | 使用 orientation |
layout.scene.cameraposition | 使用 layout.scene.camera |
heatmapgl / pointcloud | 使用 heatmap / scattergl |
opacity(error bars) | 使用 color 的 alpha 通道 |
| jQuery 事件支持 | 使用原生 Plotly.js 事件 |
plot3dPixelRatio | 使用 plotGlPixelRatio |
title(纯字符串) | 使用 title.text |
titlefont 等扁平属性 | 使用嵌套对象 title.font |
zauto / zmin / zmax | 使用 cauto / cmin / cmax |
| Transforms | 已完全移除 |
学习资源
官方资源
- 官方文档(JavaScript):https://plotly.com/javascript/
- API 参考:https://plotly.com/javascript/plotlyjs-function-reference/
- v3 迁移指南:https://plotly.com/javascript/version-3-changes/
- 官方示例库:https://plotly.com/javascript/basic-charts/ (含 40+ 图表类型的完整示例)
- GitHub 仓库:https://github.com/plotly/plotly.js
- CHANGELOG:https://github.com/plotly/plotly.js/blob/master/CHANGELOG.md
教程与书籍
- Plotly 官方教程:https://plotly.com/javascript/getting-started/
- Plotly React 教程:https://plotly.com/javascript/react/
- Plotly.js 按图表类型教程:每种图表类型在官方文档中都有详细页面
- 《Interactive Data Visualization for the Web》(Scott Murray)—— 虽以 D3.js 为主,但对理解 Plotly.js 的数据驱动理念很有帮助
- Coursera / DataCamp:多个数据科学课程使用 Plotly.py(底层即 Plotly.js)进行教学
社区资源
- Plotly Community Forum:https://community.plotly.com/ — 官方论坛,活跃度极高
- Stack Overflow
[plotly]标签:https://stackoverflow.com/questions/tagged/plotly - GitHub Discussions:https://github.com/plotly/plotly.js/discussions
- Twitter/X:
@plotlygraphs— 官方账号 - Reddit:
r/dataviz、r/d3js等社区中 Plotly 讨论较多 - Plotly Blog:https://plotly.com/blog/ — 官方案例和技术博客
视频资源
- Plotly 官方 YouTube:https://www.youtube.com/@PlotlyInc
- Dash 教程(含 Plotly.js):大量 YouTube 教程覆盖 Dash + Plotly 的全栈开发
2026 年现状
版本与发布
截至 2026 年 7 月,Plotly.js 最新版本为 v3.7.0(2026 年 7 月 3 日发布)。v3.x 系列自 2025 年 2 月发布以来,已经迭代到 v3.7.0,保持着稳定的发布节奏(约每 1-2 个月一个版本)。
| 版本 | 发布时间 | 重要变更 |
|---|---|---|
| v3.0.0 | 2025 年 2 月 | 重大 Breaking Change,清除所有废弃 API |
| v3.1.0 | 2025 年 8 月 | 切换到 UN 地理边界;与 plotly.py 6.3 同步 |
| v3.2.0 | 2025 年 11 月 | 性能优化 |
| v3.5.0 | 2026 年 6 月 | 功能增强 |
| v3.7.0 | 2026 年 7 月 | 最新版本 |
社区活跃度
- GitHub Stars:~18,200+,稳步增长
- 活跃维护:每周有 commit 提交,issue 响应时间较短
- 社区论坛:Plotly Community Forum 持续活跃,每天都有新问题和技术讨论
- npm 下载量:~32 万+/周(plotly.js-dist-min),稳定
- 被依赖:~37,700 个 GitHub 仓库依赖 Plotly.js
发展趋势
-
v3.x 稳定迭代:v3.0 的 Breaking Change 已经完成,目前处于稳定的功能迭代期。未来版本将继续优化性能、增加图表类型、改善可访问性。
-
与 Dash 生态深度绑定:Plotly.js 作为 Dash(Python Web 框架)的底层图表引擎,两者的发展紧密关联。Dash 的企业版(Dash Enterprise)是 Plotly 公司的核心商业模式。
-
科学计算领域持续深耕:Plotly.js 在科学可视化领域的优势地位短期内难以被撼动。随着数据科学和 AI 的持续发展,对高质量科学可视化的需求只会增加。
-
WebGL 性能优化:社区对大规模数据渲染性能的需求持续增长,Plotly.js 团队在 WebGL 渲染引擎方面持续投入。
-
面临竞争:在前端图表库整体生态中,ECharts、Chart.js 等轻量级方案在商业应用领域持续增长;Deck.gl 等专注大数据可视化的库也在分流部分用户。但 Plotly.js 在科学计算和数据科学领域的核心地位依然稳固。
-
AI 与可视化结合:随着 LLM 和 AI 应用的发展,Plotly.js 的声明式 JSON API 天然适合 AI 代码生成场景(AI 可以直接输出 Plotly JSON 配置),这是一个值得关注的增长点。