Matplotlib Figure and Axes Objects
Matplotlib enables us to create simple 2D plots with just a few commands. Most users are familiar with the command-line for interactively creating plots using Matplotlib. However, the true power of Matplotlib is in the underlying object structure.
Understanding The Matplotlib Object Hierarchy –
A Figure in matplotlib is divided into two different objects.
· Figure object
· Axes object
A Figure object is an instance of matplotlib.figure.Figure. It can contain one or more axes objects. Figure is a container and we cannot plot data on it.
Axes is the instance of matplotlib.axes.Axes. It is the actual area on which our data is plotted. One axes represents one plot inside figure. Axes can contain other figure elements. All the other elements in our plot are also Python objects.
The image below represents the hierarchy of a matplotlib figure.
We all have probably used something like plt.plot([1,2,3]) which is the simplest way to plot the given parameters. This one-liner hides the fact that a plot is really a hierarchy of nested Python objects meaning that there is a tree-like structure of matplotlib objects underlying each plot. Here we are simply using the plt object with the plot function which we have imported using-
import matplotlib.pyplot as plt
We have never actually created this object ourselves. This is referred to as the stateful approach. (state-based, state-machine), i.e. the functions “implicitly” refers to an existing current Figure and current Axes. The other approach is the object oriented or the stateless approach in which we modify the underlying objects directly. We usually do this by calling methods of an Axes object, which is the object that represents the plot itself.
The stateless approach is more customizable and comes in handy as graphs become more complex. The prescribed way to create a Figure with a single Axes using this approach is with plt.subplots() function. The subplots() function takes two arguments that describe the layout of the figure.
fig,ax = plt.subplots(nrows=2, ncols=2, figsize=(7,7))
Here, we have created a Figure object fig, and multiple Axes objects, two rows and two columns more specifically(meaning that space for four plots is created, two side-by-side on top of the other two) ax stores the Numpy array of these Axes objects. We can inspect this:
# output: numpy.ndarray
# output: array([[<matplotlib.axes._subplots.AxesSubplot object at 0x1106daf98>,
<matplotlib.axes._subplots.AxesSubplot object at 0x113045c88>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x11d573cf8>,
<matplotlib.axes._subplots.AxesSubplot object at 0x1130117f0>]],
# output: (2, 2)
We can now call plotting method on each of these Axes objects.
x = np.arange(1,5)
The above method result in the creation of a figure and the following plots on it:
We can also use figure() function to create a new figure. We then add Axes on the figure by using add_axes function. This returns an axes object. So, we need to specify the left, bottom, width, height and create separate axes objects in order to add multiple axes.
fig = plt.figure() #creates empty figure object
axes1 = fig.add_axes([0.1, 0.1, 0.9, 0.9])
axes2 = fig.add_axes([0.1, 0.1, 0.9, 0.9])
axes3 = fig.add_axes([0.1, 0.1, 0.9, 0.9])
axes4 = fig.add_axes([0.1, 0.1, 0.9, 0.9])
x = np.arange(1,5)
Object hierarchy is an important concept in matplotlib plotting. The plot that we see as the output is the Figure object which is the top-level container for all the plotting elements. The Axes object holds the actual plot. We can access the Figure and Axes objects directly or through stateful approach i.e. implicitly. We covered the object-oriented approach of creating and using these objects for plotting. Each time we call plt.subplots() or the plt.figure(), we create a Figure object that Matplotlib sneakily keeps around in memory. We can create multiple plots in a single figure by creating multiple Axes objects on a Figure.