@@ -1072,10 +1072,10 @@ def cla():
1072
1072
@docstring .dedent_interpd
1073
1073
def subplot (* args , ** kwargs ):
1074
1074
"""
1075
- Add a subplot to the current figure.
1075
+ Add an Axes to the current figure or retrieve an existing Axes .
1076
1076
1077
- Wrapper of `.Figure.add_subplot` with a difference in
1078
- behavior explained in the notes section.
1077
+ This is a wrapper of `.Figure.add_subplot` which provides additional
1078
+ behavior when working with the implicit API (see the notes section) .
1079
1079
1080
1080
Call signatures::
1081
1081
@@ -1142,8 +1142,8 @@ def subplot(*args, **kwargs):
1142
1142
1143
1143
Notes
1144
1144
-----
1145
- Creating a subplot will delete any pre-existing subplot that overlaps
1146
- with it beyond sharing a boundary::
1145
+ Creating a new Axes will delete any pre-existing Axes that
1146
+ overlaps with it beyond sharing a boundary::
1147
1147
1148
1148
import matplotlib.pyplot as plt
1149
1149
# plot a line, implicitly creating a subplot(111)
@@ -1156,18 +1156,19 @@ def subplot(*args, **kwargs):
1156
1156
If you do not want this behavior, use the `.Figure.add_subplot` method
1157
1157
or the `.pyplot.axes` function instead.
1158
1158
1159
- If the figure already has a subplot with key (*args*,
1160
- *kwargs*) then it will simply make that subplot current and
1161
- return it. This behavior is deprecated. Meanwhile, if you do
1162
- not want this behavior (i.e., you want to force the creation of a
1163
- new subplot), you must use a unique set of args and kwargs. The axes
1164
- *label* attribute has been exposed for this purpose: if you want
1165
- two subplots that are otherwise identical to be added to the figure,
1166
- make sure you give them unique labels.
1159
+ If no *kwargs* are passed and there exists an Axes in the location
1160
+ specified by *args* then that Axes will be returned rather than a new
1161
+ Axes being created.
1167
1162
1168
- In rare circumstances, `.Figure.add_subplot` may be called with a single
1169
- argument, a subplot axes instance already created in the
1170
- present figure but not in the figure's list of axes.
1163
+ If *kwargs* are passed and there exists an Axes in the location
1164
+ specified by *args*, the projection type is the same, and the
1165
+ *kwargs* match with the existing Axes, then the existing Axes is
1166
+ returned. Otherwise a new Axes is created with the specified
1167
+ parameters. We save a reference to the *kwargs* which we us
1168
+ for this comparison. If any of the values in *kwargs* are
1169
+ mutable we will not detect the case where they are mutated.
1170
+ In these cases we suggest using `.Figure.add_subplot` and the
1171
+ explicit Axes API rather than the implicit pyplot API.
1171
1172
1172
1173
See Also
1173
1174
--------
@@ -1183,10 +1184,10 @@ def subplot(*args, **kwargs):
1183
1184
plt.subplot(221)
1184
1185
1185
1186
# equivalent but more general
1186
- ax1= plt.subplot(2, 2, 1)
1187
+ ax1 = plt.subplot(2, 2, 1)
1187
1188
1188
1189
# add a subplot with no frame
1189
- ax2= plt.subplot(222, frameon=False)
1190
+ ax2 = plt.subplot(222, frameon=False)
1190
1191
1191
1192
# add a polar subplot
1192
1193
plt.subplot(223, projection='polar')
@@ -1199,18 +1200,34 @@ def subplot(*args, **kwargs):
1199
1200
1200
1201
# add ax2 to the figure again
1201
1202
plt.subplot(ax2)
1203
+
1204
+ # make the first axes "current" again
1205
+ plt.subplot(221)
1206
+
1202
1207
"""
1208
+ # Here we will only normalize `polar=True` vs `projection='polar'` and let
1209
+ # downstream code deal with the rest.
1210
+ unset = object ()
1211
+ projection = kwargs .get ('projection' , unset )
1212
+ polar = kwargs .pop ('polar' , unset )
1213
+ if polar is not unset and polar :
1214
+ # if we got mixed messages from the user, raise
1215
+ if projection is not unset and projection != 'polar' :
1216
+ raise ValueError (
1217
+ f"polar={ polar } , yet projection={ projection !r} . "
1218
+ "Only one of these arguments should be supplied."
1219
+ )
1220
+ kwargs ['projection' ] = projection = 'polar'
1203
1221
1204
1222
# if subplot called without arguments, create subplot(1, 1, 1)
1205
1223
if len (args ) == 0 :
1206
1224
args = (1 , 1 , 1 )
1207
1225
1208
- # This check was added because it is very easy to type
1209
- # subplot(1, 2, False) when subplots(1, 2, False) was intended
1210
- # (sharex=False, that is). In most cases, no error will
1211
- # ever occur, but mysterious behavior can result because what was
1212
- # intended to be the sharex argument is instead treated as a
1213
- # subplot index for subplot()
1226
+ # This check was added because it is very easy to type subplot(1, 2, False)
1227
+ # when subplots(1, 2, False) was intended (sharex=False, that is). In most
1228
+ # cases, no error will ever occur, but mysterious behavior can result
1229
+ # because what was intended to be the sharex argument is instead treated as
1230
+ # a subplot index for subplot()
1214
1231
if len (args ) >= 3 and isinstance (args [2 ], bool ):
1215
1232
_api .warn_external ("The subplot index argument to subplot() appears "
1216
1233
"to be a boolean. Did you intend to use "
@@ -1224,15 +1241,24 @@ def subplot(*args, **kwargs):
1224
1241
1225
1242
# First, search for an existing subplot with a matching spec.
1226
1243
key = SubplotSpec ._from_subplot_args (fig , args )
1227
- ax = next (
1228
- (ax for ax in fig .axes
1229
- if hasattr (ax , 'get_subplotspec' ) and ax .get_subplotspec () == key ),
1230
- None )
1231
1244
1232
- # If no existing axes match, then create a new one.
1233
- if ax is None :
1245
+ for ax in fig .axes :
1246
+ # if we found an axes at the position sort out if we can re-use it
1247
+ if hasattr (ax , 'get_subplotspec' ) and ax .get_subplotspec () == key :
1248
+ # if the user passed no kwargs, re-use
1249
+ if kwargs == {}:
1250
+ break
1251
+ # if the axes class and kwargs are identical, reuse
1252
+ elif ax ._projection_init == fig ._process_projection_requirements (
1253
+ * args , ** kwargs
1254
+ ):
1255
+ break
1256
+ else :
1257
+ # we have exhausted the known Axes and none match, make a new one!
1234
1258
ax = fig .add_subplot (* args , ** kwargs )
1235
1259
1260
+ fig .sca (ax )
1261
+
1236
1262
bbox = ax .bbox
1237
1263
axes_to_delete = []
1238
1264
for other_ax in fig .axes :
0 commit comments