1
1
import functools
2
+ import numpy as np
2
3
import warnings
3
4
4
5
from matplotlib import docstring
@@ -31,39 +32,40 @@ def __init__(self, fig, *args, **kwargs):
31
32
"""
32
33
33
34
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...
39
42
try :
40
43
s = str (int (args [0 ]))
41
44
rows , cols , num = map (int , s )
42
45
except ValueError :
43
46
raise ValueError ('Single argument to subplot must be '
44
47
'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 ]
57
61
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 ]]
64
67
# num - 1 for converting from MATLAB to python indexing
65
- else :
66
- raise ValueError ('Illegal argument(s) to subplot: %s' % (args ,))
68
+
67
69
68
70
self .update_params ()
69
71
@@ -87,6 +89,42 @@ def __init__(self, fig, *args, **kwargs):
87
89
name = self ._layoutbox .name + '.pos' ,
88
90
pos = True , subplot = True , artist = self )
89
91
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
+
90
128
def __reduce__ (self ):
91
129
# get the first axes class which does not inherit from a subplotbase
92
130
axes_class = next (
0 commit comments