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

A clean, styled matplotlib bar chart on an ivory background with navy bars, gold edges, no top or right spines, and a source caption.
The same bar chart, run through the house style: ivory paper, navy ink, gold accents, source caption. Sample data for illustration.

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

The CollegeAthleteInsider Analyst

I'm an independent analyst covering college football and basketball through public data. Every number here traces to a script in /scripts. More about the methodology →