Skip to content

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.

Loading example…
express/gapminder
ts
import { 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:

ts
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:

ts
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:

ts
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:

ts
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 ​

Functionplotly.pyTraces
scatterpx.scatterscatter (markers)
scatter + trendlinepx.scatter(trendline=…)scatter (lines)
linepx.linescatter (lines)
areapx.areascatter (stacked, filled)
barpx.barbar
timelinepx.timelinebar (horizontal, date axis)
piepx.piepie
funnelpx.funnelfunnel
funnelAreapx.funnel_areafunnelarea
histogrampx.histogramhistogram
box, violin, strippx.box, px.violin, …box, violin
ecdfpx.ecdfscatter (steps)
densityHeatmappx.density_heatmaphistogram2d
densityContourpx.density_contourhistogram2dcontour
scatterMatrixpx.scatter_matrixsplom
parallelCoordinatespx.parallel_coordinatesparcoords
parallelCategoriespx.parallel_categoriesparcats
ff.distplotff.create_distplothistogram, scatter
imshowpx.imshowheatmap, image
scatterPolarpx.scatter_polarscatterpolar (markers)
linePolarpx.line_polarscatterpolar (lines)
barPolarpx.bar_polarbarpolar
scatter3dpx.scatter_3dscatter3d (markers)
line3dpx.line_3dscatter3d (lines)
scatterGeopx.scatter_geoscattergeo (markers)
lineGeopx.line_geoscattergeo (lines)
choroplethpx.choroplethchoropleth
graph—graph
chord—chord
adjacencyMatrix—heatmap
sunburstpx.sunburstsunburst
treemappx.treemaptreemap
iciclepx.icicleicicle
getTrendlineResultspx.get_trendline_results—
data.fromCSVpd.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 ​

OptionpxWhat it does
labelslabelsDisplay names of columns: axis titles, hover lines, legend, facets
titletitlelayout.title.text
templatetemplatelayout.template; also where colors and symbols come from
width, heightwidth, heightFigure size
categoryOrderscategory_ordersValue orders of columns: traces, legend, facets, frames, axes
color, symbol, lineDash, …color, symbol, line_dash, …Grouping columns
facetRow, facetCol, facetColWrapfacet_row, facet_col, …Subplot grids
animationFrame, animationGroupanimation_frame, animation_groupFrames with a player
hoverName, hoverData, customDatahover_name, hover_data, …Hover text
logX, logY, rangeX, rangeYlog_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, not go.Figure instances.
  • Wide-form data (a list of columns for y) is not supported yet; use long-form rows.
  • Scatter traces are always scatter (px switches to scattergl above 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.
  • parallelCoordinates and parallelCategories put their colorscale on the trace (line.colorscale, line.showscale) instead of layout.coloraxis.
  • Fill patterns (pattern) group traces, name them and hatch their bars (see Patterns & textures).
  • agg on bar, line and area is 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. An overall trendline skips marginal subplots (px also draws it there).
  • barPolar's barmode: 'overlay' sets layout.polar.barmode (plotly.js ignores px's top-level barmode on polar bars, which always stack there); barnorm isn't offered, as polar bars don't read it.
  • scatter3d and line3d fix the scene's axis ranges over every frame of an animated figure (px leaves that to range_x / range_y / range_z), as the 2D and polar functions do.
  • The maps (scatterGeo, lineGeo, choropleth) leave geo.fitbounds unset, so Holochart fits the view to the data (px shows the whole scope), except with animationFrame, where they set it to false so the view holds still. A choropleth colored by a column that is not numeric keeps the usual legendgroup and one legend item per value (px gives every such trace its own item), and choropleth takes no lat / lon (px accepts them, and the trace has neither).
  • graph, chord and adjacencyMatrix have 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. chord and adjacencyMatrix also take a matrix, as imshow does.
  • Not yet: marginal on line / bar, text_auto (except on imshow), render_mode, color_discrete_map given as a Plotly px.colors object, px.Constant.

Released under the MIT License.