Graph objects: building figures trace by trace

Plotly · Practical · 12 min

Graph objects handle what Express cannot: mixing trace types, custom per-trace styling and charts assembled in loops.

plotly.graph_objects (imported as go) has a class for every trace type: go.Scatter (used for lines and markers alike), go.Bar, go.Histogram, go.Box, go.Heatmap, go.Pie, go.Scattergl, go.Candlestick and many more. Build a figure by adding traces:

fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode="lines+markers", name="actual"))
fig.add_trace(go.Bar(x=x, y=forecast, name="forecast", opacity=0.5))

Key points:

  • go.Scatter draws lines, markers or both through mode: "lines", "markers", "lines+markers", "text".
  • Each trace has its own name (legend entry), marker, line, hovertemplate, showlegend and legendgroup.
  • Traces are drawn in the order added, so later traces sit on top.
  • Arguments can be nested dicts (marker=dict(color="red", size=8)) or classes (go.scatter.Marker(...)).

Mix with Express freely: start from px.scatter(...) and call fig.add_trace(go.Scatter(...)) to add a reference curve, or take Express traces from one figure (fig_a.data) and add them to another.

Use Express when your data is a tidy DataFrame and the chart maps columns to roles. Switch to graph objects when combining different trace types, building traces in a loop from non-tabular data, or when you need a trace type Express does not wrap.

Example

import plotly.graph_objects as go
import plotly.express as px

months = ["Jan", "Feb", "Mar", "Apr", "May"]
actual = [120, 135, 128, 150, 162]
target = [125, 130, 135, 140, 145]

fig = go.Figure()
fig.add_trace(go.Bar(x=months, y=actual, name="actual", marker_color="#3F4F75"))
fig.add_trace(go.Scatter(x=months, y=target, name="target",
                         mode="lines+markers", line=dict(dash="dash", color="orange")))
print([t.type for t in fig.data])         # ['bar', 'scatter']

base = px.scatter(x=[1, 2, 3, 4], y=[1, 4, 9, 16])
base.add_trace(go.Scatter(x=[1, 4], y=[1, 16], mode="lines", name="chord"))
print(len(base.data), base.data[1].mode)  # 2 lines
fig.write_html("target.html")

Remember

  • Every trace type has a go class; add them with fig.add_trace
  • go.Scatter covers lines and markers via mode
  • Mix freely: refine Express figures with added graph-object traces

Watch out for

  • Looking for go.Line; lines are go.Scatter with mode='lines'.

Check yourself

  1. How do you draw a line chart with graph objects?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: plotly.com/python/graph-objects/