1
1
import functools
2
+ import numpy as np
2
3
import warnings
3
4
4
5
from matplotlib import docstring
@@ -42,25 +43,27 @@ def __init__(self, fig, *args, **kwargs):
42
43
except ValueError :
43
44
raise ValueError ('Single argument to subplot must be '
44
45
'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 ]
47
49
# num - 1 for converting from MATLAB to python indexing
48
50
elif len (args ) == 3 :
49
51
rows , cols , num = args
50
52
rows = int (rows )
51
53
cols = int (cols )
52
54
if isinstance (num , tuple ) and len (num ) == 2 :
53
55
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 ]]
57
59
else :
58
60
if num < 1 or num > rows * cols :
59
61
raise ValueError (
60
62
("num must be 1 <= num <= {maxn}, not {num}"
61
63
).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 ]
64
67
# num - 1 for converting from MATLAB to python indexing
65
68
else :
66
69
raise ValueError ('Illegal argument(s) to subplot: %s' % (args ,))
@@ -87,6 +90,42 @@ def __init__(self, fig, *args, **kwargs):
87
90
name = self ._layoutbox .name + '.pos' ,
88
91
pos = True , subplot = True , artist = self )
89
92
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
+
90
129
def __reduce__ (self ):
91
130
# get the first axes class which does not inherit from a subplotbase
92
131
axes_class = next (
0 commit comments