Matplotlib is a library for producing publication-quality figures. mpl (for short) was designed from the bottom-up to serve dual-purposes. First, to allow for interactive, cross-platform control of figures and plots, and second, to make it very easy to produce static raster or vector graphics files without the need for any GUIs. Furthermore, mpl — much like Python itself — gives the developer complete control over the appearance of their plots, while still being very usable through a powerful defaults system.
Anatomy of a Plots
People use “plot” to mean many different things. Here, we’ll be using a consistent terminology (mirrored by the names of the underlying classes, etc):
The Figure is the top-level container in this hierarchy. It is the overall window/page that everything is drawn on. You can have multiple independent figures and Figures can contain multiple Axes.
Most plotting occurs on an
Axes . The
axes is effectively the area that we plot data on and any ticks/labels/etc associated with it. Usually we’ll set up an
Axes with a call to
subplot (which places
Axes on a regular grid), so in most cases,
Subplot are synonymous.
Each Axes has an XAxis and a YAxis. These contain the ticks, tick locations, labels, etc. In this tutorial, we’ll mostly control ticks, tick labels, and data limits through other mechanisms, so we won’t touch the individual Axis part of things all that much.
In this tutorial, we’ll use the following import statements. These abbreviations are semi-standardized, and most tutorials, other scientific python code, etc that you’ll find elsewhere will use them as well.
import numpy as np import matplotlib.pyplot as plt
Now let’s create a figure…
fig = plt.figure()
Awww, nothing happened! This is because by default mpl will not show anything until told to do so. Instead, we’ll need to call plt.show()
fig = plt.show()
Here it will create a blank figure! Not terribly useful yet. We can control the size of the figure through the figsize argument, which expects a tuple of (width, height) in inches. A really useful utility function is figaspect.
All plotting is done with respect to an
Axes is made up of
Axis objects and many other things. An
Axes object must belong to a Figure (and only one Figure). Most commands you will ever issue will be with respect to this Axes object. Typically, you’ll set up a Figure, and then add an Axes to it.
You can use fig.add_axes , but in most cases, you’ll find that adding a subplot will fit your needs perfectly. (Again a “subplot” is just an axes on a grid system.)
fig = plt.figure() ax = fig.add_subplot(111) # We'll explain the "111" later. Basically, 1 row and 1 column. ax.set(xlim=[0.5, 4.5], ylim=[-2, 8], title='An Example Axes', ylabel='Y-Axis', xlabel='X-Axis') plt.show()
For example, we could have written the third line above as:
ax.set_xlim([0.5, 4.5]) ax.set_ylim([-2, 8]) ax.set_title('An Example Axes') ax.set_ylabel('Y-Axis') ax.set_xlabel('X-Axis')
Clearly this can get repitive quickly. Therefore, Matplotlib’s set method can be very handy. It takes each kwarg you pass it and tries to call the corresponding “setter”. For example, foo.set(bar='blah') would call foo.set_bar('blah'). Note that the set method doesn’t just apply to Axes; it applies to more-or-less all matplotlib objects. However, there are cases where you’ll want to use things like ax.set_xlabel('Some Label', size=25) to control other options for a particular function.
Basic Plotting with Matplotlib
Most plotting happens on an Axes. Therefore, if you’re plotting something on an axes, then you’ll use one of its methods. We’ll talk about different plotting methods in more depth in the next section. For now, let’s focus on two methods: plot and scatter. plot draws points with lines connecting them. scatter draws unconnected points, optionally scaled or colored by additional variables. As a basic example:
fig = plt.figure() ax = fig.add_subplot(111) ax.plot([1, 2, 3, 4], [10, 20, 25, 30], color='lightblue', linewidth=3) ax.scatter([0.3, 3.8, 1.2, 2.5], [11, 25, 9, 26], color='darkgreen', marker='^') ax.set_xlim(0.5, 4.5) plt.show()
Axes methods vs. pyplot
Interestingly, just about all methods of an Axes object exist as a function in the pyplot module (and vice-versa). For example, when calling plt.xlim(1, 10) , pyplot calls ax.set_xlim(1, 10) on whichever Axes is “current”. Here is an equivalent version of the above example using just pyplot.
plt.plot([1, 2, 3, 4], [10, 20, 25, 30], color='lightblue', linewidth=3) plt.scatter([0.3, 3.8, 1.2, 2.5], [11, 25, 9, 26], color='darkgreen', marker='^') plt.xlim(0.5, 4.5) plt.show()
Much cleaner, and much clearer! So, why will most of my examples not follow the pyplot approach? Because PEP20 “The Zen of Python” says: “Explicit is better than implicit”. While very simple plots, with short scripts would benefit from the conciseness of the pyplot implicit approach, when doing more complicated plots, or working within larger scripts, you will want to explicitly pass around the Axes and/or Figure object to operate upon.
The advantage of keeping which axes we’re working with very clear in our code will become more obvious when we start to have multiple axes in one figure.
We’ve mentioned before that a figure can have more than one Axes on it. If you want your axes to be on a regular grid system, then it’s easiest to use
plt.subplots(...) to create a figure and add the axes to it automatically.
fig, axes = plt.subplots(nrows=2, ncols=2) plt.show()
plt.subplots(...) created a new figure and added 4 subplots to it. The axes object that was returned is a 2D numpy object array. Each item in the array is one of the subplots. They’re laid out as you see them on the figure.
Therefore, when we want to work with one of these axes, we can index the axes array and use that item’s methods.
fig, axes = plt.subplots(nrows=2, ncols=2) axes[0,0].set(title='Upper Left') axes[0,1].set(title='Upper Right') axes[1,0].set(title='Lower Left') axes[1,1].set(title='Lower Right') # To iterate over all items in a multidimensional numpy array, use the
flatattribute for ax in axes.flat: # Remove all xticks and yticks... ax.set(xticks=, yticks=) plt.show()
fig = plt.figure() ax = fig.add_subplot(111)
You can replace it with:
fig, ax = plt.subplots()
We’ll be using that approach for the rest of the examples. It’s much cleaner. However, keep in mind that we’re still creating a figure and adding axes to it. When we start making plot layouts that can’t be described by subplots, we’ll go back to creating the figure first and then adding axes to it one-by-one.
This article is contributed by Ram Kripal. If you like eLgo Academy and would like to contribute, you can mail your article to firstname.lastname@example.org. See your article appearing on the eLgo Academy page and help other Geeks. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.