Standardize Plotly Chart Styling with Custom Layout Templates
Stop styling every Plotly chart by hand. Register a custom layout template once and apply it across notebooks, scripts, and Dash apps.
05 Oct 2026, 10:50 UTC

Your team’s Plotly charts probably look like they came from different companies. One analyst uses plotly_white, another hardcodes navy titles, and a third ships plotly_dark only for evening demos. When those charts appear in the same dashboard or report, the visual inconsistency distracts from the data.
The fix is not to add more update_layout calls to every script. Plotly.py lets you define a layout template once, register it, and make it the default for every figure in a notebook, script, or Dash application. Explicit per-figure settings still override the template, so you get consistency without losing flexibility.
What a Plotly template actually controls
A Plotly template is a named bundle of layout defaults: fonts, colors, axis styles, background colors, and trace defaults. The layout is everything except the data itself—titles, axes, legends, and backgrounds. A trace is a single series of plotted points or bars.
You apply a template with go.Figure.update_layout(template=’plotly_dark’). Because Plotly Express returns graph_objects.Figure objects, the same template works for px.scatter, px.line, and other Express charts. Template values merge with explicit layout properties, so a hardcoded title or axis range still wins over the theme.
Register a custom template and set it as default
Run this in a Python script, Jupyter notebook cell, or Dash app initialization block. No special system permissions are required. First confirm you are on Plotly.py 5.x:
import plotly
print(plotly.__version__)
Then define and register the template:
import plotly.graph_objects as go
import plotly.io as pio
corp_template = go.layout.Template(
layout=go.Layout(
font=dict(family=’Inter, sans-serif’, size=12, color=’#1a1a1a’),
title=dict(font=dict(size=18, color=’#1a1a1a’)),
paper_bgcolor=’#ffffff’,
plot_bgcolor=’#ffffff’,
xaxis=dict(gridcolor=’#e5e5e5’),
yaxis=dict(gridcolor=’#e5e5e5’),
)
)
pio.templates[’corp-light’] = corp_template
pio.templates.default = ’corp-light’
After registration, any new figure inherits the theme:
fig = go.Figure(data=[go.Scatter(x=[1, 2, 3], y=[4, 5, 6])])
fig.update_layout(title_text=’Monthly signups’)
fig.show()
The font and background come from corp-light; title_text is your per-figure override.
Verify the result and know the limits
Check that the template was applied:
print(fig.layout.template.name)
print(fig.layout.font.family)
The first line should print corp-light. The second should include Inter. If you need to undo the default, set pio.templates.default = ’plotly’; because this changes in-process state, reverting restores the previous behavior.
Templates have clear boundaries. They control visual defaults only and will not validate data or prevent invalid trace configurations that fail at render time. Because templates merge rather than replace, explicitly set layout properties can override theme values and produce inconsistent styling if reviewers do not catch them. Finally, exporting to HTML bundles Plotly.js independently of the template, so changing templates does not reduce output file size without a separate CDN or bundle configuration.
Start with one shared template in a utility module, import it across notebooks and Dash apps, and treat hardcoded colors as review comments. Consistency scales better than one-off styling.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.