Customizing Matplotlib: Configurations and Stylesheets#

While many of the topics covered in previous chapters involve adjusting the style of plot elements one by one, Matplotlib also offers mechanisms to adjust the overall style of a chart all at once. In this chapter we’ll walk through some of Matplotlib’s runtime configuration (rc) options, and take a look at the stylesheets feature, which contains some nice sets of default configurations.

Plot Customization by Hand#

Throughout this part of the book, you’ve seen how it is possible to tweak individual plot settings to end up with something that looks a little nicer than the default. It’s also possible to do these customizations for each individual plot. For example, here is a fairly drab default histogram, shown in the following figure:

import matplotlib.pyplot as plt
plt.style.use('classic')
import numpy as np

%matplotlib inline
x = np.random.randn(1000)
plt.hist(x);
_images/477f4664e1363735bc30d31d94d4ee7aae4b16d9e442c70af662446e755ddb90.png

We can adjust this by hand to make it a much more visually pleasing plot, as you can see in the following figure:

# use a gray background
fig = plt.figure(facecolor='white')
ax = plt.axes(facecolor='#E6E6E6')
ax.set_axisbelow(True)

# draw solid white gridlines
plt.grid(color='w', linestyle='solid')

# hide axis spines
for spine in ax.spines.values():
    spine.set_visible(False)
    
# hide top and right ticks
ax.xaxis.tick_bottom()
ax.yaxis.tick_left()

# lighten ticks and labels
ax.tick_params(colors='gray', direction='out')
for tick in ax.get_xticklabels():
    tick.set_color('gray')
for tick in ax.get_yticklabels():
    tick.set_color('gray')
    
# control face and edge color of histogram
ax.hist(x, edgecolor='#E6E6E6', color='#EE6666');
_images/ac737f46b22bdb5ed749a043d0a611e1203577606a88ab584019a1712af2a70e.png

This looks better, and you may recognize the look as inspired by that of the R language’s ggplot visualization package. But this took a whole lot of effort! We definitely do not want to have to do all that tweaking each time we create a plot. Fortunately, there is a way to adjust these defaults once in a way that will work for all plots.

Changing the Defaults: rcParams#

Each time Matplotlib loads, it defines a runtime configuration containing the default styles for every plot element you create. This configuration can be adjusted at any time using the plt.rc convenience routine. Let’s see how we can modify the rc parameters so that our default plot will look similar to what we did before.

We can use the plt.rc function to change some of these settings:

from matplotlib import cycler
colors = cycler('color',
                ['#EE6666', '#3388BB', '#9988DD',
                 '#EECC55', '#88BB44', '#FFBBBB'])
plt.rc('figure', facecolor='white')
plt.rc('axes', facecolor='#E6E6E6', edgecolor='none',
       axisbelow=True, grid=True, prop_cycle=colors)
plt.rc('grid', color='w', linestyle='solid')
plt.rc('xtick', direction='out', color='gray')
plt.rc('ytick', direction='out', color='gray')
plt.rc('patch', edgecolor='#E6E6E6')
plt.rc('lines', linewidth=2)

With these settings defined, we can now create a plot and see our settings in action (see the following figure):

plt.hist(x);
_images/3f7737f079c8e69894781b2dff126c440661a31d78adbcfb4687ae2322550006.png

Let’s see what simple line plots look like with these rc parameters (see the following figure):

for i in range(4):
    plt.plot(np.random.rand(10))
_images/04d2aaef4c000621f572d7dcf9b8bc217204f5c4a551677878a230d91b39f3c2.png

For charts viewed onscreen rather than printed, I find this much more aesthetically pleasing than the default styling. If you disagree with my aesthetic sense, the good news is that you can adjust the rc parameters to suit your own tastes! Optionally, these settings can be saved in a .matplotlibrc file, which you can read about in the Matplotlib documentation.

Stylesheets#

A newer mechanism for adjusting overall chart styles is via Matplotlib’s style module, which includes a number of default stylesheets, as well as the ability to create and package your own styles. These stylesheets are formatted similarly to the .matplotlibrc files mentioned earlier, but must be named with a .mplstyle extension.

Even if you don’t go as far as creating your own style, you may find what you’re looking for in the built-in stylesheets. plt.style.available contains a list of the available styles—here I’ll list only the first five for brevity:

plt.style.available[:5]
['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background']

The standard way to switch to a stylesheet is to call style.use:

plt.style.use('stylename')

But keep in mind that this will change the style for the rest of the Python session! Alternatively, you can use the style context manager, which sets a style temporarily:

with plt.style.context('stylename'):
    make_a_plot()

To demonstrate these styles, let’s create a function that will make two basic types of plot:

def hist_and_lines():
    np.random.seed(0)
    fig, ax = plt.subplots(1, 2, figsize=(11, 4))
    ax[0].hist(np.random.randn(1000))
    for i in range(3):
        ax[1].plot(np.random.rand(10))
    ax[1].legend(['a', 'b', 'c'], loc='lower left')

We’ll use this to explore how these plots look using the various built-in styles.

Default Style#

Matplotlib’s default style was updated in the version 2.0 release; let’s look at this first (see the following figure):

with plt.style.context('default'):
    hist_and_lines()
_images/09192220a488e0ffa40d22a6c8e2a02e8ee405333d80f42385e79be577b0c3c5.png

FiveThiryEight Style#

The fivethirtyeight style mimics the graphics found on the popular FiveThirtyEight website. As you can see in the following figure, it is typified by bold colors, thick lines, and transparent axes:

with plt.style.context('fivethirtyeight'):
    hist_and_lines()
_images/06db9565f77a3e9b1ee93f284e0737b8a8056097e16fe2550aa29dd0ebfd21d0.png

ggplot Style#

The ggplot package in the R language is a popular visualization tool among data scientists. Matplotlib’s ggplot style mimics the default styles from that package (see the following figure):

with plt.style.context('ggplot'):
    hist_and_lines()
_images/a7d9e5009a542d256c4726c2b54dcc7c5febe687cc63629bb666ac5edfe60894.png

Bayesian Methods for Hackers Style#

There is a neat short online book called Probabilistic Programming and Bayesian Methods for Hackers by Cameron Davidson-Pilon that features figures created with Matplotlib, and uses a nice set of rc parameters to create a consistent and visually appealing style throughout the book. This style is reproduced in the bmh stylesheet (see the following figure):

with plt.style.context('bmh'):
    hist_and_lines()
_images/72038b1573f22ffa6225270d5adaf352731508a35971f9f55d437eed69ad88a0.png

Dark Background Style#

For figures used within presentations, it is often useful to have a dark rather than light background. The dark_background style provides this (see the following figure):

with plt.style.context('dark_background'):
    hist_and_lines()
_images/09ce05810eb5a78ca2d116467c1fb210330efd88ebddd354103e7dd9c82170dd.png

Grayscale Style#

Sometimes you might find yourself preparing figures for a print publication that does not accept color figures. For this, the grayscale style (see the following figure) can be useful:

with plt.style.context('grayscale'):
    hist_and_lines()
_images/fe453844fda3be6e6cc2dc171c6f1208243b9d114624f1411fc195bc98a1b0ae.png

Seaborn Style#

Matplotlib also has several stylesheets inspired by the Seaborn library (discussed more fully in Visualization With Seaborn). I’ve found these settings to be very nice, and tend to use them as defaults in my own data exploration (see the following figure):

with plt.style.context('seaborn-whitegrid'):
    hist_and_lines()
_images/ed3280199fcddaf8730e71e5526744a2e1b4bd0c9e5646cd90df0c8483880e82.png

Take some time to explore the built-in options and find one that appeals to you! Throughout this book, I will generally use one or more of these style conventions when creating plots.