Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 866a194

Browse files
committed
ENH: make subplot reuse gridspecs if they fit
1 parent bfa8d61 commit 866a194

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

lib/matplotlib/axes/_subplots.py

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import functools
2+
import numpy as np
23
import warnings
34

45
from matplotlib import docstring
@@ -42,25 +43,27 @@ def __init__(self, fig, *args, **kwargs):
4243
except ValueError:
4344
raise ValueError('Single argument to subplot must be '
4445
'a 3-digit integer')
45-
self._subplotspec = GridSpec(rows, cols,
46-
figure=self.figure)[num - 1]
46+
gs, num = self._make_subplotspec(rows, cols, num,
47+
figure=self.figure)
48+
self._subplotspec = gs[num - 1]
4749
# num - 1 for converting from MATLAB to python indexing
4850
elif len(args) == 3:
4951
rows, cols, num = args
5052
rows = int(rows)
5153
cols = int(cols)
5254
if isinstance(num, tuple) and len(num) == 2:
5355
num = [int(n) for n in num]
54-
self._subplotspec = GridSpec(
55-
rows, cols,
56-
figure=self.figure)[(num[0] - 1):num[1]]
56+
gs, num = self._make_subplotspec(rows, cols, num,
57+
figure=self.figure)
58+
self._subplotspec = gs[(num[0] - 1):num[1]]
5759
else:
5860
if num < 1 or num > rows*cols:
5961
raise ValueError(
6062
("num must be 1 <= num <= {maxn}, not {num}"
6163
).format(maxn=rows*cols, num=num))
62-
self._subplotspec = GridSpec(
63-
rows, cols, figure=self.figure)[int(num) - 1]
64+
gs, num = self._make_subplotspec(rows, cols, num,
65+
figure=self.figure)
66+
self._subplotspec = gs[int(num) - 1]
6467
# num - 1 for converting from MATLAB to python indexing
6568
else:
6669
raise ValueError('Illegal argument(s) to subplot: %s' % (args,))
@@ -87,6 +90,42 @@ def __init__(self, fig, *args, **kwargs):
8790
name=self._layoutbox.name+'.pos',
8891
pos=True, subplot=True, artist=self)
8992

93+
def _make_subplotspec(self, rows, cols, num, figure=None):
94+
"""
95+
Return the subplotspec for this subplot, but reuse an old
96+
GridSpec if it exists and if the new gridspec "fits".
97+
"""
98+
axs = figure.get_axes()
99+
for ax in axs:
100+
gs = ax.get_subplotspec().get_gridspec()
101+
(nrow, ncol) = gs.get_geometry()
102+
if (not (nrow % rows) and not (ncol % cols)):
103+
# this gridspec "fits"...
104+
# now we have to see if we need to modify num...
105+
rowfac = int(nrow / rows)
106+
colfac = int(ncol / cols)
107+
if (not isinstance(num, tuple) and
108+
not isinstance(num, list)):
109+
num = [num, num]
110+
# converting between num and rows/cols is a PITA:
111+
newnum = num
112+
row = int(np.floor((num[0]-1) / cols))
113+
col = (num[0]-1) - row * cols
114+
row *= rowfac
115+
col *= colfac
116+
newnum[0] = row * ncol + col + 1
117+
row = int(np.floor((num[1]-1) / cols))
118+
col = (num[1]-1) - row * cols
119+
row *= rowfac
120+
col *= colfac
121+
row = row + (rowfac - 1)
122+
col = col + (colfac - 1)
123+
newnum[1] = row * ncol + col + 1
124+
return gs, newnum
125+
# no axes fit with the new subplot specification so make a
126+
# new one...
127+
return GridSpec(rows, cols, figure=figure), num
128+
90129
def __reduce__(self):
91130
# get the first axes class which does not inherit from a subplotbase
92131
axes_class = next(

lib/matplotlib/figure.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,8 @@ def add_subplot(self, *args, **kwargs):
11971197
fig.add_subplot(111, projection='polar')
11981198
11991199
# add Subplot instance sub
1200+
gs = gridspec.GridSpec(2, 3)
1201+
sub = gs[1, 1]
12001202
fig.add_subplot(sub)
12011203
12021204
See Also

0 commit comments

Comments
 (0)