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

Skip to content

Commit 6ccc62a

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

File tree

2 files changed

+65
-25
lines changed

2 files changed

+65
-25
lines changed

lib/matplotlib/axes/_subplots.py

Lines changed: 63 additions & 25 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
@@ -31,39 +32,40 @@ def __init__(self, fig, *args, **kwargs):
3132
"""
3233

3334
self.figure = fig
34-
35-
if len(args) == 1:
36-
if isinstance(args[0], SubplotSpec):
37-
self._subplotspec = args[0]
38-
else:
35+
if len(args) == 1 and isinstance(args[0], SubplotSpec):
36+
self._subplotspec = args[0]
37+
else:
38+
# we need to make the subplotspec either from a new gridspec or
39+
# an existing one:
40+
if len(args) == 1:
41+
# 223-style argument...
3942
try:
4043
s = str(int(args[0]))
4144
rows, cols, num = map(int, s)
4245
except ValueError:
4346
raise ValueError('Single argument to subplot must be '
4447
'a 3-digit integer')
45-
self._subplotspec = GridSpec(rows, cols,
46-
figure=self.figure)[num - 1]
47-
# num - 1 for converting from MATLAB to python indexing
48-
elif len(args) == 3:
49-
rows, cols, num = args
50-
rows = int(rows)
51-
cols = int(cols)
52-
if isinstance(num, tuple) and len(num) == 2:
53-
num = [int(n) for n in num]
54-
self._subplotspec = GridSpec(
55-
rows, cols,
56-
figure=self.figure)[(num[0] - 1):num[1]]
48+
num = [num, num]
49+
elif len(args) == 3:
50+
rows, cols, num = args
51+
rows = int(rows)
52+
cols = int(cols)
53+
if isinstance(num, tuple) and len(num) == 2:
54+
num = [int(n) for n in num]
55+
else:
56+
if num < 1 or num > rows*cols:
57+
raise ValueError(
58+
("num must be 1 <= num <= {maxn}, not {num}"
59+
).format(maxn=rows*cols, num=num))
60+
num = [num, num]
5761
else:
58-
if num < 1 or num > rows*cols:
59-
raise ValueError(
60-
("num must be 1 <= num <= {maxn}, not {num}"
61-
).format(maxn=rows*cols, num=num))
62-
self._subplotspec = GridSpec(
63-
rows, cols, figure=self.figure)[int(num) - 1]
62+
raise ValueError('Illegal argument(s) to subplot: %s' %
63+
(args,))
64+
gs, num = self._make_subplotspec(rows, cols, num,
65+
figure=self.figure)
66+
self._subplotspec = gs[(num[0] - 1):num[1]]
6467
# num - 1 for converting from MATLAB to python indexing
65-
else:
66-
raise ValueError('Illegal argument(s) to subplot: %s' % (args,))
68+
6769

6870
self.update_params()
6971

@@ -87,6 +89,42 @@ def __init__(self, fig, *args, **kwargs):
8789
name=self._layoutbox.name+'.pos',
8890
pos=True, subplot=True, artist=self)
8991

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