Plotly compatibility
Holochart reads Plotly figures. This page says how much of plotly.js it covers, in two parts:
- Coverage: tables of trace types, attributes, layout keys and config options, generated by comparing the two libraries' attribute schemas.
- Known deviations: where Holochart has the attribute but draws or behaves differently.
To move an existing chart over, start with Coming from Plotly.
Coverage
The tables compare plotly.js' plot-schema.json with Holochart's own (plot-schema.json), attribute by attribute. An attribute is named by its path, such as marker.line.width or annotations[].text, and is:
- Supported when Holochart has the same path and accepts every value Plotly does;
- Partial when Holochart has the path but accepts less (fewer enumeration values or flags, one value where Plotly also takes an array), or accepts the attribute without acting on it;
- Missing when Holochart doesn't have the path. A missing attribute in a figure is ignored with a console warning.
This is a comparison of what the two libraries accept, not of what they draw. An attribute that is supported here can still behave differently; those cases are under Known deviations. Attributes that only Holochart has are not listed; they are in the attribute reference.
Compared with plotly.js 4.1.1.
| Supported | Partial | Missing | Total | |
|---|---|---|---|---|
| Trace types | 0 | 36 | 11 | 47 |
| Attributes of the 36 shared trace types | 4412 (80%) | 180 | 897 | 5489 |
| Top-level layout keys | 59 | 11 | 18 | 88 |
| Layout attributes | 1244 (73%) | 57 | 399 | 1700 |
| Config options | 13 | 2 | 18 | 33 |
A trace type or a layout key counts as supported only when every one of its Plotly attributes is, and as partial when Holochart has it but lacks or limits some of its attributes.
Holochart also has trace types that plotly.js does not: bar3d, chord, graph, graph3d.
chord, graph, graph3d need import '@mk7s/holochart/graph'.
Trace types
| Plotly trace type | Status | Supported | Partial | Missing | Notes |
|---|---|---|---|---|---|
bar | Partial | 179 (77%) | 16 | 36 | Attributes |
barpolar | Partial | 136 (87%) | 2 | 19 | Attributes |
box | Partial | 81 (77%) | 0 | 24 | Attributes |
candlestick | Partial | 53 (80%) | 0 | 13 | Attributes |
carpet | Missing | No carpet axes. | |||
choropleth | Partial | 110 (85%) | 2 | 18 | Attributes. Needs import '@mk7s/holochart/geo' |
choroplethmap | Missing | No tile maps (layout.map). | |||
cone | Partial | 125 (86%) | 2 | 18 | Attributes |
contour | Partial | 155 (85%) | 2 | 25 | Attributes |
contourcarpet | Missing | No carpet axes. | |||
densitymap | Missing | No tile maps (layout.map). | |||
funnel | Partial | 149 (77%) | 12 | 33 | Attributes |
funnelarea | Partial | 62 (64%) | 9 | 26 | Attributes |
heatmap | Partial | 132 (83%) | 2 | 25 | Attributes |
histogram | Partial | 191 (82%) | 7 | 36 | Attributes |
histogram2d | Partial | 130 (83%) | 2 | 25 | Attributes |
histogram2dcontour | Partial | 152 (85%) | 2 | 25 | Attributes |
icicle | Partial | 139 (74%) | 14 | 36 | Attributes |
image | Partial | 41 (77%) | 0 | 12 | Attributes |
indicator | Partial | 105 (83%) | 1 | 21 | Attributes |
isosurface | Partial | 142 (86%) | 2 | 21 | Attributes |
mesh3d | Partial | 130 (85%) | 2 | 21 | Attributes |
ohlc | Partial | 54 (81%) | 0 | 13 | Attributes |
parcats | Partial | 113 (84%) | 2 | 19 | Attributes |
parcoords | Partial | 122 (85%) | 2 | 20 | Attributes |
pie | Partial | 65 (59%) | 15 | 31 | Attributes |
quiver | Missing | ||||
sankey | Partial | 68 (58%) | 2 | 47 | Attributes |
scatter | Partial | 189 (79%) | 13 | 37 | Attributes |
scatter3d | Partial | 242 (85%) | 15 | 29 | Attributes |
scattercarpet | Missing | No carpet axes. | |||
scattergeo | Partial | 145 (82%) | 4 | 28 | Attributes. Needs import '@mk7s/holochart/geo' |
scattergl | Missing | Use scatter: every Holochart trace is drawn on the GPU. | |||
scattermap | Missing | No tile maps (layout.map). | |||
scatterpolar | Partial | 151 (82%) | 4 | 29 | Attributes |
scatterpolargl | Missing | Use scatterpolar: every Holochart trace is drawn on the GPU. | |||
scattersmith | Missing | No Smith charts (layout.smith). | |||
scatterternary | Missing | No ternary subplots (layout.ternary). | |||
splom | Partial | 136 (86%) | 2 | 20 | Attributes |
streamtube | Partial | 126 (86%) | 3 | 18 | Attributes |
sunburst | Partial | 131 (75%) | 11 | 32 | Attributes |
surface | Partial | 155 (86%) | 4 | 21 | Attributes |
table | Partial | 58 (75%) | 0 | 19 | Attributes |
treemap | Partial | 145 (74%) | 14 | 36 | Attributes |
violin | Partial | 78 (83%) | 0 | 16 | Attributes |
volume | Partial | 143 (86%) | 2 | 21 | Attributes |
waterfall | Partial | 79 (68%) | 10 | 27 | Attributes |
The numbers count attributes of the Plotly trace type.
Trace attributes
In every trace type
These gaps are the same in every shared trace type that has the attribute in Plotly, and are left out of the lists per trace type below.
Partial:
marker.colorbar.exponentformat,colorbar.exponentformat: without'SI extended'marker.colorbar.tickmode,colorbar.tickmode:syncaligns with the overlaid axis (reserved; behaves asauto)
Missing: hoverlabel.font.lineposition, hoverlabel.font.shadow, hoverlabel.font.style, hoverlabel.font.textcase, hoverlabel.font.variant, hoverlabel.font.weight, hoverlabel.showarrow, hovertemplatefallback, insidetextfont.lineposition, insidetextfont.shadow, insidetextfont.textcase, insidetextfont.variant, legendgrouptitle.font.lineposition, legendgrouptitle.font.shadow, legendgrouptitle.font.textcase, legendgrouptitle.font.variant, marker.colorbar.labelalias, marker.colorbar.tickformatstops.* (5), marker.pattern.path, outsidetextfont.lineposition, outsidetextfont.shadow, outsidetextfont.textcase, outsidetextfont.variant, textfont.lineposition, textfont.textcase, textfont.variant, texttemplatefallback, xcalendar, ycalendar, colorbar.labelalias, colorbar.tickformatstops.* (5)
By trace type
bar: 14 partial, 3 missing
Partial:
cliponaxis:falseis not drawn yet: labels are always clipped to the subploterror_x.traceref,error_x.tracerefminus,error_y.traceref,error_y.tracerefminus: Accepted for Plotly compatibility; has no effectinsidetextfont.family,insidetextfont.style,insidetextfont.weight,outsidetextfont.family,outsidetextfont.style,outsidetextfont.weight,textfont.family,textfont.style,textfont.weight: one value only, no array
Missing: textfont.shadow, xhoverformat, yhoverformat
box: 10 missing
Missing: selected.marker.size, unselected.marker.size, xhoverformat, xperiod, xperiod0, xperiodalignment, yhoverformat, yperiod, yperiod0, yperiodalignment
contour: 1 missing
Missing: textfont.shadow
funnel: 10 partial, 3 missing
Partial:
cliponaxis:falseis not drawn yet: labels are always clipped to the subplotinsidetextfont.family,insidetextfont.style,insidetextfont.weight,outsidetextfont.family,outsidetextfont.style,outsidetextfont.weight,textfont.family,textfont.style,textfont.weight: one value only, no array
Missing: textfont.shadow, xhoverformat, yhoverformat
funnelarea: 9 partial, 5 missing
Partial:
insidetextfont.family,insidetextfont.style,insidetextfont.weight,textfont.family,textfont.style,textfont.weight,title.font.family,title.font.style,title.font.weight: one value only, no array
Missing: textfont.shadow, title.font.lineposition, title.font.shadow, title.font.textcase, title.font.variant
heatmap: 1 missing
Missing: textfont.shadow
histogram: 5 partial, 3 missing
Partial:
cliponaxis:falseis not drawn yet: labels are always clipped to the subploterror_x.traceref,error_x.tracerefminus,error_y.traceref,error_y.tracerefminus: Accepted for Plotly compatibility; has no effect
Missing: textfont.shadow, xhoverformat, yhoverformat
histogram2d: 1 missing
Missing: textfont.shadow
histogram2dcontour: 1 missing
Missing: textfont.shadow
icicle: 12 partial, 5 missing
Partial:
insidetextfont.family,insidetextfont.style,insidetextfont.weight,outsidetextfont.family,outsidetextfont.style,outsidetextfont.weight,pathbar.textfont.family,pathbar.textfont.style,pathbar.textfont.weight,textfont.family,textfont.style,textfont.weight: one value only, no array
Missing: pathbar.textfont.lineposition, pathbar.textfont.shadow, pathbar.textfont.textcase, pathbar.textfont.variant, textfont.shadow
indicator: 1 partial, 17 missing
Partial:
gauge.axis.exponentformat: without'SI extended'
Missing: delta.font.lineposition, delta.font.shadow, delta.font.textcase, delta.font.variant, gauge.axis.labelalias, gauge.axis.tickfont.lineposition, gauge.axis.tickfont.shadow, gauge.axis.tickfont.textcase, gauge.axis.tickfont.variant, number.font.lineposition, number.font.shadow, number.font.textcase, number.font.variant, title.font.lineposition, title.font.shadow, title.font.textcase, title.font.variant
isosurface: 3 missing
Missing: contour.* (3)
mesh3d: 1 missing
Missing: zcalendar
parcats: 2 partial, 14 missing
Partial:
line.colorbar.exponentformat: without'SI extended'line.colorbar.tickmode:syncaligns with the overlaid axis (reserved; behaves asauto)
Missing: labelfont.lineposition, labelfont.textcase, labelfont.variant, line.coloraxis, line.colorbar.labelalias, line.colorbar.tickformatstops.* (5), line.hovertemplatefallback, tickfont.lineposition, tickfont.textcase, tickfont.variant
parcoords: 2 partial, 16 missing
Partial:
line.colorbar.exponentformat: without'SI extended'line.colorbar.tickmode:syncaligns with the overlaid axis (reserved; behaves asauto)
Missing: labelfont.lineposition, labelfont.textcase, labelfont.variant, line.coloraxis, line.colorbar.labelalias, line.colorbar.tickformatstops.* (5), rangefont.lineposition, rangefont.textcase, rangefont.variant, tickfont.lineposition, tickfont.textcase, tickfont.variant
pie: 15 partial, 6 missing
Partial:
insidetextfont.family,insidetextfont.style,insidetextfont.weight,legend,legendrank,outsidetextfont.family,outsidetextfont.style,outsidetextfont.weight,showlegend,textfont.family,textfont.style,textfont.weight,title.font.family,title.font.style,title.font.weight: one value only, no array
Missing: automargin, textfont.shadow, title.font.lineposition, title.font.shadow, title.font.textcase, title.font.variant
sankey: 2 partial, 33 missing
Partial:
link.hovertemplate,node.hovertemplate: one value only, no array
Missing: direction, link.hoverlabel.* (14), link.hovertemplatefallback, link.sort, node.hoverlabel.* (14), node.hovertemplatefallback, node.sort
scatter: 11 partial, 13 missing
Partial:
error_x.traceref,error_x.tracerefminus,error_y.traceref,error_y.tracerefminus: Accepted for Plotly compatibility; has no effectfillpattern.bgcolor,fillpattern.fgcolor,fillpattern.shape,fillpattern.size,fillpattern.solidity,textfont.style,textfont.weight: one value only, no array
Missing: alignmentgroup, cliponaxis, fillpattern.path, line.backoff, marker.angleref, marker.gradient.* (2), marker.line.dash, marker.standoff, offsetgroup, textfont.shadow, xhoverformat, yhoverformat
scatter3d: 13 partial, 7 missing
Partial:
error_x.traceref,error_x.tracerefminus,error_y.traceref,error_y.tracerefminus,error_z.traceref,error_z.tracerefminus: Accepted for Plotly compatibility; has no effecterror_x.width,error_y.width,error_z.width: Accepted for Plotly compatibility: 3D error bars are drawn without caps (Plotly draws them with a width of 0 by default)line.colorbar.exponentformat: without'SI extended'line.colorbar.tickmode:syncaligns with the overlaid axis (reserved; behaves asauto)textfont.style,textfont.weight: one value only, no array
Missing: line.colorbar.labelalias, line.colorbar.tickformatstops.* (5), zcalendar
scattergeo: 2 partial, 6 missing
Partial:
textfont.style,textfont.weight: one value only, no array
Missing: marker.angleref, marker.gradient.* (2), marker.line.dash, marker.standoff, textfont.shadow
scatterpolar: 2 partial, 7 missing
Partial:
textfont.style,textfont.weight: one value only, no array
Missing: line.backoff, marker.angleref, marker.gradient.* (2), marker.line.dash, marker.standoff, textfont.shadow
splom: 2 missing
Missing: xhoverformat, yhoverformat
streamtube: 1 partial
Partial:
hoverinfo: one value only, no array
sunburst: 9 partial, 1 missing
Partial:
insidetextfont.family,insidetextfont.style,insidetextfont.weight,outsidetextfont.family,outsidetextfont.style,outsidetextfont.weight,textfont.family,textfont.style,textfont.weight: one value only, no array
Missing: textfont.shadow
surface: 2 partial, 1 missing
Partial:
hovertext,text: value typedata_array(Plotly:string)
Missing: zcalendar
table: 8 missing
Missing: cells.font.lineposition, cells.font.shadow, cells.font.textcase, cells.font.variant, header.font.lineposition, header.font.shadow, header.font.textcase, header.font.variant
treemap: 12 partial, 5 missing
Partial:
insidetextfont.family,insidetextfont.style,insidetextfont.weight,outsidetextfont.family,outsidetextfont.style,outsidetextfont.weight,pathbar.textfont.family,pathbar.textfont.style,pathbar.textfont.weight,textfont.family,textfont.style,textfont.weight: one value only, no array
Missing: pathbar.textfont.lineposition, pathbar.textfont.shadow, pathbar.textfont.textcase, pathbar.textfont.variant, textfont.shadow
violin: 4 missing
Missing: selected.marker.size, unselected.marker.size, xhoverformat, yhoverformat
volume: 3 missing
Missing: contour.* (3)
waterfall: 10 partial, 3 missing
Partial:
cliponaxis:falseis not drawn yet: labels are always clipped to the subplotinsidetextfont.family,insidetextfont.style,insidetextfont.weight,outsidetextfont.family,outsidetextfont.style,outsidetextfont.weight,textfont.family,textfont.style,textfont.weight: one value only, no array
Missing: textfont.shadow, xhoverformat, yhoverformat
Layout
| Layout key | Status | Supported | Partial | Missing | Notes |
|---|---|---|---|---|---|
activeselection | Missing | 0 | 0 | 2 | |
activeshape | Supported | 2 | 0 | 0 | |
annotations | Partial | 49 | 12 | 0 | |
autosize | Supported | 1 | 0 | 0 | |
autotypenumbers | Missing | 0 | 0 | 1 | |
calendar | Missing | 0 | 0 | 1 | |
clickanywhere | Missing | 0 | 0 | 1 | |
clickmode | Supported | 1 | 0 | 0 | |
coloraxis | Partial | 68 | 2 | 6 | |
colorscale | Supported | 3 | 0 | 0 | |
colorway | Supported | 1 | 0 | 0 | |
computed | Missing | 0 | 0 | 1 | |
datarevision | Supported | 1 | 0 | 0 | |
dragmode | Supported | 1 | 0 | 0 | |
editrevision | Missing | 0 | 0 | 1 | |
font | Supported | 9 | 0 | 0 | |
geo | Supported | 57 | 0 | 0 | Needs import '@mk7s/holochart/geo' |
grid | Supported | 13 | 0 | 0 | |
height | Supported | 1 | 0 | 0 | |
hoveranywhere | Missing | 0 | 0 | 1 | |
hoverdistance | Supported | 1 | 0 | 0 | |
hoverlabel | Partial | 11 | 0 | 12 | |
hovermode | Supported | 1 | 0 | 0 | |
hoversort | Missing | 0 | 0 | 1 | |
hoversubplots | Missing | 0 | 0 | 1 | |
images | Supported | 15 | 0 | 0 | |
legend | Partial | 53 | 0 | 3 | |
map | Missing | 0 | 0 | 44 | |
margin | Supported | 6 | 0 | 0 | |
meta | Supported | 1 | 0 | 0 | |
minreducedheight | Missing | 0 | 0 | 1 | |
minreducedwidth | Missing | 0 | 0 | 1 | |
modebar | Partial | 4 | 3 | 0 | |
newselection | Missing | 0 | 0 | 4 | |
newshape | Partial | 25 | 2 | 15 | |
paper_bgcolor | Supported | 1 | 0 | 0 | |
plot_bgcolor | Supported | 1 | 0 | 0 | |
polar | Partial | 136 | 6 | 3 | |
scene | Partial | 292 | 22 | 6 | |
selectdirection | Supported | 1 | 0 | 0 | |
selectionrevision | Missing | 0 | 0 | 1 | |
selections | Supported | 14 | 0 | 0 | |
separators | Supported | 1 | 0 | 0 | |
shapes | Partial | 37 | 4 | 18 | |
showlegend | Supported | 1 | 0 | 0 | |
sliders | Supported | 55 | 0 | 0 | |
smith | Missing | 0 | 0 | 71 | |
spikedistance | Supported | 1 | 0 | 0 | |
template | Supported | 1 | 0 | 0 | |
ternary | Missing | 0 | 0 | 184 | |
title | Supported | 31 | 0 | 0 | |
transition | Supported | 3 | 0 | 0 | |
uirevision | Supported | 1 | 0 | 0 | |
uniformtext | Supported | 2 | 0 | 0 | |
updatemenus | Supported | 35 | 0 | 0 | |
width | Supported | 1 | 0 | 0 | |
xaxis | Partial | 155 | 3 | 9 | |
yaxis | Partial | 123 | 3 | 9 | |
barcornerradius | Supported | 1 | 0 | 0 | With bar, histogram traces |
bargap | Supported | 1 | 0 | 0 | With bar, barpolar, histogram traces |
bargroupgap | Supported | 1 | 0 | 0 | With bar, histogram traces |
barmode | Supported | 1 | 0 | 0 | With bar, barpolar, histogram traces |
barnorm | Supported | 1 | 0 | 0 | With bar, histogram traces |
boxgap | Supported | 1 | 0 | 0 | With box, candlestick traces |
boxgroupgap | Supported | 1 | 0 | 0 | With box, candlestick traces |
boxmode | Supported | 1 | 0 | 0 | With box, candlestick traces |
funnelgap | Supported | 1 | 0 | 0 | With funnel traces |
funnelgroupgap | Supported | 1 | 0 | 0 | With funnel traces |
funnelmode | Supported | 1 | 0 | 0 | With funnel traces |
extendfunnelareacolors | Supported | 1 | 0 | 0 | With funnelarea traces |
funnelareacolorway | Supported | 1 | 0 | 0 | With funnelarea traces |
hiddenlabels | Supported | 1 | 0 | 0 | With funnelarea, pie traces |
extendiciclecolors | Supported | 1 | 0 | 0 | With icicle traces |
iciclecolorway | Supported | 1 | 0 | 0 | With icicle traces |
extendpiecolors | Supported | 1 | 0 | 0 | With pie traces |
piecolorway | Supported | 1 | 0 | 0 | With pie traces |
scattergap | Missing | 0 | 0 | 1 | With scatter traces |
scattermode | Missing | 0 | 0 | 1 | With scatter traces |
extendsunburstcolors | Supported | 1 | 0 | 0 | With sunburst traces |
sunburstcolorway | Supported | 1 | 0 | 0 | With sunburst traces |
extendtreemapcolors | Supported | 1 | 0 | 0 | With treemap traces |
treemapcolorway | Supported | 1 | 0 | 0 | With treemap traces |
violingap | Supported | 1 | 0 | 0 | With violin traces |
violingroupgap | Supported | 1 | 0 | 0 | With violin traces |
violinmode | Supported | 1 | 0 | 0 | With violin traces |
waterfallgap | Supported | 1 | 0 | 0 | With waterfall traces |
waterfallgroupgap | Supported | 1 | 0 | 0 | With waterfall traces |
waterfallmode | Supported | 1 | 0 | 0 | With waterfall traces |
The numbers count the attributes under each key. xaxis and yaxis stand for every axis (xaxis2, …), and likewise scene, polar, coloraxis and legend.
annotations: 12 partial
Partial:
annotations[].hoverlabel.bgcolor,annotations[].hoverlabel.bordercolor,annotations[].hoverlabel.font.color,annotations[].hoverlabel.font.family,annotations[].hoverlabel.font.lineposition,annotations[].hoverlabel.font.shadow,annotations[].hoverlabel.font.size,annotations[].hoverlabel.font.style,annotations[].hoverlabel.font.textcase,annotations[].hoverlabel.font.variant,annotations[].hoverlabel.font.weight: Hover label style (declared; not drawn yet)annotations[].hovertext: Hover text (declared; hover labels for annotations are not drawn yet)
coloraxis: 2 partial, 6 missing
Partial:
coloraxis.colorbar.exponentformat: without'SI extended'coloraxis.colorbar.tickmode:syncaligns with the overlaid axis (reserved; behaves asauto)
Missing: coloraxis.colorbar.labelalias, coloraxis.colorbar.tickformatstops.* (5)
hoverlabel: 12 missing
Missing: hoverlabel.font.lineposition, hoverlabel.font.shadow, hoverlabel.font.style, hoverlabel.font.textcase, hoverlabel.font.variant, hoverlabel.font.weight, hoverlabel.grouptitlefont.lineposition, hoverlabel.grouptitlefont.shadow, hoverlabel.grouptitlefont.style, hoverlabel.grouptitlefont.textcase, hoverlabel.grouptitlefont.variant, hoverlabel.grouptitlefont.weight
legend: 3 missing
Missing: legend.groupdoubleclick, legend.titleclick, legend.titledoubleclick
modebar: 3 partial
Partial:
modebar.add,modebar.remove: value typeinfo_array(Plotly:string)modebar.uirevision: Accepted for Plotly compatibility; the modebar has no state of its own yet
newshape: 2 partial, 15 missing
Partial:
newshape.legendgroup: Legend group (declared; not used yet)newshape.showlegend: Legend entry for this shape (declared; not drawn yet)
Missing: newshape.label.texttemplatefallback, newshape.legend, newshape.legendgrouptitle.* (10), newshape.legendrank, newshape.legendwidth, newshape.name
polar: 6 partial, 3 missing
Partial:
polar.angularaxis.categoryorder,polar.radialaxis.categoryorder: without'geometric mean ascending','geometric mean descending'polar.angularaxis.exponentformat,polar.radialaxis.exponentformat: without'SI extended'polar.angularaxis.tickmode,polar.radialaxis.tickmode:syncaligns with the overlaid axis (reserved; behaves asauto)
Missing: polar.angularaxis.labelalias, polar.radialaxis.calendar, polar.radialaxis.labelalias
scene: 22 partial, 6 missing
Partial:
scene.annotations[].hoverlabel.bgcolor,scene.annotations[].hoverlabel.bordercolor,scene.annotations[].hoverlabel.font.color,scene.annotations[].hoverlabel.font.family,scene.annotations[].hoverlabel.font.lineposition,scene.annotations[].hoverlabel.font.shadow,scene.annotations[].hoverlabel.font.size,scene.annotations[].hoverlabel.font.style,scene.annotations[].hoverlabel.font.textcase,scene.annotations[].hoverlabel.font.variant,scene.annotations[].hoverlabel.font.weight: Hover label style (declared; not drawn yet)scene.annotations[].hovertext: Hover text (declared; hover labels for annotations are not drawn yet)scene.uirevision: Accepted for Plotly compatibility;layout.uirevisiongoverns themscene.xaxis.categoryorder,scene.yaxis.categoryorder,scene.zaxis.categoryorder: without'geometric mean ascending','geometric mean descending'scene.xaxis.exponentformat,scene.yaxis.exponentformat,scene.zaxis.exponentformat: without'SI extended'scene.xaxis.tickmode,scene.yaxis.tickmode,scene.zaxis.tickmode:syncaligns with the overlaid axis (reserved; behaves asauto)
Missing: scene.xaxis.calendar, scene.xaxis.labelalias, scene.yaxis.calendar, scene.yaxis.labelalias, scene.zaxis.calendar, scene.zaxis.labelalias
shapes: 4 partial, 18 missing
Partial:
shapes[].legendgroup: Legend group (declared; not used yet)shapes[].showlegend: Legend entry for this shape (declared; not drawn yet)shapes[].xref,shapes[].yref: one value only, no array
Missing: shapes[].label.texttemplatefallback, shapes[].legend, shapes[].legendgrouptitle.* (10), shapes[].legendrank, shapes[].legendwidth, shapes[].x0shift, shapes[].x1shift, shapes[].y0shift, shapes[].y1shift
xaxis: 3 partial, 9 missing
Partial:
xaxis.categoryorder: without'geometric mean ascending','geometric mean descending'xaxis.exponentformat: without'SI extended'xaxis.tickmode:syncaligns with the overlaid axis (reserved; behaves asauto)
Missing: xaxis.calendar, xaxis.insiderange, xaxis.labelalias, xaxis.modebardisable, xaxis.ticklabelindex, xaxis.tickson, xaxis.uirevision, xaxis.unifiedhovertitle.*, xaxis.zerolinelayer
yaxis: 3 partial, 9 missing
Partial:
yaxis.categoryorder: without'geometric mean ascending','geometric mean descending'yaxis.exponentformat: without'SI extended'yaxis.tickmode:syncaligns with the overlaid axis (reserved; behaves asauto)
Missing: yaxis.calendar, yaxis.insiderange, yaxis.labelalias, yaxis.modebardisable, yaxis.ticklabelindex, yaxis.tickson, yaxis.uirevision, yaxis.unifiedhovertitle.*, yaxis.zerolinelayer
Config
| Config option | Status | Notes |
|---|---|---|
autosizable | Missing | |
displaylogo | Partial | Accepted for Plotly compatibility and ignored: the modebar has no logo |
displayModeBar | Supported | |
displayNotifier | Missing | |
doubleClick | Supported | |
doubleClickDelay | Supported | |
editable | Supported | |
edits | Supported | |
editSelection | Missing | |
fillFrame | Missing | |
frameMargins | Missing | |
locale | Supported | |
locales | Supported | |
logging | Missing | |
modeBarButtons | Missing | |
modeBarButtonsToAdd | Supported | |
modeBarButtonsToRemove | Supported | |
notifyOnLogging | Missing | |
plotGlPixelRatio | Missing | |
plotlyServerURL | Missing | |
queueLength | Missing | |
responsive | Supported | |
scrollZoom | Partial | without 'gl3d' |
setBackground | Missing | |
showAxisDragHandles | Missing | |
showAxisRangeEntryBoxes | Missing | |
showSendToCloud | Missing | |
showTips | Missing | |
staticPlot | Supported | |
toImageButtonOptions | Supported | |
topojsonURL | Supported | |
typesetMath | Missing | |
watermark | Missing |
Known deviations
Holochart follows plotly.js' behavior unless there is a reason not to. These are the places where it differs on purpose, or where a Plotly behavior is not implemented yet. Each chart page has the full list for its trace type under "Plotly migration notes"; the main ones are collected here.
API and events
- The functional API takes an
HTMLElement, not an element id, and resolves to aChartobject instead of the element. Figure data and events are on the chart (chart.data,chart.on), not on the element. See Coming from Plotly. unhovercarries an emptypointslist. Plotly sends the points that were hovered.plotly_autosize,plotly_react,plotly_update,plotly_beforeexport,plotly_afterexport,plotly_exportfailandplotly_frameworkare not emitted.resizetakes the place ofplotly_autosize.- A
clicklistener that returnsfalsecancels a sunburst, treemap or icicle drill-down. The drill-down is arestyleofleveland emitsrestyle; Plotly animates it withanimate. - A
parcoordsbrush also writes the newconstraintrangeinto the figure; Plotly only emits the event. Aparcoordsaxis drop and atablecolumn drag emitrestyleonly when the order changed. - Selection events of polar subplots have no
rangeorlassoPoints, and a histogram's lists one point per selected sample where Plotly lists one per bin. toImageanddownloadImagemake PNG, JPEG and WebP images. There is no SVG export. Sliders, update menus and the modebar are page elements and are not in the image.- Promises of interrupted animations settle, rejecting with an
ErrornamedAnimationInterrupted. Plotly's may never settle, or reject withundefined. See Transitions.
Dates and text
- A JavaScript
Dateis shown at its UTC time. Plotly shows it at the browser's local time. Date strings without a UTC offset are read alike, without a time zone; Holochart converts a string with an offset (Z,+01:00) to UTC. There is nolayout.timezone, and no non-Gregorian calendar (xcalendar,layout.calendar). - Text is drawn from font files. A
font.familythat isn't registered is drawn with the built-in font, TeX Gyre Heros, on every platform, where Plotly uses the fonts installed on the computer. - LaTeX (
$…$) is not rendered. Unknown tags in text are shown literally. In titles, annotations, legends and axis labels a newline breaks the line, where Plotly shows a space. See Text. - In the default
en-USlocale,%x,%Xand%cfollow d3's US English (3/5/2024,12:30:00 PM); Plotly writes03/05/2024and12:30:00. See Locales.
Look
- Figures without
layout.templateget Holochart's dark default look, not Plotly's.template: 'plotly-classic'gives Plotly's. See Default look. - Default colorscales come from the template too: a figure that relied on Plotly's default
RdBuor Viridis gets the template's scale unless it setscolorscale.
Layout and interaction
- Shapes and images
abovethe traces are drawn below axis lines, tick labels, the legend and annotations; Plotly draws them over axis lines and tick labels. See Shapes. - Value-based
categoryordersortsmediannumerically (Plotly compares strings), and has no'geometric mean …'orders. xperiodandyperiodalignment also works on linear axes; in Plotly it applies to date axes only.- On axes with
rangebreaks, OHLC bars, candles and heatmap cells next to a break keep their full width; Plotly narrows them. - Maps move under a drag in
dragmode: 'zoom'as in'pan'; Plotly moves them in'pan'only.geo.uirevisionis not read (layout.uirevisionis). See Maps. - Pinch zoom works on cartesian subplots, and a vertical swipe scrolls the page in zoom mode. See Interaction.
- Sliders and update menus are DOM controls with keyboard support; their labels are plain text without Plotly's markup. See Controls.
- Transitions animate every trace type and follow autoranged axes while they move. See Transitions.
Maps
scattergeo,choroplethandlayout.geoare in a package the full bundle does not register: a figure with a map needsimport '@mk7s/holochart/geo'.- The base map is bundled Natural Earth data and nothing is fetched by default (
config.topojsonURLis empty; Plotly's default is its CDN). Coastlines and borders differ slightly from Plotly's files, and disputed borders are drawn by de facto control. - A scoped map keeps whole every country polygon that reaches into the scope's box; Plotly's scope files are cut at the box.
- The graticule keeps its last meridian unless it is the first one again; Plotly drops the last meridian of every map.
- There are no modebar buttons for maps yet. Tile maps (
layout.map) are not available. - See Maps for the rest.
3D scenes
- Tick labels and axis titles face the camera; Plotly draws them along the axes.
- A double-click resets the camera.
- Hover picks on the GPU and respects depth: you hover what you see.
- Holochart doesn't write the computed
aspectratioandaspectmodeback into the input layout. - Camera changes in
reactand in animation frames animate. - See 3D scenes for the rest.
Deviations by trace type
The main deviations of each trace type, with a link to its full migration notes.
scatter:scatterglisscatter.line.simplifydecimates per pixel column and re-runs on zoom. A'tonext…'fill keeps the trace order instead of moving the trace down. Nomarker.gradient,marker.angleref,marker.standoff,line.backofforscattermode: 'group'. Notes: scatter, lines, areas.bar: Nomarker.pattern.path. Default pattern colors are computed when drawing, so they are not infullData(see patterns). Notes: bar.pie: Hiding a slice re-flows the others without a transition. Outside labels don't push the margins. Notes: pie.table: Rows are virtualized. Cells of a wrapped row share one baseline.columnorderinfullDatais normalized to display ranks. Notes: table.histogram: Restyling one member of abingroupre-bins that trace only, until the next full recalculation. Noxbins.adaptive. Notes: histogram.histogram2d: A click point'spointNumberis a flat cell index, not[row, col]. Notes: histogram2d.box,violin: Noxperiod/yperiod. Violin scale groups are shared within a subplot, not across the figure, and the outline is not spline-smoothed. Notes: box, violin.splom: Default hover labels readlabel: valuefor both dimensions; Plotly shows(x, y). Notes: splom.parcoords: Unselected lines are drawn in the same pass as selected ones. Lines are 1 px wide. Noline.coloraxis. Notes: parcoords.parcats: A trace-levelhovertemplatealso applies to paths. Clicking a category band emits noclick. Notes: parcats.heatmap,image:zsmooth: 'fast'is bilinear filtering on the GPU. Heatmap grids over 4096 × 4096 cells are not drawn. Notes: heatmap, image.contour,histogram2dcontour: A value exactly on a level counts as above it (Plotly: below). Contour smoothing runs in grid space, so smoothed lines differ slightly. Notes: contour, histogram2dcontour.scatterpolar,barpolar:scatterpolarglisscatterpolar.thetaunit: 'gradians'converts gradians; plotly.js reads them as radians. Notes: scatterpolar, barpolar.candlestick,ohlc: Inboxmode: 'group', candles group with candlesticks only, not with boxes.%{change}and%{changepercent}are added tohovertemplate. Notes: candlestick, ohlc.waterfall,funnel: Inbetweenmode, waterfall bars are not lengthened by the connector width. A funnel'smarker.opacityis applied, and%{percentTotal}is formatted as a percentage. Notes: waterfall, funnel.indicator: Transitions lay the number out for every in-between value, and animatedelta.reference. Notes: indicator.sunburst,treemap,icicle: Labels fade in at the end of a drill-down instead of moving with their sectors. Treemap and icicle labels wrap before they shrink. Notes: sunburst, treemap, icicle.sankey: Cyclic graphs are laid out and drawn with loops, so node placement can differ. Nonode.hoverlabelorlink.hoverlabel.'snap'drags have no force simulation. Notes: sankey.scattergeo:'ISO-3'codes match in any case. Unmatched locations are named in one warning. Atoselffill takes the smaller of the two regions its path bounds. Nomarker.gradient,marker.angleref,marker.standofformarker.line.dash. Notes: scattergeo.choropleth: Ageojsonwound the RFC 7946 way is rewound, with a warning. With'geojson-id', a location given twice is drawn twice. The hover label falls back to the pointer when the region's label point is hidden. Notes: choropleth.scatter3d: Projections are camera-facing sprites on the walls; Plotly flattens them onto the wall. The error bars'widthis ignored. Notes: scatter3d.surface: The grid is drawn as given; Plotly resamples small grids for smoother shading. Contour levels don't follow the camera. Hover reportspointNumberas[row, column]. Notes: surface.mesh3d,cone: Cone sizes andalphahullscale by the trace's own data span, not by the span of every trace in the scene. A mesh'scontour.widthis honored. Notes: mesh3d, cone.streamtube: Tubes are integrated with Runge–Kutta (RK4) steps instead of Euler steps, so curved flow is followed accurately. Colors use each sample's own norm. Notes: streamtube.isosurface,volume: The triangles are Plotly's. Hover snaps to the nearest grid point. Nocontour. Notes: isosurface, volume.
Express lists the differences from plotly.express.
How the tables are made
pnpm --filter @mk7s/holochart-docs gen:compat runs apps/docs/scripts/gen-plotly-compat.ts, which the docs build runs too. It reads Holochart's schema as the docs build generates it from the registered trace types and components, and a reduced copy of plotly.js' dist/plot-schema.json (attribute names, value types and enumeration values; plotly.js is MIT licensed) kept in apps/docs/scripts/plotly-compat/. The plotly.js version is stated at the top of the coverage section.