Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does plt.gca work internally

Tags:

matplotlib

I have searched on google but didn't get an answer. I created a subplot consisting of 2 axes and called plt.gca() but every time it only referred to the last axis in the axes of my subplots. I then started to wonder if it is possible to get a particular axis by passing in some kwargs but didn't find such parameter. I would really like to know how plt.gca() works and why you can't specify which axis to get.

like image 271
aldnoah Avatar asked Jul 28 '17 20:07

aldnoah


Video Answer


2 Answers

gca means "get current axes".

"Current" here means that it provides a handle to the last active axes. If there is no axes yet, an axes will be created. If you create two subplots, the subplot that is created last is the current one.

There is no such thing as gca(something), because that would translate into "get current axes which is not the current one" - sound unlogical already, doesn't it?

The easiest way to make sure you have a handle to any axes in the plot is to create that handle yourself. E.g.

ax = plt.subplot(121)
ax2 = plt.subplot(122)

You may then use ax or ax2 at any point after that to manipulate the axes of choice.

Also consider using the subplots (note the s) command,

fig, (ax, ax2) = plt.subplots(ncols=2)

If you don't have a handle or forgot to create one, you may get one e.g. via

all_axes = plt.gcf().get_axes()
ax = all_axes[0]

to get the first axes. Since there is no natural order of axes in a plot, this should only be used if no other option is available.

like image 160
ImportanceOfBeingErnest Avatar answered Oct 13 '22 16:10

ImportanceOfBeingErnest


As a supplement to Importance's very fine answer, I thought I would point out the pyplot command sca, which stands for "set current axes".

It takes an axes as an argument and sets it as the current axes, so you still need references to your axes. But the thing about sca that some may find useul is that you can have multiple axes and work on all of them while still using the pyplot interface rather than the object-oriented approach.

import matplotlib.pyplot as plt

fig = plt.figure()
ax = plt.subplot(121)
ax2 = plt.subplot(122)

# Check if ax2 is current axes
print(ax2 is plt.gca())
# >>> True

# Plot on ax2
plt.plot([0,1],[0,1])
plt.xlabel('X')
plt.ylabel('Y')

# Now set ax as current axes
plt.sca(ax)

print(ax2 is plt.gca())
# >>> False
print(ax is plt.gca())
# >>> True

# We can call the exact same commands as we did for ax2, but draw on ax
plt.plot([0,1],[0,1])
plt.xlabel('X')
plt.ylabel('Y')

plt.show()

So you'll notice that we were able to reuse the same code to plot and add labels to both axes.

like image 33
saintsfan342000 Avatar answered Oct 13 '22 16:10

saintsfan342000