I coming from java world, and currently trying to learn python for the sake of learning matplotlib. As a java programmer, the following snippet looked very strange.
x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x**2)
f, (ax1, ax2) = plt.subplots(1, 2, sharex='all', sharey='all')
ax1.plot(x, y)
ax1.set_title('Sharing Y axis')
ax2.scatter(x, y)
plt.show()
I was wondering how the plt.show() can read the configurations set on the axes since we doesn't pass any arguments to it. Can someone explain the rough idea how this behavior might be achieved?
EDIT
Since being asked by @ImportanceOfBeingErnest, I might be well clarify my intention. My question is not about how the mechanics that pyplot creating an image, my question is more to how the axes configuration is visible to the pyplot. John Zwinck has attemped in the right direction on answering my question, I myself had come into conclusion that it must be something related to global state. But glancing on the internal implementation of subplots, it gives me confusion.
Let's take some part of the internal implementation of pyplot :
def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True,
subplot_kw=None, gridspec_kw=None, **fig_kw):
fig = figure(**fig_kw)
axs = fig.subplots(nrows=nrows, ncols=ncols, sharex=sharex, sharey=sharey,
squeeze=squeeze, subplot_kw=subplot_kw,
gridspec_kw=gridspec_kw)
return fig, axs
def subplots(self, nrows=1, ncols=1, sharex=False, sharey=False,
squeeze=True, subplot_kw=None, gridspec_kw=None):
if isinstance(sharex, bool):
sharex = "all" if sharex else "none"
if isinstance(sharey, bool):
sharey = "all" if sharey else "none"
share_values = ["all", "row", "col", "none"]
if sharex not in share_values:
if isinstance(sharex, int):
warnings.warn(
"sharex argument to subplots() was an integer. "
"Did you intend to use subplot() (without 's')?")
raise ValueError("sharex [%s] must be one of %s" %
(sharex, share_values))
if sharey not in share_values:
raise ValueError("sharey [%s] must be one of %s" %
(sharey, share_values))
if subplot_kw is None:
subplot_kw = {}
if gridspec_kw is None:
gridspec_kw = {}
if self.get_constrained_layout():
gs = GridSpec(nrows, ncols, figure=self, **gridspec_kw)
else:
# this should turn constrained_layout off if we don't want it
gs = GridSpec(nrows, ncols, figure=None, **gridspec_kw)
# Create array to hold all axes.
axarr = np.empty((nrows, ncols), dtype=object)
for row in range(nrows):
for col in range(ncols):
shared_with = {"none": None, "all": axarr[0, 0],
"row": axarr[row, 0], "col": axarr[0, col]}
subplot_kw["sharex"] = shared_with[sharex]
subplot_kw["sharey"] = shared_with[sharey]
axarr[row, col] = self.add_subplot(gs[row, col], **subplot_kw)
# turn off redundant tick labeling
if sharex in ["col", "all"]:
# turn off all but the bottom row
for ax in axarr[:-1, :].flat:
ax.xaxis.set_tick_params(which='both',
labelbottom=False, labeltop=False)
ax.xaxis.offsetText.set_visible(False)
if sharey in ["row", "all"]:
# turn off all but the first column
for ax in axarr[:, 1:].flat:
ax.yaxis.set_tick_params(which='both',
labelleft=False, labelright=False)
ax.yaxis.offsetText.set_visible(False)
if squeeze:
# Discarding unneeded dimensions that equal 1. If we only have one
# subplot, just return it instead of a 1-element array.
return axarr.item() if axarr.size == 1 else axarr.squeeze()
else:
# Returned axis array will be always 2-d, even if nrows=ncols=1.
return axarr
For all that I aware of, the axes is created as a numpy array in this line
axarr = np.empty((nrows, ncols), dtype=object)
But this is a local variable and doesn't indicate how the state of the axes that had been changed on the main program can be visible to the pyplot. This is my actual question.