Create your custom Matplotlib style

Karthikeyan P
Analytics Vidhya
Published in
8 min readAug 11, 2020

A hands-on to create a .mplstyle

Matplotlib is an open-source 2D plotting library for Python. With its support for various types of graphs and charts, Matplotlib is primarily used for data analysis and data visualisation. Being a versatile data visualisation tool with endless customisation options, the popularity of Matplotlib has seen a steady increase over the past five years which is evident from the google trends graph shown below.

Google trends graph showing increasing interest in matplotlib
Interest trend for Matplotlib. Data source: Google Trends (https://www.google.com/trends)

Though it has its advantages, Matplotlib has a major drawback. It has an extremely low-level interface, requiring greater effort to make visualisations look appealing to the audience.

After reading this tutorial, you would gain the ability to create a custom style for your Matplotlib projects. Basic knowledge of Matplotlib is needed to understand this tutorial.

Styles provided by Matplotlib

To handle its major drawback, Matplotlib provides its users with some built-in styles to make graphs and charts more appealing. The following command lists the styles provided by Matplotlib.

import matplotlib as pltprint(plt.style.available)['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']

What good would come from knowing the names of the built-in styles? Matplotlib is a visualisation tool. Let us visually see these styles by plotting a line graph and a bar chart.

All the available styles in Matplotlib
Available styles in Matplotlib. (Image by Author)

What if you did not like any of these built-in styles? You can create your style. But first, you need to understand how and where the styles are applied. To accomplish this, let us look at the layers in Matplotlib.

Layers in Matplotlib

Matplotlib architecture comprises of 3 distinct layers, which can be visualised as a stack.

  • Scripting Layer
  • Artist Layer
  • Backend Layer

Backend Layer

This is the bottom layer of the stack consisting of 3 interfaces.

  • FigureCanvas represents the surface to draw (eg. the paper).
  • Renderer does the drawing (eg. the paintbrush).
  • Event handles user inputs from keyboard and mouse.

Artist Layer

This is the middle layer of the stack that does most of the heavy lifting. Artist knows how to use the Renderer (the paintbrush) and paint on the FigureCanvas (the paper). Every component in a Matplotlib Figure is a Artist instance i.e. the title, the labels, the lines, the axes, the ticks, etc. are individual Artist instances. This layer is meant for professional developers who like to utilise the versatile functionalities of Artist.

Scripting Layer (pyplot)

This is the top layer of the stack and uses APIs to draw graphs. This layer is designed for programmers who focus on creating graphs and does not wish to tinker with the various functionalities. To know more about the layers, please follow this link.

Where are customisations applied?

All the components of a Matplotlib Figure marked in the below image are customisable. And, these customisations are carried out in the Artist layer of Matplotlib.

Anatomy of a Figure
Anatomy of a figure (Source: https://matplotlib.org/3.3.0/gallery/showcase/anatomy.html)

Creating a custom style

Now that you know where customisations take place, allow me to show you how to customise your graphs. But first, we need to decide on the components of Figure that need to be customised. Let us, for example, make the following customisations in our graphs.

  1. Set a default figure size of 5 x 4 inches with white background.
  2. Use a four-colour cycle based on cyan, magenta, yellow and black.
  3. Remove the top and the right spines.
  4. Move the tick marks to the inside of the axis line.
  5. Increase the major tick width to 2.
  6. Increase the tick label’s size.
  7. Change the title font to Arial and make it bigger.
  8. Change both the axes label’s font to Arial and make it bigger.

You can find the Jupyter notebooks for this tutorial in my GitHub repository.

Worst-case customisation

Let us create a simple bar chart comparing the yearly performance of three departments of an imaginary educational institution.

import matplotlib.pyplot as plt
import numpy as np
data = [[30, 25, 50, 20],
[40, 23, 51, 17],
[35, 22, 45, 19]]
X = np.arange(4)
width = 0.25
fig = plt.figure()ax = fig.add_axes([0,0,1,1])ax.bar(X + 0.00, data[0], width = 0.25)
ax.bar(X + 0.25, data[1], width = 0.25)
ax.bar(X + 0.50, data[2], width = 0.25)
ax.set_xticks(X+width)
ax.set_xticklabels(('2015','2016','2017','2018'))
ax.set_title('Performance Comparison')
ax.set_xlabel('Departments')
ax.set_ylabel('Average')
ax.legend(labels=["CS", "IT", "ECE"])plt.show()

Running this code snippet would produce a bar chart with the default style.

A Sample bar chart without customisation (Image by Author)

Let us modify the same bar chart by customising the components decided earlier.

import matplotlib.pyplot as plt
import numpy as np
import math
from cycler import cycler
data = [[30, 25, 50, 20],
[40, 23, 51, 17],
[35, 22, 45, 19]]
X = np.arange(4)
width = 0.25
# Set a default figure size of 5 x 4 inches with white background
fig = plt.figure(figsize=(5,4), facecolor='w')
ax = fig.add_axes([0,0,1,1])# Change color cycle to cyan, magenta, yellow and black
custom_cycler = (cycler(color=['c', 'm', 'y', 'k']))
ax.set_prop_cycle(custom_cycler)
# Remove right and top spine
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
# Both axis tick customisations
ax.xaxis.set_tick_params(direction='in', which='major', width=2, labelsize='medium')
ax.yaxis.set_tick_params(direction='in', which='major', width=2, labelsize='medium')
ax.bar(X + 0.00, data[0], width = 0.25)
ax.bar(X + 0.25, data[1], width = 0.25)
ax.bar(X + 0.50, data[2], width = 0.25)
ax.set_xticks(X+width)
ax.set_xticklabels(('2015','2016','2017','2018'))
# Change font and font size for title and both axis labels
ax.set_title('Performance Comparison', fontname='Arial', fontsize='x-large')
ax.set_xlabel('Departments', fontname='Arial', fontsize='large')
ax.set_ylabel('Average', fontname='Arial', fontsize='large')
ax.legend(labels=["CS", "IT", "ECE"])plt.show()

Executing the above code snippet would produce a bar chart with the customisations that we needed.

The same bar chart with customization. (Image by Author)

10 lines of code were added to the original code to make these 8 customisations in 1 graph. Imagine a scenario where your data visualisation project comprises of 10 such graphs. To do these 8 customisations, you must add these 10 lines of code to all the 10 graphs. It would be a tiring process of copying and pasting these 10 lines. Moreover, doing this would be the worst-case scenario and would also affect the readability of your code. I shall show you the best-case scenario, wherein you need to add only one line of code to your entire project to perform not only these 8 but also many more customisations that you may need. This best-case scenario would hold to any number of your future projects.

Best-case customisation: Creating .mplstyle file

Creating a .mplsyle file would be the best-case scenario. This is the file that holds all the customisations to be applied to your Figure. One file to rule them all! - Kudos to you, if you get the reference.

Let us create a demo_style.mplstyle file in your data visualisation project folder. And in this file, we shall do the 8 customisations as follows.

# demo_syle.mplstyle# Set figure size to 5x4 inches with white background
figure.figsize: 5,4 # figure size in inches
figure.facecolor: white # figure facecolor
# Change to cyan, magenta, yellow and black color palette
axes.prop_cycle: cycler('color', ['c', 'm', 'y', 'k'])
# Remove top and right spines
axes.spines.left: True # display axis spines
axes.spines.bottom: True
axes.spines.top: False
axes.spines.right: False
# Both axis tick customisations
xtick.direction: in # direction: {in, out, inout}
ytick.direction: in # direction: {in, out, inout}
xtick.major.width: 2 # major tick width in points
ytick.major.width: 2 # major tick width in points
xtick.labelsize: medium # fontsize of the tick labels
ytick.labelsize: medium # fontsize of the tick labels
# Change font and font size of title and both axis labels
font.family: Arial
font.size: 14.0
axes.titlesize: x-large # fontsize of the axes title
axes.labelsize: large # fontsize of the x and y labels

With the one file created, let us re-create the bar chart from the previous section.

import matplotlib.pyplot as plt
import numpy as np
# Applying the custom style sheet to all of the graphs to be created in this notebook
plt.style.use('demo_style.mplstyle')
data = [[30, 25, 50, 20],
[40, 23, 51, 17],
[35, 22, 45, 19]]
X = np.arange(4)
width = 0.25
fig = plt.figure()ax = fig.add_axes([0,0,1,1])ax.bar(X + 0.00, data[0], width = 0.25)
ax.bar(X + 0.25, data[1], width = 0.25)
ax.bar(X + 0.50, data[2], width = 0.25)
ax.set_xticks(X+width)
ax.set_xticklabels(('2015','2016','2017','2018'))
ax.set_title('Performance Comparison')
ax.set_xlabel('Departments')
ax.set_ylabel('Average')
ax.legend(labels=["CS", "IT", "ECE"])plt.show()

Executing this code creates a bar chart with all the 8 customisations. But that is not the interesting part. Did you notice the above code snippet is the same as the code snippet without any customisation, except for the one line?

That one line is plt.style.use('demo_style.mplstyle'). This command instructs Matplotlib to use the .mplstyle file to perform customisations on all the graphs in that Jupyter notebook or python script. Isn't it easy and efficient to add one line of code to customise all of your graphs?

This is not the only way of customizing Matplotlib graphs. But this is the best way. This link describes various other ways of customising your graphs.

I have created another demo_syle_2.mplsyle file to show more customizations. The output of this customisation is shown below in comparison with built-in styles. Both the .mplstyle files and Jupyter notebooks for this tutorial can be found in my GitHub repository.

A sample chart comparing customised graph with available styles. (Image by Author)
A sample bar chart comparing customised chart with available styles. (Image by Author)

Note: If you wish to change the style of a single graph or chart while using .mplstyle, you can always override the custom style using inline customisations. Using inline customisation does not affect the .mplstyle file and the customisation will apply only to that graph or chart. We had previously used inline customisations in the worst-case customisation section.

Closing remarks

I have shown you how to create your custom style in Matplotlib. Creating and perfecting a custom .mplstyle file takes time and many tries, but it is worth the effort. It will save you time and effort in all your future data visualisation and data analysis projects.

A kind request: While choosing colours for your style, kindly choose colour blind friendly colours. You never know if your audience includes a colour blind. You can use websites like https://colorbrewer2.org/ to choose colour blind friendly colours.

Until next time, good luck. Stay safe and happy learning.!

--

--

Karthikeyan P
Analytics Vidhya

Data Science & Machine Learning Aficionado | Tech Geek | Writing to share the joy of learning