Matplotlib gives its best to create a plot for us. But sometimes that result can be cleaned-up and improved to better represent the interesting parts of our data. Let us find out how we can do that.
This post is part of my journey to learn Python. You can find the other parts of this series here. You find the code for this post in my PythonFriday repository on GitHub.
What can we customise?
The section “Parts of a Figure” in the Matplotlib tutorials has this nice graphic that shows what we can customise:
If we look at the different parts, we can safely say that Matplotlib allows us to customise nearly every aspect of a plot. Since we find all those details in the documentation, I only cover the most often customised parts of a figure. For everything else, check the documentation.
I strongly suggest you keep the official cheat sheet and the handouts for Matplotlib near you. You can find them on matplotlib.org/cheatsheets.
Name your axes
Nothing is more useless than a plot where we have no idea about the axes. Is it apples? Bananas? Number of cars? We can use the set_xlabel() and set_ylabel() methods to set the labels for our axes:
1 2 3 4 5 6 7 |
x = [1, 2, 3, 4] y = [7, 6, 1, 2] fig, ax = plt.subplots() ax.bar(x,y) ax.set_xlabel("days of performance testing") ax.set_ylabel("# bugs found") |
IMAGE:
Set a title
Especially when we have multiple axes in a figure, we should set a title to keep them apart. We can do that with the set_title() method:
1 2 3 4 5 6 7 8 |
x = [1, 2, 3, 4] y = [7, 6, 1, 2] fig, ax = plt.subplots() ax.bar(x,y) ax.set_xlabel("days of performance testing") ax.set_ylabel("# bugs found") ax.set_title("Project Alpha2") |
Tweak the axis ticks
We can format and configure the major and minor ticks on an axis. To show only whole numbers, we can use the MultipleLocator and set it to a multiple of 1:
1 2 3 4 5 6 7 8 9 10 11 |
from matplotlib.ticker import MultipleLocator x = [1, 2, 3, 4] y = [7, 6, 1, 2] fig, ax = plt.subplots() ax.bar(x,y) ax.xaxis.set_major_locator(MultipleLocator(1)) ax.set_xlabel("days of performance testing") ax.set_ylabel("# bugs found") ax.set_title("Project Alpha2") |
This gives us a plot with only whole numbers in the X axis:
We can change the orientation of the minor ticks while keeping the major ticks unchanged:
1 2 3 4 5 6 7 8 9 10 11 |
from matplotlib.ticker import MultipleLocator as ML from matplotlib.ticker import ScalarFormatter as SF fig, ax = plt.subplots(figsize=[11, 2]) X = np.linspace(0.1, 4*np.pi, 1000) Y = np.sin(X) ax.plot(X, Y, "C1o:", markevery=25, mec="1.0") ax.xaxis.set_minor_locator(ML(0.25)) ax.xaxis.set_minor_formatter(SF()) ax.tick_params(axis='x',which='minor',rotation=90) |
Especially when we do not have enough space is a change of the orientation a useful customisation:
Change the size of your figure
We can change a single figure with the figsize() parameter, that takes the width and the hight in inches:
1 2 3 4 5 |
x = [1, 2, 3, 4] y = [7, 6, 1, 2] fig, ax = plt.subplots(figsize=[2, 2]) ax.plot(x,y) |
This gives us a 2 by 2 inches plot:
If we want to change the size of all plots in a notebook, we can set the figsize in plt.rcParams() right after we import Matplotlib:
1 2 3 4 5 |
import matplotlib as mpl import matplotlib.pyplot as plt # plt.rcParams['figure.figsize'] = [6.4, 4.8] # default plt.rcParams['figure.figsize'] = [10, 5] |
Change the line of your line plot
In a line plot, we can change the thickness of the line, the line style, the colour and the marker for our points:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
x = [1, 2, 3, 4] y = [0, 6, 1, 2] fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, constrained_layout=True) ax1.plot(x, y, linewidth=5) ax1.set_title("Changed line size") ax2.plot(x, y, color="red") ax2.set_title("Changed Colour") ax3.plot(x, y, linestyle="--") ax3.set_title("Changed line style") ax4.plot(x, y, marker="o") ax4.set_title("Changed marker") |
This gives us one plot with a thicker line, one with a red line, one with a dashed line and one with visible dots for the points:
Change the bins or the range in your histogram
Matplotlib makes a guess on a useful number of bins for a histogram (a bin is a range of values that are represented by a bar). While the default is often a good fit, it is not always the case. We can change the number of bins or show only a range of data to improve our plot:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, constrained_layout=True) ax1.hist(data); ax1.set_title("basic") ax2.hist(data, bins=5) ax2.set_title("5 bins") ax3.hist(data, bins=30) ax3.set_title("30 bins"); ax4.hist(data, bins=20, range=(60,90)) ax4.set_title("20 bins, range 60-90"); |
This creates four axes for us. The first one uses the default settings, in axes 2 and 3 we change the number of bins and in the 4th we select only a part of the data:
Next
The tricks presented in this post allow us to display the data in a way that fits our needs. Next week we will explore the different styling options Matplotlib offers for our figures.
2 thoughts on “Python Friday #168: Customise Your Plots in Matplotlib”