The aesthetics of data visualizations are important. I often view this as "beautiful data deserves beautiful presentations" – Being overly fastidious with graph styling is not encouraged, but a healthy amount of polishing could go a long way.
Nevertheless, for static graphs that we typically make with matplotlib or seaborn, the default aesthetics usually require tweaking. This is where custom style sheets come in handy for at least two reasons:
- Make our workflow compliant with the Don’t Repeat Yourself (DRY) principle: We don’t need to type the same chunks of styling codes repetitively every time. Instead, we apply the style sheet with one line of code
- Styling consistency is easily achieved, and that could be an implicit signature for individuals, teams, and organizations
How To Set Up And Use Custom Style Sheet
Start With Built-in Examples
Most of us may already have been using a few built-in styles in day-to-day work. For example, a quick run of
# This code snippet mimics command usages in ipython console
In [1]: import matplotlib.pyplot as plt
Out [1]: plt.style.available
will return a full list of style sheets, and we can find a gallery view of their effects in matplotlib’s documentation.
Under the hood, we can locate these built-in style sheets and take a look:
# This code snippet mimics command usages in ipython console
In [2]: import matplotlib
# Locate path to matplotlib by checking where config file is
# To learn more about the function below,
# type ?matplotlib.matplotlib_fname
In [3]: matplotlib.matplotlib_fname()
Out [3]: '/Users/sdou/opt/miniconda3/lib/python3.8/site-packages/matplotlib/mpl-data/matplotlibrc'
The path /Users/.../mpl-data
is where we would like to go and locate the style sheets:
In [4]: !ls /Users/sdou/opt/miniconda3/lib/python3.8/site-packages/matplotlib/mpl-data/
fonts images matplotlibrc stylelib
The folder of interest is stylelib
. Let’s now take a look inside this folder:
In [5]: !ls -1 /Users/sdou/opt/miniconda3/lib/python3.8/site-packages/matplotlib/mpl-data/stylelib/
Solarize_Light2.mplstyle
_classic_test_patch.mplstyle
bmh.mplstyle
classic.mplstyle
dark_background.mplstyle
fast.mplstyle
fivethirtyeight.mplstyle
ggplot.mplstyle
grayscale.mplstyle
seaborn-bright.mplstyle
seaborn-colorblind.mplstyle
seaborn-dark-palette.mplstyle
seaborn-dark.mplstyle
seaborn-darkgrid.mplstyle
seaborn-deep.mplstyle
seaborn-muted.mplstyle
seaborn-notebook.mplstyle
seaborn-paper.mplstyle
seaborn-pastel.mplstyle
seaborn-poster.mplstyle
seaborn-talk.mplstyle
seaborn-ticks.mplstyle
seaborn-white.mplstyle
seaborn-whitegrid.mplstyle
seaborn.mplstyle
tableau-colorblind10.mplstyle
Let’s inspect one of the .mplstyle
files. Here we use classic.mplstyle
as an example and display the top 37 lines of the file:

classic.mplstyle
file (37 is an arbitrary choice)We can see a comprehensive list of matplotlib parameter settings and their default values, and the parameters are organized into groups such as lines
, markers
, patch
, text
.
Build Custom .mplstyle File
A Minimalism Example
Below is a minimalism example (named signature.mplstyle
)built on top of the built-in style sheetseaborn-colorblind.mplstyle
How To Invoke Custom Style Sheet
- If we have write privilege to the abovementioned path for
stylelib
, we can put the custom style sheet into the same folder and invoke the style sheet with
# Scenario 1: Apply globally to a jupyter notebook
plt.style.use("signature")
# Scenario 2: Apply locally with context manager
with plt.style.context("signature"):
plt.plot([1, 2, 3, 4])
- If we don’t have the write privilege, the only extra thing we would need to do is to include the full path of the custom style sheet. Here we use a simple example of directly storing the style sheet under the home directory:
# Scenario 1: Apply globally to a jupyter notebook
plt.style.use("/home/signature.mplstyle")
# Scenario 2: Apply locally with context manager
with plt.style.context("/home/signature.mplstyle"):
plt.plot([1, 2, 3, 4])
How To Return To Default
There could be cases when we want to recover the default styling. There are at two ways to recover the default settings:
- Reset via
rcParams.update
import matplotlib as mpl
mpl.rcParams.update(mpl.rcParamsDefault)
- Reset with default style sheet
plt.style.use('default')
Data Viz Example: Style Sheet In Action
Here we penguin dataset as an example to demonstrate the effect of the custom style sheet signaure.mplstyle
.
import matplotlib.pyplot as plt
import seaborn as sns
# Load the penguins dataset
penguins = sns.load_dataset("penguins")
- Use default style
plt.style.use("default")
# Show the joint distribution using kernel density estimation
g = sns.jointplot(
data=penguins,
x="bill_length_mm",
y="bill_depth_mm",
hue="species",
kind="kde",
)
g.fig.suptitle("Styled With Default Style Sheet", y=1.01)
plt.show()

- Use custom style set in
signature.mplstyle
plt.style.use("signature")
# Show the joint distribution using kernel density estimation
g = sns.jointplot(
data=penguins,
x="bill_length_mm",
y="bill_depth_mm",
hue="species",
kind="kde",
)
g.fig.suptitle("Styled With Custom Style Sheet", y=1.01)
plt.show()

Key Takeaways
- Beautiful data deserves beautiful presentations. But instead of typing chunks of styling codes repetitively, a bit upfront time investment in setting up our own custom style sheet (file extension
.mplstyle
) could both save time and ensure styling consistency - To build custom style sheets, we could start with built-in style sheets and custom them further to our liking. One key step is to locate these style sheets with the help of
matplotlib.matplotlib_fname()
References
4.11 Customizing Matplotlib: Configurations and Stylesheets: Data Science Handbook by Jake VanderPlas