-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Move impl. of plt.subplots to Figure.add_subplots. #5146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1131,106 +1131,11 @@ def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True, | |
# same as | ||
plt.subplots(2, 2, sharex=True, sharey=True) | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we eliminate a lot of this docstring? Either with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure how to make this work, given that the APIs are subtly different (one returns just the new axes, the other returns a figure, axes pair). Open to suggestions... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not super worried about the duplication of docstrings at this point. An interesting follow on to this PR would be to generate |
||
# for backwards compatibility | ||
if isinstance(sharex, bool): | ||
if sharex: | ||
sharex = "all" | ||
else: | ||
sharex = "none" | ||
if isinstance(sharey, bool): | ||
if sharey: | ||
sharey = "all" | ||
else: | ||
sharey = "none" | ||
share_values = ["all", "row", "col", "none"] | ||
if sharex not in share_values: | ||
# This check was added because it is very easy to type | ||
# `subplots(1, 2, 1)` when `subplot(1, 2, 1)` was intended. | ||
# In most cases, no error will ever occur, but mysterious behavior will | ||
# result because what was intended to be the subplot index is instead | ||
# treated as a bool for sharex. | ||
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 = {} | ||
|
||
fig = figure(**fig_kw) | ||
gs = GridSpec(nrows, ncols, **gridspec_kw) | ||
|
||
# Create empty object array to hold all axes. It's easiest to make it 1-d | ||
# so we can just append subplots upon creation, and then | ||
nplots = nrows*ncols | ||
axarr = np.empty(nplots, dtype=object) | ||
|
||
# Create first subplot separately, so we can share it if requested | ||
ax0 = fig.add_subplot(gs[0, 0], **subplot_kw) | ||
axarr[0] = ax0 | ||
|
||
r, c = np.mgrid[:nrows, :ncols] | ||
r = r.flatten() * ncols | ||
c = c.flatten() | ||
lookup = { | ||
"none": np.arange(nplots), | ||
"all": np.zeros(nplots, dtype=int), | ||
"row": r, | ||
"col": c, | ||
} | ||
sxs = lookup[sharex] | ||
sys = lookup[sharey] | ||
|
||
# Note off-by-one counting because add_subplot uses the MATLAB 1-based | ||
# convention. | ||
for i in range(1, nplots): | ||
if sxs[i] == i: | ||
subplot_kw['sharex'] = None | ||
else: | ||
subplot_kw['sharex'] = axarr[sxs[i]] | ||
if sys[i] == i: | ||
subplot_kw['sharey'] = None | ||
else: | ||
subplot_kw['sharey'] = axarr[sys[i]] | ||
axarr[i] = fig.add_subplot(gs[i // ncols, i % ncols], **subplot_kw) | ||
|
||
# returned axis array will be always 2-d, even if nrows=ncols=1 | ||
axarr = axarr.reshape(nrows, ncols) | ||
|
||
# turn off redundant tick labeling | ||
if sharex in ["col", "all"] and nrows > 1: | ||
# turn off all but the bottom row | ||
for ax in axarr[:-1, :].flat: | ||
for label in ax.get_xticklabels(): | ||
label.set_visible(False) | ||
ax.xaxis.offsetText.set_visible(False) | ||
|
||
if sharey in ["row", "all"] and ncols > 1: | ||
# turn off all but the first column | ||
for ax in axarr[:, 1:].flat: | ||
for label in ax.get_yticklabels(): | ||
label.set_visible(False) | ||
ax.yaxis.offsetText.set_visible(False) | ||
|
||
if squeeze: | ||
# Reshape the array to have the final desired dimension (nrow,ncol), | ||
# though discarding unneeded dimensions that equal 1. If we only have | ||
# one subplot, just return it instead of a 1-element array. | ||
if nplots == 1: | ||
ret = fig, axarr[0, 0] | ||
else: | ||
ret = fig, axarr.squeeze() | ||
else: | ||
# returned axis array will be always 2-d, even if nrows=ncols=1 | ||
ret = fig, axarr.reshape(nrows, ncols) | ||
|
||
return ret | ||
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 subplot2grid(shape, loc, rowspan=1, colspan=1, **kwargs): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we throw a
self.clf()
in here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not, IMO if you use the OO interface you know what you're doing and it's anyways easier for the caller to add a call the
clf
rather than to remove a call toclf
.