Quick Reference · interactive graphing in Python

plotly cheat sheet

Plotly builds interactive, web-native charts. The mental model: a Figure is just data (a list of traces) + a layout, serialized to JSON and drawn by Plotly.js. You build that figure two ways — Plotly Express (px, one high-level call) or Graph Objects (go, assembled by hand) — and both return the same go.Figure, which you then refine with fig.update_*() and export to HTML, PNG, or JSON.

setup / import / data Plotly Express Graph Objects encode channels update · subplots · layout interact · render · export gotcha most common

Distilled & cross-checked across: plotly.com/python · figure structure · plotly express · graph objects · creating & updating figures · API reference 7.0 · v6/v7 migration · Dash docs  — Verified 2026-08-26 against Plotly 7.0.0

How a plot is built — two APIs converge on one figure, then you refine & render
PLOTLY EXPRESS · high-level px.scatter(df, x, y, color="grp") one call · returns a figure GRAPH OBJECTS · low-level go.Figure( data=[go.Scatter(…)], layout={…}) assemble · full control px builds go 5–100× less code the same go.Figure — a JSON tree data = [ trace, trace, … ] each trace = one series: Scatter · Bar · Heatmap · Box … layout = { title, xaxis, yaxis, legend … } everything that isn't data frames = [ … ] · animation (optional) print(fig) · fig.to_dict() · fig.to_json() px and go produce identical objects REFINE fig.update_layout(title=…) fig.update_traces(marker_size=…) fig.add_trace(…) · add_hline(…) chainable · merges recursively returns the same figure RENDER / EXPORT fig.show() → browser · notebook fig.write_html("f.html") standalone fig.write_image("f.png") kaleido fig.to_json() → embed anywhere Every figure serializes to JSON → Plotly.js draws it in the browser interactive by default: zoom · pan · box-select · hover tooltips · click the legend to toggle traces
01Setup & Importthe two entry points
02Express · basicspx · one call → figure
03Express · distributions1-D & 2-D shape
04Express · hierarchypart-of-whole
05Express · maps · 3D · nDbeyond the plane
06Encode channelscolumns → visuals (px)
07Graph Objectsfigure = data + layout
08Trace zoogo.* building blocks
09Update the figurepost-creation edits
10Subplotsmake_subplots
11Layout & stylingshape the frame
12Color & templatesinstant restyle
13Interactivityit's live by default
14Output & exportget it out
15Express vs Graph Objectsthe one big choice ★
16Gotchasthe usual traps

Four ideas worth a picture

The flow up top shows the whole build. These four zoom in on the ideas that make plotly click: what a figure actually is, how the two APIs relate, how updates merge, and how a figure becomes pixels.

a figure is data + layout

Under any chart is one nested dict: a list of traces (the data) and a layout. That's the whole object model.

go.Figure data = [ { type:"scatter", x:[…], y:[…], marker:{…} } { type:"bar", … } trace 2 … ] layout = { title, legend, xaxis:{…}, yaxis:{…}, template, margin } frames = [ … ] animation (optional)

one chart, two ways

Express writes the graph-objects for you. The same figure, either as a one-liner or assembled by hand.

Plotly Express fig = px.bar( df, x="d", y="n") 1 line Graph Objects fig = go.Figure( data=[go.Bar( x=df.d, y=df.n)], layout=go.Layout( barmode="group")) 5–100× more lines same go.Figure

magic underscore & recursive update

Underscores flatten nested keys; update_* merges into the tree instead of clobbering its siblings.

fig.update_layout(title_font_size=20) underscores → nesting layout title font size=20 title.text stays intact merge, don't overwrite (overwrite=True to replace)

from figure to pixels

One figure, many destinations. All go through JSON → Plotly.js, which is why the HTML export stays fully interactive.

go.Figure to JSON .show() notebook/browser .write_html() interactive file .write_image() PNG · kaleido .to_json() embed Plotly.js draws the interactive ones

Worth memorizing

figure = data + layouta JSON tree Plotly.js renders
px vs gohigh-level 1 call vs assembled — same go.Figure
px.* → go.Figureso refine any px chart with fig.update_*
px builds gounder the hood, 5–100× less code
color/facet/animationpx encodes columns → visuals & panels
update_traces(selector=)or it edits every trace
magic underscoremarker_color="red"marker=dict(color=…)
write_html()standalone & interactive · write_image needs kaleido
template="plotly_white" restyles instantly
make_subplots()mixed-type / dual-axis panels (px can't)