Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 2

Plotting with Matplotlib's Object-Oriented API

Recommended resources

Welcome back. In our previous lesson, we established the theoretical foundation of Matplotlib by dissecting a plot into its core components: the Figure, Axes, Axis, and the versatile Artist objects. This hierarchy is the key to unlocking full control over your visualizations.

Today, we will put that theory into practice. You'll learn to create plots using Matplotlib's powerful object-oriented (OO) Application Programming Interface (API). By the end of this lesson, you will be able to create a plot using this standard workflow and, crucially, explain why this approach is superior for building complex, customizable, and reproducible charts—skills that are essential for both exploratory analysis and professional reporting.

Stateful vs. Stateless: The Two Faces of Matplotlib

Before we write any code, it's important to understand a core distinction in how Matplotlib can be used. As you may have seen in online tutorials or examples, there appear to be two different ways to create the same plot. These are often called the "stateful" (or procedural) and "stateless" (or object-oriented) interfaces.

  • The Stateful pyplot Interface: This approach uses a collection of functions within the matplotlib.pyplot module (commonly imported as plt). Functions like plt.plot() and plt.title() implicitly operate on the "current" figure and axes that Matplotlib is keeping track of behind the scenes. This can be quick for simple, one-off plots, but it becomes ambiguous and difficult to manage as charts get more complex.

  • The Stateless Object-Oriented Interface: This is the approach we will use throughout this course. Here, we explicitly create and hold references to our Figure and Axes objects (usually in variables named fig and ax). We then call methods directly on these objects, such as ax.plot() and ax.set_title(). This method is explicit, clear, and gives us complete control over every element of the plot.

To solidify your understanding of this crucial difference, we'll turn to a well-written guide on the topic.

Python Plotting With Matplotlib (Guide)

This article from Real Python provides an excellent, clear explanation of the two Matplotlib interfaces.

Please read the section titled "Stateful Versus Stateless Approaches". As you read, focus on the description of how pyplot works "under the hood" by getting the current axes (plt.gca()) and then calling a method on it. This reveals that the simple pyplot functions are just wrappers around the more powerful object-oriented methods we're about to learn.

The key insight is that the pyplot interface is essentially a simplified convenience layer built on top of the object-oriented API. For the level of customization and storytelling you're aiming for, we need to work directly with the underlying object-oriented layer.


Creating Plots with the Object-Oriented API

The standard workflow for the object-oriented approach begins with a single, crucial line of code: fig, ax = plt.subplots(). Let's break down what this does.

The function plt.subplots() is a convenient factory function that creates a Figure and a grid of one or more Axes objects all at once.

  • fig: This variable captures the top-level Figure object—the entire canvas.
  • ax: This variable captures the Axes object—the actual subplot where we will draw our data.

By default, plt.subplots() creates a single Figure with a single Axes. Once we have these objects, we can call their methods to build our plot step-by-step. All plotting functions (plot, scatter, bar, etc.) and customization functions (set_title, set_xlabel, etc.) are methods of the ax object.

Let's see this in action. The following guide provides a clear, practical demonstration.

Python Plotting With Matplotlib (Guide)

This section of the Real Python guide demonstrates the practical application of the object-oriented workflow.

Please read the section "Understanding plt.subplots() Notation". Pay close attention to the first code example, where a stacked area chart is created. Notice the pattern: fig, ax = plt.subplots() is called to get the objects. Methods like ax.stackplot(), ax.set_title(), ax.legend(), and ax.set_ylabel() are called on the ax object. A final method, fig.tight_layout(), is called on the fig object.

Here is a minimal, complete example of this workflow in code. You can see the direct mapping from the theory to the implementation.

import matplotlib.pyplot as plt
import numpy as np




# 1. Prepare data
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)




# 2. Create Figure and Axes objects
fig, ax = plt.subplots()




# 3. Plot data on the Axes
ax.plot(x, y)




# 4. Customize the plot using Axes methods
ax.set_title("A Simple Sine Wave")
ax.set_xlabel("Radian")
ax.set_ylabel("Value")
ax.grid(True)




# 5. Display the plot
plt.show()

This pattern—create objects, then call methods on them—is the fundamental workflow you will use for the rest of this course.


The Advantages: Why Be Explicit?

Now that you've seen how to use the OO API, we can address why it's the professional standard. The advantages become clear when you move beyond a single, simple plot.

  1. Clarity and Readability: The code explicitly states which object you are modifying. ax1.set_title(...) is unambiguous, whereas with the pyplot interface, you would have to mentally track which plot is "active." This makes your code far easier for others (and your future self) to understand and debug.

  2. Control over Complex Layouts: Your goal includes creating charts for reports and data storytelling. These often involve multiple plots arranged in a grid. The OO approach is essential here. plt.subplots(2, 2) would return a figure and a 2x2 array of Axes objects, allowing you to control each of the four plots independently. This is nearly impossible to manage cleanly with the stateful pyplot interface.

  3. Reproducibility: Because the pyplot interface depends on a hidden "state," the order of commands can sometimes have unexpected side effects. The explicit OO approach eliminates this. Your script will produce the exact same plot every time, regardless of the environment.

  4. Integration with Other Libraries: As a user of Pandas, you'll find that its built-in plotting functions (.plot()) can feel like a black box. However, these functions often return the Matplotlib Axes object they plotted on. By understanding the OO API, you can take this ax object and perform any further customization you need, unlocking the full power of Matplotlib even when starting from Pandas.

The official Matplotlib documentation makes a strong case for this explicit approach.

Matplotlib Application Interfaces (APIs) — Matplotlib 3.10.9 documentation

This page from the official documentation explains why the explicit "Axes" interface is the recommended approach for robust plotting.

Please read the sections Why be explicit? and the final Summary. The key takeaway is that while the explicit interface is slightly more verbose for a simple plot, it is ultimately simpler and more powerful for creating complex visualizations.


Key Takeaways

In this lesson, we've transitioned from theory to practice, focusing on the standard, object-oriented way of working with Matplotlib.

  • Matplotlib offers two APIs: an implicit, stateful pyplot interface and an explicit, object-oriented interface.
  • The object-oriented API is the preferred and most powerful method for creating complex, reproducible, and highly customized visualizations.
  • The standard workflow is to first create a Figure and one or more Axes objects using fig, ax = plt.subplots().
  • You then build your visualization by calling methods directly on the ax object (e.g., ax.plot(), ax.set_title()). This gives you explicit control over every element.

What's Next?

You now have the foundational workflow for creating any plot in Matplotlib. In our next lesson, we will build directly on this foundation. We will explore how to construct and customize simple line and bar charts, focusing on the various methods available on the Axes object to control properties like color, line styles, labels, and titles.