Express API
@mk7s/holochart-express is Holochart's plotly.express: one call turns a table into a complete figure, with one trace per group, a legend, axis titles, hover text, facets, animation frames and marginal distributions. It follows plotly.py's px closely (the same arguments in camelCase, the same trace structure), so figures from px code translate line by line.
express/gapminderimport { createChart } from '@mk7s/holochart';
import hx from '@mk7s/holochart-express';
const rows = [
{ country: 'Chad', continent: 'Africa', year: 2007, lifeExp: 50.7, gdpPercap: 1704, pop: 1.0e7 },
{
country: 'Peru',
continent: 'Americas',
year: 2007,
lifeExp: 71.4,
gdpPercap: 7409,
pop: 2.8e7,
},
];
const figure = hx.scatter(rows, {
x: 'gdpPercap',
y: 'lifeExp',
color: 'continent',
size: 'pop',
hoverName: 'country',
logX: true,
});
createChart(el, figure);Two ways to call
Every function takes the data and an options object, and returns the figure as plain data ({ data, layout, frames? }), so you can adjust it before drawing:
import { createChart } from '@mk7s/holochart';
import hx from '@mk7s/holochart-express';
declare const rows: object[]; // [{ total_bill: 16.99, sex: 'Female', … }, …]
const figure = hx.histogram(rows, { x: 'total_bill', color: 'sex' });
figure.layout['bargap'] = 0.05;
createChart(el, figure);Given an element first, it draws the figure there with newPlot and resolves with the chart:
import hx from '@mk7s/holochart-express';
declare const rows: object[];
const chart = await hx.histogram(el, rows, { x: 'total_bill', color: 'sex' });The figure is ordinary Holochart JSON: createChart, react, chart.animate, chartToJSON and the rest of the API work on it as on any figure.
What to register
Express only builds figures; drawing them needs their trace types and components registered. The @mk7s/holochart bundle registers everything and also carries Express as the express namespace (Holochart.express in the script-tag build), so with the bundle you need only one import:
import { express as hx } from '@mk7s/holochart';
declare const rows: object[];
const chart = await hx.scatter(el, rows, { x: 'total_bill', y: 'tip', color: 'day' });With partial bundles, register what the figures use:
import { register } from '@mk7s/holochart-runtime';
import { basicTraces } from '@mk7s/holochart-traces-basic';
import { statsTraces } from '@mk7s/holochart-traces-stats';
import { builtinComponents } from '@mk7s/holochart-components';
register(...basicTraces, ...statsTraces, ...builtinComponents);scatter, line, area, bar, timeline, pie, ecdf and trendlines use traces-basic; histogram, box, violin, strip, the densities, scatterMatrix, parallelCoordinates, parallelCategories, marginals and ff.distplot use traces-stats too; imshow uses the heatmap and image traces of traces-sci, and scatterPolar, linePolar and barPolar its polar traces (register(...sciTraces)); funnel and funnelArea use traces-finance (register(...financeTraces)); sunburst, treemap and icicle use traces-hier (register(...hierTraces)); scatter3d and line3d use the scatter3d trace and the 3D scene of traces-3d (register(...traces3d) from @mk7s/holochart-traces-3d; in the script-tag build, load holochart-3d.iife.min.js after holochart.iife.min.js). Facet labels, legends, colorbars and animation controls are components.
The maps are the exception to "the bundle registers everything": scatterGeo, lineGeo and choropleth use the geo subplot and traces of @mk7s/holochart-traces-geo, which the bundle leaves out so that apps without a map do not pay for it. Add import '@mk7s/holochart/geo' next to the bundle's import, or register(...tracesGeo) in a partial bundle (Maps).
Network graphs are left out the same way: graph and chord use the traces of @mk7s/holochart-traces-graph. Add import '@mk7s/holochart/graph', or register(...tracesGraph) in a partial bundle (Networks). adjacencyMatrix is a heatmap of traces-sci and needs neither.
Functions
| Function | plotly.py | Traces |
|---|---|---|
scatter | px.scatter | scatter (markers) |
scatter + trendline | px.scatter(trendline=…) | scatter (lines) |
line | px.line | scatter (lines) |
area | px.area | scatter (stacked, filled) |
bar | px.bar | bar |
timeline | px.timeline | bar (horizontal, date axis) |
pie | px.pie | pie |
funnel | px.funnel | funnel |
funnelArea | px.funnel_area | funnelarea |
histogram | px.histogram | histogram |
box, violin, strip | px.box, px.violin, … | box, violin |
ecdf | px.ecdf | scatter (steps) |
densityHeatmap | px.density_heatmap | histogram2d |
densityContour | px.density_contour | histogram2dcontour |
scatterMatrix | px.scatter_matrix | splom |
parallelCoordinates | px.parallel_coordinates | parcoords |
parallelCategories | px.parallel_categories | parcats |
ff.distplot | ff.create_distplot | histogram, scatter |
imshow | px.imshow | heatmap, image |
scatterPolar | px.scatter_polar | scatterpolar (markers) |
linePolar | px.line_polar | scatterpolar (lines) |
barPolar | px.bar_polar | barpolar |
scatter3d | px.scatter_3d | scatter3d (markers) |
line3d | px.line_3d | scatter3d (lines) |
scatterGeo | px.scatter_geo | scattergeo (markers) |
lineGeo | px.line_geo | scattergeo (lines) |
choropleth | px.choropleth | choropleth |
graph | — | graph |
chord | — | chord |
adjacencyMatrix | — | heatmap |
sunburst | px.sunburst | sunburst |
treemap | px.treemap | treemap |
icicle | px.icicle | icicle |
getTrendlineResults | px.get_trendline_results | — |
data.fromCSV | pd.read_csv | — |
The rest of plotly.py's catalogue (ternary, the tile maps scatter_map, choropleth_map and density_map) follows with its trace types.
Options every function shares
| Option | px | What it does |
|---|---|---|
labels | labels | Display names of columns: axis titles, hover lines, legend, facets |
title | title | layout.title.text |
template | template | layout.template; also where colors and symbols come from |
width, height | width, height | Figure size |
categoryOrders | category_orders | Value orders of columns: traces, legend, facets, frames, axes |
color, symbol, lineDash, … | color, symbol, line_dash, … | Grouping columns |
facetRow, facetCol, facetColWrap | facet_row, facet_col, … | Subplot grids |
animationFrame, animationGroup | animation_frame, animation_group | Frames with a player |
hoverName, hoverData, customData | hover_name, hover_data, … | Hover text |
logX, logY, rangeX, rangeY | log_x, log_y, range_x, … | Axis types and ranges, on every facet |
Column options take a column name or an array of values (as long as the data); see Data input.
The default look
Express leaves layout.template unset unless you pass template, so figures render in Holochart's default holochart look. Colors, marker symbols and line dashes are still written into each trace, as px does, taken from the template the figure will use: the default template, or the template option. Pass template: 'plotly-classic' (or call setDefaultTemplate('plotly-classic') before building figures) for Plotly's colors.
Differences from plotly.express
- Options are camelCase (
color_discrete_map→colorDiscreteMap); data are rows, columns, an Arrow table or a parsed CSV instead of a pandas DataFrame; results are plain figure objects, notgo.Figureinstances. - Wide-form data (a list of columns for
y) is not supported yet; use long-form rows. - Scatter traces are always
scatter(px switches toscatterglabove 1000 rows; every Holochart trace is GPU-rendered). - Animated figures keep every group's trace in every frame (empty when a group has no rows that frame), so frames line up with the figure's traces by index, and axis ranges are fixed across frames when not given (details).
- Wrapped facets drop the empty cells at the end of the last row and keep tick labels on the lowest cell of each column.
- Facet labels are named annotations (
name: 'facet label'), so the default look's top legend makes room for them. parallelCoordinatesandparallelCategoriesput their colorscale on the trace (line.colorscale,line.showscale) instead oflayout.coloraxis.- Fill patterns (
pattern) group traces, name them and hatch their bars (see Patterns & textures). aggonbar,lineandareais a Holochart extension; px draws every row there.- Trendline fit results live beside the figure object (
getTrendlineResults), not in its JSON, and are an array of typed results rather than a DataFrame of statsmodels objects. Anoveralltrendline skips marginal subplots (px also draws it there). barPolar'sbarmode: 'overlay'setslayout.polar.barmode(plotly.js ignores px's top-levelbarmodeon polar bars, which always stack there);barnormisn't offered, as polar bars don't read it.scatter3dandline3dfix the scene's axis ranges over every frame of an animated figure (px leaves that torange_x/range_y/range_z), as the 2D and polar functions do.- The maps (
scatterGeo,lineGeo,choropleth) leavegeo.fitboundsunset, so Holochart fits the view to the data (px shows the whole scope), except withanimationFrame, where they set it tofalseso the view holds still. Achoroplethcolored by a column that is not numeric keeps the usuallegendgroupand one legend item per value (px gives every such trace its own item), andchoroplethtakes nolat/lon(px accepts them, and the trace has neither). graph,chordandadjacencyMatrixhave no counterpart in px. They read two tables (edges and nodes) where every px function reads one, make one trace per figure, and take no facets or animation frames.chordandadjacencyMatrixalso take a matrix, asimshowdoes.- Not yet:
marginalonline/bar,text_auto(except onimshow),render_mode,color_discrete_mapgiven as a Plotlypx.colorsobject,px.Constant.