@@ -153,9 +153,8 @@ def set_default_color_cycle(clist):
153
153
DeprecationWarning )
154
154
155
155
156
- class _process_plot_var_args :
156
+ class _process_plot_var_args ( object ) :
157
157
"""
158
-
159
158
Process variable length arguments to the plot command, so that
160
159
plot commands like the following are supported::
161
160
@@ -171,6 +170,14 @@ def __init__(self, axes, command='plot'):
171
170
self .command = command
172
171
self .set_color_cycle ()
173
172
173
+ def __getstate__ (self ):
174
+ # note: it is not possible to pickle a itertools.cycle instance
175
+ return {'axes' : self .axes , 'command' : self .command }
176
+
177
+ def __setstate__ (self , state ):
178
+ self .__dict__ = state .copy ()
179
+ self .set_color_cycle ()
180
+
174
181
def set_color_cycle (self , clist = None ):
175
182
if clist is None :
176
183
clist = rcParams ['axes.color_cycle' ]
@@ -281,7 +288,7 @@ def _plot_args(self, tup, kwargs):
281
288
linestyle , marker , color = _process_plot_format (tup [- 1 ])
282
289
tup = tup [:- 1 ]
283
290
elif len (tup ) == 3 :
284
- raise ValueError , 'third arg must be a format string'
291
+ raise ValueError ( 'third arg must be a format string' )
285
292
else :
286
293
linestyle , marker , color = None , None , None
287
294
kw = {}
@@ -354,6 +361,7 @@ class Axes(martist.Artist):
354
361
355
362
def __str__ (self ):
356
363
return "Axes(%g,%g;%gx%g)" % tuple (self ._position .bounds )
364
+
357
365
def __init__ (self , fig , rect ,
358
366
axisbg = None , # defaults to rc axes.facecolor
359
367
frameon = True ,
@@ -488,6 +496,15 @@ def __init__(self, fig, rect,
488
496
self ._ycid = self .yaxis .callbacks .connect ('units finalize' ,
489
497
self .relim )
490
498
499
+ def __setstate__ (self , state ):
500
+ self .__dict__ = state
501
+ # put the _remove_method back on all artists contained within the axes
502
+ for container_name in ['lines' , 'collections' , 'tables' , 'patches' ,
503
+ 'texts' , 'images' ]:
504
+ container = getattr (self , container_name )
505
+ for artist in container :
506
+ artist ._remove_method = container .remove
507
+
491
508
def get_window_extent (self , * args , ** kwargs ):
492
509
"""
493
510
get the axes bounding box in display space; *args* and
@@ -1472,7 +1489,7 @@ def _update_line_limits(self, line):
1472
1489
return
1473
1490
1474
1491
line_trans = line .get_transform ()
1475
-
1492
+
1476
1493
if line_trans == self .transData :
1477
1494
data_path = path
1478
1495
@@ -1491,8 +1508,8 @@ def _update_line_limits(self, line):
1491
1508
else :
1492
1509
data_path = trans_to_data .transform_path (path )
1493
1510
else :
1494
- # for backwards compatibility we update the dataLim with the
1495
- # coordinate range of the given path, even though the coordinate
1511
+ # for backwards compatibility we update the dataLim with the
1512
+ # coordinate range of the given path, even though the coordinate
1496
1513
# systems are completely different. This may occur in situations
1497
1514
# such as when ax.transAxes is passed through for absolute
1498
1515
# positioning.
@@ -1502,7 +1519,7 @@ def _update_line_limits(self, line):
1502
1519
updatex , updatey = line_trans .contains_branch_seperately (
1503
1520
self .transData
1504
1521
)
1505
- self .dataLim .update_from_path (data_path ,
1522
+ self .dataLim .update_from_path (data_path ,
1506
1523
self .ignore_existing_data_limits ,
1507
1524
updatex = updatex ,
1508
1525
updatey = updatey )
@@ -2199,11 +2216,11 @@ def ticklabel_format(self, **kwargs):
2199
2216
cb = False
2200
2217
else :
2201
2218
cb = True
2202
- raise NotImplementedError , "comma style remains to be added"
2219
+ raise NotImplementedError ( "comma style remains to be added" )
2203
2220
elif style == '' :
2204
2221
sb = None
2205
2222
else :
2206
- raise ValueError , "%s is not a valid style value"
2223
+ raise ValueError ( "%s is not a valid style value" )
2207
2224
try :
2208
2225
if sb is not None :
2209
2226
if axis == 'both' or axis == 'x' :
@@ -3706,9 +3723,9 @@ def hlines(self, y, xmin, xmax, colors='k', linestyles='solid',
3706
3723
xmax = np .resize ( xmax , y .shape )
3707
3724
3708
3725
if len (xmin )!= len (y ):
3709
- raise ValueError , 'xmin and y are unequal sized sequences'
3726
+ raise ValueError ( 'xmin and y are unequal sized sequences' )
3710
3727
if len (xmax )!= len (y ):
3711
- raise ValueError , 'xmax and y are unequal sized sequences'
3728
+ raise ValueError ( 'xmax and y are unequal sized sequences' )
3712
3729
3713
3730
verts = [ ((thisxmin , thisy ), (thisxmax , thisy ))
3714
3731
for thisxmin , thisxmax , thisy in zip (xmin , xmax , y )]
@@ -3785,9 +3802,9 @@ def vlines(self, x, ymin, ymax, colors='k', linestyles='solid',
3785
3802
ymax = np .resize ( ymax , x .shape )
3786
3803
3787
3804
if len (ymin )!= len (x ):
3788
- raise ValueError , 'ymin and x are unequal sized sequences'
3805
+ raise ValueError ( 'ymin and x are unequal sized sequences' )
3789
3806
if len (ymax )!= len (x ):
3790
- raise ValueError , 'ymax and x are unequal sized sequences'
3807
+ raise ValueError ( 'ymax and x are unequal sized sequences' )
3791
3808
3792
3809
Y = np .array ([ymin , ymax ]).T
3793
3810
@@ -4768,7 +4785,7 @@ def make_iterable(x):
4768
4785
if len (height ) == 1 :
4769
4786
height *= nbars
4770
4787
else :
4771
- raise ValueError , 'invalid orientation: %s' % orientation
4788
+ raise ValueError ( 'invalid orientation: %s' % orientation )
4772
4789
4773
4790
if len (linewidth ) < nbars :
4774
4791
linewidth *= nbars
@@ -4826,7 +4843,7 @@ def make_iterable(x):
4826
4843
bottom = [bottom [i ] - height [i ]/ 2. for i in xrange (len (bottom ))]
4827
4844
4828
4845
else :
4829
- raise ValueError , 'invalid alignment: %s' % align
4846
+ raise ValueError ( 'invalid alignment: %s' % align )
4830
4847
4831
4848
args = zip (left , bottom , width , height , color , edgecolor , linewidth )
4832
4849
for l , b , w , h , c , e , lw in args :
@@ -5701,7 +5718,7 @@ def computeConfInterval(data, med, iq, bootstrap):
5701
5718
else :
5702
5719
x = [x [:,i ] for i in xrange (nc )]
5703
5720
else :
5704
- raise ValueError , "input x can have no more than 2 dimensions"
5721
+ raise ValueError ( "input x can have no more than 2 dimensions" )
5705
5722
if not hasattr (x [0 ], '__len__' ):
5706
5723
x = [x ]
5707
5724
col = len (x )
@@ -7069,10 +7086,10 @@ def _pcolorargs(self, funcname, *args):
7069
7086
7070
7087
Nx = X .shape [- 1 ]
7071
7088
Ny = Y .shape [0 ]
7072
- if len (X .shape ) <> 2 or X .shape [0 ] == 1 :
7089
+ if len (X .shape ) != 2 or X .shape [0 ] == 1 :
7073
7090
x = X .reshape (1 ,Nx )
7074
7091
X = x .repeat (Ny , axis = 0 )
7075
- if len (Y .shape ) <> 2 or Y .shape [1 ] == 1 :
7092
+ if len (Y .shape ) != 2 or Y .shape [1 ] == 1 :
7076
7093
y = Y .reshape (Ny , 1 )
7077
7094
Y = y .repeat (Nx , axis = 1 )
7078
7095
if X .shape != Y .shape :
@@ -8815,7 +8832,15 @@ def __init__(self, fig, *args, **kwargs):
8815
8832
# _axes_class is set in the subplot_class_factory
8816
8833
self ._axes_class .__init__ (self , fig , self .figbox , ** kwargs )
8817
8834
8818
-
8835
+ def __reduce__ (self ):
8836
+ # get the first axes class which does not inherit from a subplotbase
8837
+ not_subplotbase = lambda c : issubclass (c , Axes ) and \
8838
+ not issubclass (c , SubplotBase )
8839
+ axes_class = [c for c in self .__class__ .mro () if not_subplotbase (c )][0 ]
8840
+ r = [_PicklableSubplotClassConstructor (),
8841
+ (axes_class ,),
8842
+ self .__getstate__ ()]
8843
+ return tuple (r )
8819
8844
8820
8845
def get_geometry (self ):
8821
8846
"""get the subplot geometry, eg 2,2,3"""
@@ -8897,6 +8922,22 @@ def subplot_class_factory(axes_class=None):
8897
8922
# This is provided for backward compatibility
8898
8923
Subplot = subplot_class_factory ()
8899
8924
8925
+
8926
+ class _PicklableSubplotClassConstructor (object ):
8927
+ """
8928
+ This stub class exists to return the appropriate subplot
8929
+ class when __call__-ed with an axes class. This is purely to
8930
+ allow Pickling of Axes and Subplots.
8931
+ """
8932
+ def __call__ (self , axes_class ):
8933
+ # create a dummy object instance
8934
+ subplot_instance = _PicklableSubplotClassConstructor ()
8935
+ subplot_class = subplot_class_factory (axes_class )
8936
+ # update the class to the desired subplot class
8937
+ subplot_instance .__class__ = subplot_class
8938
+ return subplot_instance
8939
+
8940
+
8900
8941
docstring .interpd .update (Axes = martist .kwdoc (Axes ))
8901
8942
docstring .interpd .update (Subplot = martist .kwdoc (Axes ))
8902
8943
0 commit comments