matplotlib's defaults are fine for a lab notebook and wrong for publication: gray background, cramped fonts, a box around every plot. The good news is you can fix all of it once, in a reusable "house style," and every chart you make afterward looks intentional. This is how every chart on this site gets its look. Full code: scripts/house-style-matplotlib-python.py (and the shared scripts/_chartstyle.py).
One function, applied once
matplotlib reads global settings from rcParams. Set them once at the top of your script and every subsequent figure inherits the style:
import matplotlib.pyplot as plt
NAVY, GOLD, PAPER, RULE, MUTED = "#14213d", "#b0892f", "#fbf8f0", "#d8ceb6", "#4a567a"
def apply_house_style():
plt.rcParams.update({
"figure.facecolor": PAPER, "axes.facecolor": PAPER, "savefig.facecolor": PAPER,
"font.family": "serif", "axes.titleweight": "bold", "axes.titlesize": 15,
"text.color": NAVY, "axes.labelcolor": NAVY, "axes.titlecolor": NAVY,
"axes.edgecolor": RULE, "axes.grid": True, "grid.color": RULE, "grid.alpha": 0.8,
"xtick.color": MUTED, "ytick.color": MUTED,
"axes.spines.top": False, "axes.spines.right": False, "figure.dpi": 150,
})
A consistent palette + no top/right spines + a serif font does most of the work.
The finishing touch: a source caption
Credibility comes from sourcing. Stamp every chart with where the data came from and your wordmark — two fig.text calls:
fig.text(0.01, 0.01, "Sample data for illustration.", fontsize=8.5, color=MUTED, style="italic")
fig.text(0.99, 0.01, "CollegeAthleteInsider.com", ha="right", fontsize=8.5, color=GOLD, weight="bold")
The result
That's the entire difference between "a Python plot" and "a chart you'd publish." Nothing here is hard — it's a dictionary of settings and two text calls — but applied consistently across a whole site it reads as a deliberate, trustworthy visual identity. Every chart in our Elo, efficiency, and trend pieces uses exactly this approach via the shared _chartstyle.py helper.
Principles worth keeping
- Pick a small palette and reuse it. Two or three colors, used consistently, beats a rainbow.
- Remove chartjunk. Drop the top and right spines, lighten the grid, let the data breathe.
- Label directly where you can (numbers on bars) instead of making readers hunt the axis.
- Always cite. A chart without a source is an assertion; a chart with one is evidence.
- Centralize it. Put the style in one importable module so a tweak updates every chart at once.
Sources & further reading
- matplotlib — matplotlib.org
- Companion code:
scripts/house-style-matplotlib-python.pyandscripts/_chartstyle.py - Related: From CSV to chart · Win-probability charts