What is the difference between plt and ax in matplotlib?
Short answer
plt is the stateful interface that draws on whichever plot is current, while ax is an explicit Axes object you draw on directly. Use the object-oriented ax approach for anything beyond a quick single plot.
The short version
plt.something() uses the stateful interface, which acts on whatever plot is currently active. ax.something() calls methods on a specific Axes object you hold a reference to. The ax (object-oriented) style is clearer and essential once you have more than one plot, so prefer it for anything beyond a throwaway single chart.
The two styles side by side
import matplotlib.pyplot as plt
# stateful style
plt.plot([1, 2, 3], [4, 5, 6])
plt.title("stateful")
plt.show()
# object-oriented style
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])
ax.set_title("object-oriented")
plt.show()
Both draw the same line. The difference is that the first relies on a hidden "current axes", while the second names the axes explicitly as ax and calls methods on it.
Why the method names differ
A common confusion is that the setters are named differently between the two. On plt you write plt.title, plt.xlabel, plt.xlim; on an axes you write ax.set_title, ax.set_xlabel, ax.set_xlim. The set_ prefix appears in the object-oriented form. Mixing the two styles in one block is where people get lost, so pick one.
Why the object-oriented style wins for real work
With several subplots, the stateful interface becomes ambiguous, because "the current axes" changes as you go and is easy to lose track of. Holding each axes explicitly removes all doubt about which plot a command affects.
fig, axes = plt.subplots(1, 2)
axes[0].plot([1, 2, 3])
axes[0].set_title("left")
axes[1].plot([3, 2, 1])
axes[1].set_title("right")
Each axes[i] is unambiguous, so the code reads clearly no matter how many panels there are.
What fig and ax each are
plt.subplots() returns two things: the Figure, which is the whole canvas (size, saving, overall title), and the Axes, which is a single plotting area inside it. Use the figure for fig.savefig and fig.suptitle, and the axes for the actual plotting and its labels. Keeping the two roles straight makes the rest of the API easier to navigate.
When the stateful style is fine
For a single quick plot in an interactive session, plt.plot(...) then plt.show() is perfectly reasonable and less to type. The advice to use ax is about scripts, functions and multi-panel figures, where explicitness prevents bugs. For a one-off exploratory line, either is fine.
A note on functions
If you write a function that draws a plot, accept an ax argument and draw on it, defaulting to the current axes. This lets callers place your plot into a larger figure, which the stateful style cannot support cleanly.