Plotly.js Multi-Version Support (v1, v2, v3)
plotly-js
Use this skill when working with Plotly.js in JavaScript/TypeScript frontend projects. Covers debugging Plotly code, implementing specific chart types (candlestick, 3D surfaces, choropleth maps), React integration with react-plotly.js, and version migration between v1/v2/v3. Trigger when users me...
SKILL.md
Full skill instructions
Plotly.js Multi-Version Support (v1, v2, v3)
Rules (ALWAYS follow)
- NEVER write Plotly code without first detecting the version from
package.jsonor CDN script tags - If the version cannot be determined, ASK the user before writing any code
- Apply ONLY patterns valid for the detected version — v3 removed several APIs that v1/v2 support
- Check for competing chart libraries first — if the project already uses Chart.js, Recharts, Highcharts, ECharts, Victory, ApexCharts, Nivo, or Visx for its charts, ask the user whether they want to use Plotly instead or alongside the existing library
- Inform the user about version limitations — if the detected version is v1 or v2, proactively mention what features they're missing and whether upgrading would be beneficial for their use case
- When using React, check for
react-plotly.js— if not present, recommend installing it rather than doing manual DOM manipulation
Version Detection
Always run this first when starting work with Plotly.js:
# Check npm dependency
grep -E "\"plotly.js|\"react-plotly" package.json
# Also check for CDN usage in HTML files
grep -r "cdn.plot.ly/plotly\|plotly-latest\|plotly\.js" --include="*.html" .
Extract the major version number:
const plotlyVersion = pkg.dependencies?.['plotly.js'] ||
pkg.devDependencies?.['plotly.js'] ||
pkg.dependencies?.['plotly.js-dist'] ||
pkg.dependencies?.['plotly.js-dist-min'];
const major = parseInt(plotlyVersion?.match(/\d+/)?.[0] ?? '');
Also check for partial bundles — Plotly ships several:
plotly.js— full bundle (~3.5 MB minified)plotly.js-dist/plotly.js-dist-min— pre-bundled full distributionplotly.js-basic-dist— basic charts only (scatter, bar, pie)plotly.js-cartesian-dist— cartesian chartsplotly.js-geo-dist— geographic chartsplotly.js-gl3d-dist— WebGL 3D chartsplotly.js-gl2d-dist— WebGL 2D charts (removed in v3)plotly.js-mapbox-dist— mapbox charts (deprecated in v3)plotly.js-finance-dist— financial charts
The partial bundle determines which chart types are available. If the user tries to use a chart type not in their bundle, suggest either switching to the full bundle or the appropriate partial bundle.
Competing Library Detection
Before suggesting Plotly.js patterns, scan for existing charting libraries:
grep -E "\"chart\.js\"|\"recharts\"|\"victory\"|\"highcharts\"|\"apexcharts\"|\"echarts\"|\"@nivo\"|\"visx\"|\"d3\"" package.json
If a competing library is found, ask the user before proceeding. Plotly can coexist with other libraries, but mixing chart libraries in the same project adds bundle size and inconsistency.
Exception: d3 as a dependency does not count as a competing chart library — Plotly.js itself uses D3 internally. Only flag D3 if the user is using it directly for charting (check for d3.select patterns creating SVG charts).
Version-Specific Breaking Changes
Plotly.js v1.x (Legacy)
- Title: Accepts plain string
title: "My Chart"— this is the original format - Transforms: Supported (
aggregate,filter,groupby,sort) - jQuery events:
$(graphDiv).on('plotly_click', ...)works - AMD/UMD: Bundle supports RequireJS and AMD loaders
- GL traces:
pointcloudandheatmapglavailable - Mapbox: Full
scattermapbox,choroplethmapbox,densitymapboxsupport - Build target: ES5
- Note: v1 is no longer maintained. Security patches and new features only land in v2+/v3+
Plotly.js v2.x
Key changes from v1:
- Title format:
title: { text: "My Chart" }is now the canonical form. Plain strings still work but are deprecated mapboxtraces deprecated (v2.35+): Newmaptraces introduced (scattermap,choroplethmap,densitymap) using MapLibre instead of Mapbox GL JS — no access token neededsubtitleadded (v2.34+):layout.title.subtitlefor chart subtitles- Multiple legends (v2.22+):
legend2,legend3, etc. in layout zorder(v2.31+): Control stacking order of cartesian traces- Bar corner radius (v2.29+):
marker.cornerradiusfor rounded bars insiderange(v2.27+): Avoid tick label overlap on inner axes- Shape labels (v2.19+):
labelattribute on shapes withtexttemplate - Container-referenced legends (v2.23+):
legend.xref/yref="container" - TypeScript types: Available via
@types/plotly.js(community maintained)
// v2 title (canonical form)
Plotly.newPlot('div', data, {
title: { text: 'Revenue by Quarter', font: { size: 20 } }
});
// v2.35+ map traces (replaces mapbox)
{
type: 'scattermap',
lat: [45.5, 46.0],
lon: [-73.5, -74.0],
mode: 'markers'
}
Plotly.js v3.x (Current — latest: 3.4.0)
Major breaking changes from v2:
1. String Titles Removed (CRITICAL)
// v1-v2: Plain string works
layout: { title: 'My Chart' }
// v3: MUST use object form — string will be IGNORED
layout: { title: { text: 'My Chart' } }
// Also removed: titlefont, titleposition, titleside, titleoffset
// Use: title.font, title.position, title.side, title.offset
2. Transforms Removed (CRITICAL)
// v1-v2: Transforms API available
traces: [{
x: rawData.x,
y: rawData.y,
transforms: [{ type: 'filter', target: 'y', operation: '>', value: 10 }]
}]
// v3: Pre-process data in JavaScript instead
const filtered = rawData.filter(d => d.y > 10);
traces: [{ x: filtered.map(d => d.x), y: filtered.map(d => d.y) }]
3. Deprecated Trace Types Removed
pointcloud— usescatterglinsteadheatmapgl— useheatmapinsteadgl2dsubplot type removed
4. Deprecated Attributes Removed
| Removed | Replacement |
|---|---|
bardir | orientation: 'h' |
annotation.ref | annotation.xref + annotation.yref |
error bar opacity | Use alpha channel in error bar color |
gl3d.cameraposition | gl3d.camera |
plot3dPixelRatio (config) | Removed from config |
surface.zauto/zmin/zmax | surface.cmin/cmax/cauto |
autotick on axes | tickmode: 'auto' |
5. jQuery and AMD Support Removed
// v1-v2: jQuery events worked
$(gd).on('plotly_click', handler);
// v3: Only native events
gd.on('plotly_click', handler);
// v1-v2: AMD/RequireJS loading worked
// v3: Only ES modules and CommonJS (require)
6. Mapbox Deprecated
// v2.35+/v3: Use map traces (MapLibre) instead of mapbox
// scattermapbox → scattermap
// choroplethmapbox → choroplethmap
// densitymapbox → densitymap
// No access token needed for map traces
7. CSP-Friendly
v3 removed inline styles that broke strict Content Security Policy setups. If your v2 project has CSP issues with Plotly, upgrading to v3 resolves them.
8. New Features in v3
layout.title.subtitle: Subtitles with independent font stylinghovertemplatefallback/texttemplatefallback(v3.2+): Fallback templatespattern.path(v3.1+): Custom SVG path patternszerolinelayer(v3.1+): Draw zero line above traceshoverlabel.showarrow(v3.1+): Hide hover label caret- Dashed marker lines (v3.4+): Scatter plot marker line dash styles
- Legend title click (v3.4+): Click legend title to toggle all traces
hovertemplatefor candlestick/ohlc (v3.3+)- Keyboard-accessible modebar (v3.1+)
Quick Version Reference
| Feature | v1.x | v2.x | v3.x |
|---|---|---|---|
| String title | Yes | Yes (deprecated) | Removed |
title.subtitle | No | Yes (v2.34+) | Yes |
| Transforms | Yes | Yes | Removed |
| jQuery events | Yes | Yes | Removed |
| AMD/UMD | Yes | Yes | Removed |
| pointcloud / heatmapgl | Yes | Deprecated | Removed |
| mapbox traces | Yes | Deprecated (v2.35+) | Deprecated (use map) |
| map traces (MapLibre) | No | Yes (v2.35+) | Yes |
| Multiple legends | No | Yes (v2.22+) | Yes |
| zorder | No | Yes (v2.31+) | Yes |
| Bar corner radius | No | Yes (v2.29+) | Yes |
| Shape labels | No | Yes (v2.19+) | Yes |
| CSP-safe (no inline styles) | No | No | Yes |
| ES module build (esbuild) | No | No | Yes |
| pattern.path | No | No | Yes (v3.1+) |
| Maintained | No | Security only | Active |
Core API Functions
These are the main Plotly.js functions — they are consistent across v1, v2, and v3:
// Create a new plot (replaces any existing one)
Plotly.newPlot(graphDiv, data, layout, config);
// Efficiently update a plot (preferred for React and dynamic updates)
Plotly.react(graphDiv, data, layout, config);
// Update trace data in-place
Plotly.restyle(graphDiv, update, traceIndices);
// Update layout in-place
Plotly.relayout(graphDiv, update);
// Combined restyle + relayout
Plotly.update(graphDiv, dataUpdate, layoutUpdate, traceIndices);
// Add traces
Plotly.addTraces(graphDiv, traces, newIndices);
// Delete traces
Plotly.deleteTraces(graphDiv, indices);
// Move traces (reorder)
Plotly.moveTraces(graphDiv, currentIndices, newIndices);
// Animate
Plotly.animate(graphDiv, frameOrGroupOrFrameList, animationOpts);
// Purge (destroy plot, free memory)
Plotly.purge(graphDiv);
// Export to image
Plotly.toImage(graphDiv, opts); // returns Promise<dataURL>
Plotly.downloadImage(graphDiv, opts); // triggers download
// Get plot data
Plotly.makeTemplate(graphDiv); // extract template from existing plot
Plotly.react vs Plotly.newPlot: Prefer Plotly.react for updates — it diffs the data and only redraws what changed. newPlot destroys and recreates the entire plot. React wrappers (react-plotly.js) use Plotly.react internally.
Version Upgrade Recommendations
When informing the user about their version:
If v1.x: "Your project uses Plotly.js v1 which is no longer maintained. v3 is the current release with active development, security patches, and significant new features (subtitles, map traces without access tokens, CSP support, pattern fills, better performance). Consider upgrading — see the migration guide for a step-by-step checklist."
If v2.x: "Your project uses Plotly.js v2. v3 is the current release with improved CSP support, modern ES builds (smaller bundles), and new features. The main breaking changes are: string titles must become { text: '...' }, transforms are removed (pre-process data in JS), and jQuery/AMD support is dropped. If you rely on transforms, you'll need to refactor data processing. See the migration guide for details."
If v3.x but not latest: Mention specific features added in newer v3.x releases that may be relevant to the user's task.
Additional Resources
For a comprehensive reference of all 40+ chart types with code examples, see:
For React integration with react-plotly.js (props, state management, custom bundles), see:
For detailed migration steps from v1→v2 and v2→v3 with checklists, see:
For common patterns (responsive charts, events, animations, subplots, theming, export), see:
Official Plotly docs:
