Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 91f58db

Browse filesBrowse files
committed
Merge pull request #5146 from anntzer/figure-subplots
ENH: Move impl. of plt.subplots to Figure.add_subplots. close #5139
2 parents 37182ee + eded075 commit 91f58db
Copy full SHA for 91f58db

File tree

Expand file treeCollapse file tree

2 files changed

+137
-99
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+137
-99
lines changed

‎lib/matplotlib/figure.py

Copy file name to clipboardExpand all lines: lib/matplotlib/figure.py
+133Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
from matplotlib.axes import Axes, SubplotBase, subplot_class_factory
4141
from matplotlib.blocking_input import BlockingMouseInput, BlockingKeyMouseInput
42+
from matplotlib.gridspec import GridSpec
4243
from matplotlib.legend import Legend
4344
from matplotlib.patches import Rectangle
4445
from matplotlib.projections import (get_projection_names,
@@ -1011,6 +1012,138 @@ def add_subplot(self, *args, **kwargs):
10111012
a.stale_callback = _stale_figure_callback
10121013
return a
10131014

1015+
def subplots(self, nrows=1, ncols=1, sharex=False, sharey=False,
1016+
squeeze=True, subplot_kw=None, gridspec_kw=None):
1017+
"""
1018+
Add a set of subplots to this figure.
1019+
1020+
Parameters
1021+
----------
1022+
nrows : int, default: 1
1023+
Number of rows of the subplot grid.
1024+
1025+
ncols : int, default: 1
1026+
Number of columns of the subplot grid.
1027+
1028+
sharex : {"none", "all", "row", "col"} or bool, default: False
1029+
If *False*, or "none", each subplot has its own X axis.
1030+
1031+
If *True*, or "all", all subplots will share an X axis, and the x
1032+
tick labels on all but the last row of plots will be invisible.
1033+
1034+
If "col", each subplot column will share an X axis, and the x
1035+
tick labels on all but the last row of plots will be invisible.
1036+
1037+
If "row", each subplot row will share an X axis.
1038+
1039+
sharey : {"none", "all", "row", "col"} or bool, default: False
1040+
If *False*, or "none", each subplot has its own Y axis.
1041+
1042+
If *True*, or "all", all subplots will share an Y axis, and the y
1043+
tick labels on all but the first column of plots will be invisible.
1044+
1045+
If "row", each subplot row will share an Y axis, and the y tick
1046+
labels on all but the first column of plots will be invisible.
1047+
1048+
If "col", each subplot column will share an Y axis.
1049+
1050+
squeeze : bool, default: True
1051+
If *True*, extra dimensions are squeezed out from the returned axes
1052+
array:
1053+
1054+
- if only one subplot is constructed (nrows=ncols=1), the resulting
1055+
single Axes object is returned as a scalar.
1056+
1057+
- for Nx1 or 1xN subplots, the returned object is a 1-d numpy
1058+
object array of Axes objects are returned as numpy 1-d arrays.
1059+
1060+
- for NxM subplots with N>1 and M>1 are returned as a 2d array.
1061+
1062+
If *False*, no squeezing at all is done: the returned object is
1063+
always a 2-d array of Axes instances, even if it ends up being 1x1.
1064+
1065+
subplot_kw : dict, default: {}
1066+
Dict with keywords passed to the
1067+
:meth:`~matplotlib.figure.Figure.add_subplot` call used to create
1068+
each subplots.
1069+
1070+
gridspec_kw : dict, default: {}
1071+
Dict with keywords passed to the
1072+
:class:`~matplotlib.gridspec.GridSpec` constructor used to create
1073+
the grid the subplots are placed on.
1074+
1075+
Returns
1076+
-------
1077+
ax : single Axes object or array of Axes objects
1078+
The added axes. The dimensions of the resulting array can be
1079+
controlled with the squeeze keyword, see above.
1080+
1081+
See Also
1082+
--------
1083+
pyplot.subplots : pyplot API; docstring includes examples.
1084+
"""
1085+
1086+
# for backwards compatibility
1087+
if isinstance(sharex, bool):
1088+
sharex = "all" if sharex else "none"
1089+
if isinstance(sharey, bool):
1090+
sharey = "all" if sharey else "none"
1091+
share_values = ["all", "row", "col", "none"]
1092+
if sharex not in share_values:
1093+
# This check was added because it is very easy to type
1094+
# `subplots(1, 2, 1)` when `subplot(1, 2, 1)` was intended.
1095+
# In most cases, no error will ever occur, but mysterious behavior
1096+
# will result because what was intended to be the subplot index is
1097+
# instead treated as a bool for sharex.
1098+
if isinstance(sharex, int):
1099+
warnings.warn(
1100+
"sharex argument to add_subplots() was an integer. "
1101+
"Did you intend to use add_subplot() (without 's')?")
1102+
1103+
raise ValueError("sharex [%s] must be one of %s" %
1104+
(sharex, share_values))
1105+
if sharey not in share_values:
1106+
raise ValueError("sharey [%s] must be one of %s" %
1107+
(sharey, share_values))
1108+
if subplot_kw is None:
1109+
subplot_kw = {}
1110+
if gridspec_kw is None:
1111+
gridspec_kw = {}
1112+
1113+
gs = GridSpec(nrows, ncols, **gridspec_kw)
1114+
1115+
# Create array to hold all axes.
1116+
axarr = np.empty((nrows, ncols), dtype=object)
1117+
for row in range(nrows):
1118+
for col in range(ncols):
1119+
shared_with = {"none": None, "all": axarr[0, 0],
1120+
"row": axarr[row, 0], "col": axarr[0, col]}
1121+
subplot_kw["sharex"] = shared_with[sharex]
1122+
subplot_kw["sharey"] = shared_with[sharey]
1123+
axarr[row, col] = self.add_subplot(gs[row, col], **subplot_kw)
1124+
1125+
# turn off redundant tick labeling
1126+
if sharex in ["col", "all"]:
1127+
# turn off all but the bottom row
1128+
for ax in axarr[:-1, :].flat:
1129+
for label in ax.get_xticklabels():
1130+
label.set_visible(False)
1131+
ax.xaxis.offsetText.set_visible(False)
1132+
if sharey in ["row", "all"]:
1133+
# turn off all but the first column
1134+
for ax in axarr[:, 1:].flat:
1135+
for label in ax.get_yticklabels():
1136+
label.set_visible(False)
1137+
ax.yaxis.offsetText.set_visible(False)
1138+
1139+
if squeeze:
1140+
# Discarding unneeded dimensions that equal 1. If we only have one
1141+
# subplot, just return it instead of a 1-element array.
1142+
return axarr.item() if axarr.size == 1 else axarr.squeeze()
1143+
else:
1144+
# Returned axis array will be always 2-d, even if nrows=ncols=1.
1145+
return axarr
1146+
10141147
def clf(self, keep_observers=False):
10151148
"""
10161149
Clear the figure.

‎lib/matplotlib/pyplot.py

Copy file name to clipboardExpand all lines: lib/matplotlib/pyplot.py
+4-99Lines changed: 4 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,106 +1142,11 @@ def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True,
11421142
# same as
11431143
plt.subplots(2, 2, sharex=True, sharey=True)
11441144
"""
1145-
# for backwards compatibility
1146-
if isinstance(sharex, bool):
1147-
if sharex:
1148-
sharex = "all"
1149-
else:
1150-
sharex = "none"
1151-
if isinstance(sharey, bool):
1152-
if sharey:
1153-
sharey = "all"
1154-
else:
1155-
sharey = "none"
1156-
share_values = ["all", "row", "col", "none"]
1157-
if sharex not in share_values:
1158-
# This check was added because it is very easy to type
1159-
# `subplots(1, 2, 1)` when `subplot(1, 2, 1)` was intended.
1160-
# In most cases, no error will ever occur, but mysterious behavior will
1161-
# result because what was intended to be the subplot index is instead
1162-
# treated as a bool for sharex.
1163-
if isinstance(sharex, int):
1164-
warnings.warn("sharex argument to subplots() was an integer."
1165-
" Did you intend to use subplot() (without 's')?")
1166-
1167-
raise ValueError("sharex [%s] must be one of %s" %
1168-
(sharex, share_values))
1169-
if sharey not in share_values:
1170-
raise ValueError("sharey [%s] must be one of %s" %
1171-
(sharey, share_values))
1172-
if subplot_kw is None:
1173-
subplot_kw = {}
1174-
if gridspec_kw is None:
1175-
gridspec_kw = {}
1176-
11771145
fig = figure(**fig_kw)
1178-
gs = GridSpec(nrows, ncols, **gridspec_kw)
1179-
1180-
# Create empty object array to hold all axes. It's easiest to make it 1-d
1181-
# so we can just append subplots upon creation, and then
1182-
nplots = nrows*ncols
1183-
axarr = np.empty(nplots, dtype=object)
1184-
1185-
# Create first subplot separately, so we can share it if requested
1186-
ax0 = fig.add_subplot(gs[0, 0], **subplot_kw)
1187-
axarr[0] = ax0
1188-
1189-
r, c = np.mgrid[:nrows, :ncols]
1190-
r = r.flatten() * ncols
1191-
c = c.flatten()
1192-
lookup = {
1193-
"none": np.arange(nplots),
1194-
"all": np.zeros(nplots, dtype=int),
1195-
"row": r,
1196-
"col": c,
1197-
}
1198-
sxs = lookup[sharex]
1199-
sys = lookup[sharey]
1200-
1201-
# Note off-by-one counting because add_subplot uses the MATLAB 1-based
1202-
# convention.
1203-
for i in range(1, nplots):
1204-
if sxs[i] == i:
1205-
subplot_kw['sharex'] = None
1206-
else:
1207-
subplot_kw['sharex'] = axarr[sxs[i]]
1208-
if sys[i] == i:
1209-
subplot_kw['sharey'] = None
1210-
else:
1211-
subplot_kw['sharey'] = axarr[sys[i]]
1212-
axarr[i] = fig.add_subplot(gs[i // ncols, i % ncols], **subplot_kw)
1213-
1214-
# returned axis array will be always 2-d, even if nrows=ncols=1
1215-
axarr = axarr.reshape(nrows, ncols)
1216-
1217-
# turn off redundant tick labeling
1218-
if sharex in ["col", "all"] and nrows > 1:
1219-
# turn off all but the bottom row
1220-
for ax in axarr[:-1, :].flat:
1221-
for label in ax.get_xticklabels():
1222-
label.set_visible(False)
1223-
ax.xaxis.offsetText.set_visible(False)
1224-
1225-
if sharey in ["row", "all"] and ncols > 1:
1226-
# turn off all but the first column
1227-
for ax in axarr[:, 1:].flat:
1228-
for label in ax.get_yticklabels():
1229-
label.set_visible(False)
1230-
ax.yaxis.offsetText.set_visible(False)
1231-
1232-
if squeeze:
1233-
# Reshape the array to have the final desired dimension (nrow,ncol),
1234-
# though discarding unneeded dimensions that equal 1. If we only have
1235-
# one subplot, just return it instead of a 1-element array.
1236-
if nplots == 1:
1237-
ret = fig, axarr[0, 0]
1238-
else:
1239-
ret = fig, axarr.squeeze()
1240-
else:
1241-
# returned axis array will be always 2-d, even if nrows=ncols=1
1242-
ret = fig, axarr.reshape(nrows, ncols)
1243-
1244-
return ret
1146+
axs = fig.subplots(nrows=nrows, ncols=ncols, sharex=sharex, sharey=sharey,
1147+
squeeze=squeeze, subplot_kw=subplot_kw,
1148+
gridspec_kw=gridspec_kw)
1149+
return fig, axs
12451150

12461151

12471152
def subplot2grid(shape, loc, rowspan=1, colspan=1, **kwargs):

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.