From ba6e42a0c2abe55d49f591145412e763177a6c00 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Wed, 8 Oct 2014 12:40:11 +0100 Subject: [PATCH 1/2] Fixed Image pickling closes #3614. --- lib/matplotlib/backends/backend_agg.py | 8 +++++++ lib/matplotlib/image.py | 8 +++++-- lib/matplotlib/tests/test_pickle.py | 31 ++++++++++++++++++++------ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py index b60227128c17..4cb14a6fe130 100644 --- a/lib/matplotlib/backends/backend_agg.py +++ b/lib/matplotlib/backends/backend_agg.py @@ -104,6 +104,14 @@ def __init__(self, width, height, dpi): if __debug__: verbose.report('RendererAgg.__init__ done', 'debug-annoying') + def __getstate__(self): + # We only want to preserve the init keywords of the Renderer. + # Anything else can be re-created. + return {'width': self.width, 'height': self.height, 'dpi': self.dpi} + + def __setstate__(self, state): + self.__init__(state['width'], state['height'], state['dpi']) + def _get_hinting_flag(self): if rcParams['text.hinting']: return LOAD_FORCE_AUTOHINT diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index d3bb5654477d..be7e94d5d36c 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -10,10 +10,8 @@ import os import warnings -import math import numpy as np -from numpy import ma from matplotlib import rcParams import matplotlib.artist as martist @@ -113,6 +111,12 @@ def __init__(self, ax, self.update(kwargs) + def __getstate__(self): + state = super(_AxesImageBase, self).__getstate__() + # We can't pickle the C Image cached object. + state.pop('_imcache', None) + return state + def get_size(self): """Get the numrows, numcols of the input image""" if self._A is None: diff --git a/lib/matplotlib/tests/test_pickle.py b/lib/matplotlib/tests/test_pickle.py index 98ed882175a8..14062bfd1917 100644 --- a/lib/matplotlib/tests/test_pickle.py +++ b/lib/matplotlib/tests/test_pickle.py @@ -195,17 +195,34 @@ def test_complete(): def test_no_pyplot(): # tests pickle-ability of a figure not created with pyplot - - import pickle as p from matplotlib.backends.backend_pdf import FigureCanvasPdf as fc from matplotlib.figure import Figure fig = Figure() - can = fc(fig) + _ = fc(fig) ax = fig.add_subplot(1, 1, 1) ax.plot([1, 2, 3], [1, 2, 3]) - - # Uncomment to debug any unpicklable objects. This is slow so is not - # uncommented by default. -# recursive_pickle(fig) pickle.dump(fig, BytesIO(), pickle.HIGHEST_PROTOCOL) + + +def test_renderer(): + from matplotlib.backends.backend_agg import RendererAgg + renderer = RendererAgg(10, 20, 30) + pickle.dump(renderer, BytesIO()) + + +def test_image(): + # Prior to v1.4.0 the Image would cache data which was not picklable + # once it had been drawn. + from matplotlib.backends.backend_agg import new_figure_manager + manager = new_figure_manager(1000) + fig = manager.canvas.figure + ax = fig.add_subplot(1,1,1) + ax.imshow(np.arange(12).reshape(3, 4)) + manager.canvas.draw() + pickle.dump(fig, BytesIO()) + + +if __name__ == '__main__': + import nose + nose.runmodule(argv=['-s']) From 4ba18d4b47f6233cfc244cf53a4d85c345db3650 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Thu, 9 Oct 2014 14:18:35 +0100 Subject: [PATCH 2/2] Fixed post draw pickling of Line2D --- lib/matplotlib/lines.py | 6 ++++++ lib/matplotlib/tests/test_pickle.py | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index cb7cd3ecb7d0..f9098d547de8 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -352,6 +352,12 @@ def __init__(self, xdata, ydata, self._invalidy = True self.set_data(xdata, ydata) + def __getstate__(self): + state = super(Line2D, self).__getstate__() + # _linefunc will be restored on draw time. + state.pop('_lineFunc', None) + return state + def contains(self, mouseevent): """ Test whether the mouse event occurred on the line. The pick diff --git a/lib/matplotlib/tests/test_pickle.py b/lib/matplotlib/tests/test_pickle.py index 14062bfd1917..0c289c2c702a 100644 --- a/lib/matplotlib/tests/test_pickle.py +++ b/lib/matplotlib/tests/test_pickle.py @@ -107,6 +107,8 @@ def test_simple(): plt.plot(list(xrange(10)), label='foobar') plt.legend() + # Uncomment to debug any unpicklable objects. This is slow so is not + # uncommented by default. # recursive_pickle(fig) pickle.dump(ax, BytesIO(), pickle.HIGHEST_PROTOCOL) @@ -217,12 +219,25 @@ def test_image(): from matplotlib.backends.backend_agg import new_figure_manager manager = new_figure_manager(1000) fig = manager.canvas.figure - ax = fig.add_subplot(1,1,1) + ax = fig.add_subplot(1, 1, 1) ax.imshow(np.arange(12).reshape(3, 4)) manager.canvas.draw() pickle.dump(fig, BytesIO()) +def test_grid(): + from matplotlib.backends.backend_agg import new_figure_manager + manager = new_figure_manager(1000) + fig = manager.canvas.figure + ax = fig.add_subplot(1, 1, 1) + ax.grid() + # Drawing the grid triggers instance methods to be attached + # to the Line2D object (_lineFunc). + manager.canvas.draw() + + pickle.dump(ax, BytesIO()) + + if __name__ == '__main__': import nose nose.runmodule(argv=['-s']) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy