Skip to content

Commit ba6e42a

Browse files
committed
Fixed Image pickling closes #3614.
1 parent ee3d2fb commit ba6e42a

File tree

3 files changed

+38
-9
lines changed

3 files changed

+38
-9
lines changed

lib/matplotlib/backends/backend_agg.py

+8
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ def __init__(self, width, height, dpi):
104104
if __debug__: verbose.report('RendererAgg.__init__ done',
105105
'debug-annoying')
106106

107+
def __getstate__(self):
108+
# We only want to preserve the init keywords of the Renderer.
109+
# Anything else can be re-created.
110+
return {'width': self.width, 'height': self.height, 'dpi': self.dpi}
111+
112+
def __setstate__(self, state):
113+
self.__init__(state['width'], state['height'], state['dpi'])
114+
107115
def _get_hinting_flag(self):
108116
if rcParams['text.hinting']:
109117
return LOAD_FORCE_AUTOHINT

lib/matplotlib/image.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010

1111
import os
1212
import warnings
13-
import math
1413

1514
import numpy as np
16-
from numpy import ma
1715

1816
from matplotlib import rcParams
1917
import matplotlib.artist as martist
@@ -113,6 +111,12 @@ def __init__(self, ax,
113111

114112
self.update(kwargs)
115113

114+
def __getstate__(self):
115+
state = super(_AxesImageBase, self).__getstate__()
116+
# We can't pickle the C Image cached object.
117+
state.pop('_imcache', None)
118+
return state
119+
116120
def get_size(self):
117121
"""Get the numrows, numcols of the input image"""
118122
if self._A is None:

lib/matplotlib/tests/test_pickle.py

+24-7
Original file line numberDiff line numberDiff line change
@@ -195,17 +195,34 @@ def test_complete():
195195

196196
def test_no_pyplot():
197197
# tests pickle-ability of a figure not created with pyplot
198-
199-
import pickle as p
200198
from matplotlib.backends.backend_pdf import FigureCanvasPdf as fc
201199
from matplotlib.figure import Figure
202200

203201
fig = Figure()
204-
can = fc(fig)
202+
_ = fc(fig)
205203
ax = fig.add_subplot(1, 1, 1)
206204
ax.plot([1, 2, 3], [1, 2, 3])
207-
208-
# Uncomment to debug any unpicklable objects. This is slow so is not
209-
# uncommented by default.
210-
# recursive_pickle(fig)
211205
pickle.dump(fig, BytesIO(), pickle.HIGHEST_PROTOCOL)
206+
207+
208+
def test_renderer():
209+
from matplotlib.backends.backend_agg import RendererAgg
210+
renderer = RendererAgg(10, 20, 30)
211+
pickle.dump(renderer, BytesIO())
212+
213+
214+
def test_image():
215+
# Prior to v1.4.0 the Image would cache data which was not picklable
216+
# once it had been drawn.
217+
from matplotlib.backends.backend_agg import new_figure_manager
218+
manager = new_figure_manager(1000)
219+
fig = manager.canvas.figure
220+
ax = fig.add_subplot(1,1,1)
221+
ax.imshow(np.arange(12).reshape(3, 4))
222+
manager.canvas.draw()
223+
pickle.dump(fig, BytesIO())
224+
225+
226+
if __name__ == '__main__':
227+
import nose
228+
nose.runmodule(argv=['-s'])

0 commit comments

Comments
 (0)