rcParams and Style Sheets
In one line: set your defaults once at the top of a script instead of restyling every figure — it is the highest-leverage plotting habit there is.
rcParams
A dict of ~300 defaults controlling every aspect of rendering:
import matplotlib as mpl
mpl.rcParams["font.size"] = 9
mpl.rcParams["figure.figsize"] = (5, 3.5)
mpl.rcParams["axes.grid"] = True
mpl.rcParams.update({
"font.size": 9,
"axes.labelsize": 9,
"axes.titlesize": 10,
"xtick.labelsize": 8,
"ytick.labelsize": 8,
"legend.fontsize": 8,
"figure.dpi": 100,
"savefig.dpi": 300,
"savefig.bbox": "tight",
"pdf.fonttype": 42,
"axes.spines.top": False,
"axes.spines.right": False,
"axes.grid": True,
"grid.alpha": 0.3,
"grid.linewidth": 0.5,
"axes.axisbelow": True,
"lines.linewidth": 1.5,
"figure.autolayout": False, # use layout="constrained" instead
})
mpl.rcParamsDefault # the pristine defaults
mpl.rcdefaults() # reset
print(mpl.matplotlib_fname()) # where the config file lives
Setting pdf.fonttype: 42 and axes.spines.top/right: False here means you never think about them again. See Saving Figures.
Style sheets
plt.style.available # list them
plt.style.use("seaborn-v0_8-whitegrid")
plt.style.use("ggplot")
plt.style.use(["seaborn-v0_8-paper", "custom.mplstyle"]) # layered
with plt.style.context("dark_background"): # temporary
fig, ax = plt.subplots()
Note the seaborn-v0_8- prefix: matplotlib renamed the bundled seaborn styles when seaborn 0.12 changed. Old code using plt.style.use("seaborn") breaks on modern matplotlib.
A project style file
Create paper.mplstyle:
font.family : sans-serif
font.sans-serif : Arial, Helvetica, DejaVu Sans
font.size : 8
axes.labelsize : 8
axes.titlesize : 9
axes.titlelocation : left
xtick.labelsize : 7
ytick.labelsize : 7
legend.fontsize : 7
legend.frameon : False
axes.spines.top : False
axes.spines.right : False
axes.grid : True
axes.axisbelow : True
grid.alpha : 0.3
grid.linewidth : 0.4
lines.linewidth : 1.2
figure.figsize : 3.5, 2.6
figure.dpi : 110
savefig.dpi : 300
savefig.bbox : tight
pdf.fonttype : 42
ps.fonttype : 42
svg.fonttype : none
axes.prop_cycle : cycler('color', ['4C72B0','DD8452','55A868','C44E52','8172B3','937860'])
plt.style.use("paper.mplstyle")
Commit this file to your repository. It makes every figure in the paper consistent, it documents your choices, and a collaborator regenerating your figures gets the same output. Note that hex colours in a style file have no # prefix — a common gotcha.
seaborn's set_theme
Usually easier than raw rcParams, because it sets a coherent group at once:
sns.set_theme(
style="whitegrid", # darkgrid, whitegrid, dark, white, ticks
context="paper", # paper, notebook, talk, poster
palette="colorblind",
font="Arial",
font_scale=1.0,
rc={"figure.figsize": (5, 3.5), "pdf.fonttype": 42},
)
sns.set_theme() modifies matplotlib's rcParams, so it affects your raw matplotlib plots too. One call at the top of a script styles everything.
context scales all font and line sizes together:
| context | For |
|---|---|
paper |
journal figures — smallest |
notebook |
the default |
talk |
slides |
poster |
largest |
Building a figure for a talk is sns.set_theme(context="talk") and re-running, not manually bumping fifteen font sizes.
sns.set_context("talk", font_scale=1.1)
sns.axes_style() # inspect the current style dict
with sns.axes_style("white"): # temporary
...
Fonts
mpl.rcParams["font.family"] = "sans-serif"
mpl.rcParams["font.sans-serif"] = ["Arial", "Helvetica", "DejaVu Sans"]
from matplotlib import font_manager
sorted({f.name for f in font_manager.fontManager.ttflist}) # what's available
Most journals want Arial or Helvetica. Give a fallback list — a cluster or CI container may not have Arial installed, and matplotlib silently substitutes DejaVu Sans while emitting a findfont warning.
For LaTeX-quality maths without a LaTeX install:
mpl.rcParams["mathtext.fontset"] = "stixsans" # matches sans-serif body text
The script header worth copying
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="ticks", context="paper", palette="colorblind")
mpl.rcParams.update({
"pdf.fonttype": 42, "ps.fonttype": 42, "svg.fonttype": "none",
"savefig.bbox": "tight", "savefig.dpi": 300,
"figure.dpi": 110,
"axes.titlelocation": "left",
"font.sans-serif": ["Arial", "Helvetica", "DejaVu Sans"],
})
CONDITION_COLORS = {"control": "#4C72B0", "treated": "#DD8452"}
Six lines that make every figure in the project consistent, publication-sized, colourblind-safe and editable. The CONDITION_COLORS dict belongs here too — see Colormaps and Color.
Precedence
Explicit arguments beat everything:
rcParamsDefault < style sheet < sns.set_theme() < rcParams.update() < call arguments
So ax.plot(x, y, lw=3) overrides lines.linewidth regardless of what you set.
Common mistakes
- Restyling every figure by hand instead of setting defaults once.
plt.style.use("seaborn")— renamed toseaborn-v0_8-*.- Setting rcParams after creating the figure. Most apply at draw time, but figure-level ones like
figure.figsizedo not. #prefix on hex colours in a.mplstylefile. Omit it.- Assuming Arial exists on every machine. Provide fallbacks.
- Not committing the style file, so nobody can reproduce your figures.
sns.set()— deprecated alias; usesns.set_theme().- Global rcParams in a library, silently changing your users' plots. Use a context manager.
See also
Saving Figures · seaborn Themes and Palettes · Axes Styling and Annotation · Colormaps and Color · Applied - Reproducible Environment