Skip to content

API reference

Everything below is importable from plotlyhep directly, except the convert and html modules, which are namespaces.

Styles

plotlyhep.figure

figure(exp: str | None = None, *, scale: float | None = None, **layout) -> go.Figure

A figure using the experiment template (or the current default), at mplhep's figure size.

width/height or scale draw the figure at another size with the same proportions: fonts, ticks, line widths and margins scale together (scale defaults to min(width/W, height/H) against the style's native size, and width/height default to the native size times scale).

plotlyhep.styles.use

use(exp: str = 'CMS') -> None

Make an experiment style the default for new figures (like mplhep.style.use).

plotlyhep.styles.template

template(exp: str = 'CMS', *, scale: float = 1.0) -> go.layout.Template

The Plotly template for an experiment ("CMS" or "ATLAS"), built from mplhep's rcParams: fonts, tick geometry, colour cycle, margins. scale shrinks or enlarges every length together, so a figure drawn at half the mplhep size keeps the same proportions (figure(width=..., height=...) does this).

plotlyhep.styles.template_json

template_json(exp: str = 'CMS', *, transparent: bool = False) -> dict

The template as plain JSON — usable from JavaScript: Plotly.newPlot(gd, data, {template: T}).

plotlyhep.styles.figsize_px

figsize_px(exp: str = 'CMS') -> tuple[int, int]

Figure size in pixels for an experiment style: mplhep's figure.figsize at 100 dpi (CMS 1000x1000, ATLAS 800x600).

plotlyhep.styles.root_template

root_template(width: int = 800, height: int = 600, *, label_size: float = 0.035, title_size: float = 0.04, margins=(0.1, 0.1, 0.1, 0.1), tick_len: float = 0.03, mirror_ticks: bool = False, frame_width: float = 1.0) -> go.layout.Template

A ROOT gStyle-like template: Helvetica (font 42), text sizes as fractions of the pad height like ROOT's precision-2 fonts, ticks inside on the bottom/left only (unless mirror_ticks, i.e. gPad->SetTickx/y), a full frame box, no grid, margins as ROOT pad fractions (left, right, top, bottom). Sizes are absolute pixels for the given canvas.

Labels

plotlyhep.label.exp_text

exp_text(fig: Figure, exp: str = '', text: str = '', *, loc: int = 0, lumi: str | None = None, fontsize: float | None = None, italic: bool | tuple[bool, bool, bool] = (False, True, False), xref='paper', yref='paper') -> go.Figure

Experiment label in the mplhep style: bold experiment name, italic text, optional lumi line.

italic is (experiment, text, lumi) as in mplhep's exp_text, or one bool for all three; the default keeps the text italic (e.g. italic=(False, False, False) for an upright "Open Data").

loc follows mplhep: 0 above the axes (name left, lumi right), 1-3 inside the top-left corner with the text beside or below the name, 4 the ATLAS layout with the lumi line inside too. lumi is the finished string (use exp_label to build it from lumi/com/year).

plotlyhep.label.exp_label

exp_label(fig, exp='', text='', *, loc=0, data=False, year=None, lumi=None, lumi_format='{0}', com='13', rlabel=None, fontsize=None, italic=(False, True, False))

exp_text with the lumi line built for you (like mplhep.cms.label): data=False adds "Simulation", year/lumi/com/lumi_format become "2018, 59.8 fb⁻¹ (13 TeV)", rlabel replaces the whole right label.

plotlyhep.label.set_xlabel

set_xlabel(fig: Figure, text: str, *, size_px: float | None = None) -> go.Figure

mplhep puts the x label right-aligned at the axis end (xaxis.labellocation=right).

plotlyhep.label.set_ylabel

set_ylabel(fig: Figure, text: str, *, size_px: float | None = None, ticklabel_chars: int = 4) -> go.Figure

y label top-aligned at the axis end (yaxis.labellocation=top), rotated.

plotlyhep.cms and plotlyhep.atlas expose text(fig, ...) and label(fig, ...) with the experiment name filled in.

Histograms

plotlyhep.plot.histplot

histplot(fig: Figure, H, bins=None, *, yerr=None, histtype: str = 'step', label=None, color=None, linewidth=None, edges: bool = True, stack: bool = False, density: bool = False, showlegend=None, row: int = 1, **kw) -> list

Add one or several histograms. H: 1D array or list of arrays (same bins). histtype: 'step' (mplhep default, stairs with edges to zero), 'fill', 'errorbar'. yerr: True -> sqrt(H), or an array / list of arrays.

plotlyhep.plot.hist2dplot

hist2dplot(fig: Figure, H, xbins, ybins, *, colorscale='Viridis', cbar: bool = True, **kw)

2D histogram as a heatmap with bin-edge hover, like mplhep.hist2dplot. H is indexed [x, y] as numpy.histogram2d returns it.

plotlyhep.plot.bin_hover

bin_hover(edges, values, err=None, name=None) -> dict

hovertemplate + customdata for a per-bin trace: '[lo, hi) value ± err'.

Ratio panels

plotlyhep.ratio.ratio_figure

ratio_figure(exp: str = 'CMS', *, height_ratios=(3, 1), hspace: float = 0.05, ratio_range=(0.5, 1.5), ratio_title: str = 'Data / MC', width=None, height=None) -> go.Figure

Two stacked panels sharing x: (xaxis, yaxis) on top, (xaxis2, yaxis2) below.

plotlyhep.ratio.ratioplot

ratioplot(fig: Figure, num, den, bins=None, *, num_w2=None, den_w2=None, band: bool = True, color='black', label=None, **kw)

num/den per bin with the numerator's Poisson (or num_w2) error as points in the ratio panel, plus the denominator's relative uncertainty as a band around 1 (band=True).

plotlyhep.ratio.gridspec_domains

gridspec_domains(height_ratios=(3, 1), hspace=0.05, *, top=SUBPLOT['top'], bottom=SUBPLOT['bottom'])

matplotlib GridSpec vertical layout as Plotly domains (fractions of the plot area). total = Σ h_i + (n-1)·hspace·mean(h) → paper y domains, top row first.

HTML embedding

plotlyhep.html.script_tag

script_tag(exp: str | None = 'CMS', *, transparent: bool = True) -> str

plotly.js once per deck, plus the experiment template as a page-level theme: every figure embedded afterwards (by embed() or by hand) renders with the mplhep look unless it carries its own template. This is the deck-level "CSS" for plots.

plotlyhep.html.embed

embed(fig: Figure, div_id: str, *, editable: bool = True, persist: bool = True, width: str = '100%', height: str = 'auto', inherit_template: bool = True, frozen: bool = True, download: bool = True) -> str

HTML fragment: a div plus the script that draws the figure into it.

frozen=True (default): the figure behaves like a picture — hover and its own buttons/dropdowns work, but no zoom, pan, drag or editing — and carries a small "edit" chip that switches editing on (drag annotations, legend, axis titles, zoom) and back to "done"; "reset" discards the saved edits. editable=True keeps the chip; editable=False removes it. frozen=False starts in the editing state. inherit_template=True drops the figure's own template so the page-level PLOTLYHEP_TEMPLATE (from script_tag) applies — one theme for the whole deck. download=True adds a "save" chip: PNG (3x, via Plotly.downloadImage), SVG, and PDF (the figure's SVG alone on a page of its own size, through the browser's print dialog: vector, the page's real fonts, every glyph). download=False removes it.

Conversion

plotlyhep.convert.from_mpl

from_mpl(fig, *, dpi: float | None = None) -> go.Figure

Convert a matplotlib figure to a Plotly figure by walking the drawn artists: lines, steps, error bars, patches, collections, images, texts, annotations, legend and axes geometry. dpi defaults to the figure's; sizes convert at that dpi so the result matches pixel for pixel.

plotlyhep.convert.to_mpl

to_mpl(pfig: Figure, *, dpi: float = 100.0)

Convert a Plotly figure back to matplotlib: traces become lines / steps / bars / error bars / images, annotations become texts or arrows, axes keep their ranges, ticks and labels.

plotlyhep.convert.mathtext_to_html

mathtext_to_html(s: str) -> str

Crude but useful: $m_{jj}$ -> mjj, $x^{2}$ -> x2.

plotlyhep.convert.html_to_mathtext

html_to_mathtext(s: str) -> str

Inverse of mathtext_to_html: / back to $_{}$ / $^{}$, other tags dropped.

ROOT

plotlyhep.root.from_root

from_root(obj, opt: str = '', *, width: int | None = None, height: int | None = None) -> go.Figure

ROOT -> Plotly. obj: a TCanvas / TPad (everything drawn on it, sub-pads included), or a single TH1 / TH2 / TGraph* / TMultiGraph / THStack / TF1 with a ROOT draw option in opt (it is drawn on a temporary batch canvas so ROOT's own axis ranges, title and stats apply), or an object read with uproot (no ROOT needed). width/height override the canvas size in pixels.

plotlyhep.root.to_root

to_root(pfig: Figure, *, name: str = 'c')

Plotly -> ROOT TCanvas (the objects stay alive as canvas._plotlyhep_keep).

plotlyhep.root.rootlatex_to_html

rootlatex_to_html(s: str) -> str

ROOT TLatex markup to the HTML Plotly renders: #it{} #bf{} -> , _{} ^{} -> ,

sqrt{x} -> √x, #alpha ... #pm -> Unicode, accents (#bar{x}) -> combining marks, #scale/#color/#font dropped.

plotlyhep.root.html_to_rootlatex

html_to_rootlatex(s: str) -> str

Inverse of rootlatex_to_html for the tags plotlyhep produces.

plotlyhep.root.root_color

root_color(index: int | None, alpha: float | None = None, *, ROOT=None) -> str

ROOT colour index -> CSS colour (live TColor when ROOT is loaded, the snapshot table otherwise).