Annotate data, not pixels · HoloViz · verified against HoloViews 1.23 (2026)

HoloViews cheat sheet

HoloViews flips plotting around: instead of drawing figures, you wrap data in semantic Element objects that "visualize themselves." Compose them with + and *, style them separately with .opts(), and render through Bokeh (interactive), Matplotlib, or Plotly — same code, swappable backend. The payoff: rich, interactive, and big-data-ready plots with very little code. This sheet targets HoloViews 1.23.

setup & elements dimensions compose & style containers interact & ship gotcha most common

Verified 2026-08-24 against the official docs at holoviews.org (v1.23.1). Part of the HoloViz stack (with Panel, hvPlot, Datashader). The current styling API is the .opts() method with opts.<Element>(...) builders — the old %%opts/%%output notebook magics are legacy.

Outline

Load a backend, wrap data in Elements, declare which columns are keys (x) vs values (y), compose with +/*, style with .opts(), then add interactivity, big-data rasterization, and export.

Build

  1. 1 · Setup & extension
  2. 2 · Elements from data
  3. 3 · Dimensions (kdims/vdims)

Compose & style

  1. 4 · Compose (+ and *)
  2. 5 · Options (.opts)
  3. 6 · Containers & DynamicMap

Interact & ship

  1. 7 · Interactivity
  2. 8 · Big data & export
  3. 9 · Gotchas
  4. Worth memorizing

Build

Pick a backend and turn data into self-describing elements.

1Setup & extension1.23
2Elements from datadata + semantics
3Dimensionskdims vs vdims

Compose & style

Combine elements algebraically, then style them — keeping the two separate.

4Compose (+ and *)algebra of plots
5Options (.opts)appearance, kept separate
6Containers & DynamicMapmany plots, one object

Interact & ship

Add linked interactions, scale to millions of points, and export.

7Interactivitystreams + Panel
8Big data & exportrasterize + save
!Common gotchasread before shipping

Worth memorizing

hv.extension("bokeh")load a backend first; bokeh/mpl/plotly
hv.Curve(df, "x", "y")element = data + semantics
kdims = keys (x), vdims = values (y)positional order is (kdims, vdims)
a + b = Layoutside by side; .cols(n)
a * b = Overlaysuperimposed on shared axes
.opts(...) / opts.Element(...)style separately; opts.defaults() globally
HoloMap = eager, widgetsall frames embedded
DynamicMap = lazy callbackfor big data / large spaces
Dataset(df).to(Curve, ...)tabular -> keyed plots; overlay/layout/grid
streams (RangeXY/Tap) + DynamicMaplinked interactivity
rasterize/datashade for millions of ptsserver-side aggregation
hv.save / hv.render / hv.outputexport HTML/PNG; drop to native figure