Skip to content

Figure is unpicklable after savefig #6870

Closed

Description

@Kojoley
import matplotlib.pyplot as plt
import pickle
from io import BytesIO

def test_pickle_after_savefig():
    fig = plt.figure()
    fig.add_subplot(111)
    for fmt in ['pdf', 'png', 'svg']:
        fig.savefig(BytesIO(), format=fmt)
        try:
            pickle.dump(fig, BytesIO())
        except:
            print('Unpickable after "%s"' % fmt)
            raise

test_pickle_after_savefig()
>python test_pickle_after_savefig.py
Unpickable after "svg"
Traceback (most recent call last):
  File "test_pickle_after_savefig.py", line 16, in <module>
    test_pickle_after_savefig()
  File "test_pickle_after_savefig.py", line 11, in test_pickle_after_savefig
    pickle.dump(fig, BytesIO())
TypeError: cannot serialize '_io.TextIOWrapper' object

I think those warnings from pytest are maybe related:

>py.test -n 4 lib/matplotlib/tests/test_backend_svg.py::test_fill_black_with_alpha
============================= test session starts =============================
platform win32 -- Python 3.5.2, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: C:\Working\Repositories\matplotlib, inifile: pytest.ini
plugins: xdist-1.14
gw0 [1] / gw1 [1] / gw2 [1] / gw3 [1]
scheduling tests via LoadScheduling
.sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name=0 mode='r' encoding='cp866'>
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name=1 mode='w' encoding='cp866'>
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name=0 mode='r' encoding='cp866'>
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name=0 mode='r' encoding='cp866'>
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name=1 mode='w' encoding='cp866'>
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name=1 mode='w' encoding='cp866'>
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name=0 mode='r' encoding='cp866'>
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name=1 mode='w' encoding='cp866'>

With a file name pickle fails in the pdf backend (and svg too):

import matplotlib.pylab as plt
import pickle
from io import BytesIO

def test_pickle_after_savefig2():
    fig = plt.figure()
    fig.add_subplot(111)
    for fmt in ['pdf', 'png', 'svg']:
        fig.savefig('test.%s' % fmt, format=fmt)
        try:
            pickle.dump(fig, BytesIO())
        except:
            print('Unpickable format is "%s"' % fmt)
            raise

test_pickle_after_savefig2()
>python test_pickle_after_savefig2.py
Unpickable format is "pdf"
Traceback (most recent call last):
  File "test_pickle_after_savefig2.py", line 16, in <module>
    test_pickle_after_savefig()
  File "test_pickle_after_savefig2.py", line 11, in test_pickle_after_savefig
    pickle.dump(fig, BytesIO())
TypeError: cannot serialize '_io.BufferedWriter' object

Activity

  1. changed the title [-]Figure is unpickable after `savefig`[/-] [+]Figure is unpicklable after `savefig`[/+] on Jul 31, 2016
  2. Kojoley commented on Jul 31, 2016

    @Kojoley
    MemberAuthor

    I have tracked down the problem in the svg backend. XMLWriter (locates in fig._cachedRenderer._renderer.writer) keeps reference to the file object. The easiest solution is to add self.writer = None or del self.writer to the RendererSVG.finalize here, but I still do not know if it is the right solution.

  3. tacaswell commented on Aug 1, 2016

    @tacaswell
    Member

    The way we have solved this in other places in the codebase is to customize __getstate__ and __setstate__ on the objects that have non-pickable children.

  4. Kojoley commented on Aug 1, 2016

    @Kojoley
    MemberAuthor

    But then that warning from pytest will not be solved.

  5. added this to the milestone on Aug 1, 2016
  6. Kojoley commented on Aug 1, 2016

    @Kojoley
    MemberAuthor

    I see not reason why renderer should have reference to the file object passed to savefig

  7. tacaswell commented on Aug 4, 2016

    @tacaswell
    Member

    Yes, you are correct, we should drop the reference to the file object in in the finalize step.

  8. jrbrodie77 commented on Sep 22, 2016

    @jrbrodie77

    UPDATED: I meant to post this comment on #6899 (which is related to this issue)
    I was just getting ready to create an issue with test cases. I'm seeing savefig side effects with 2.0.0b4
    Is this fix in that version?

  9. Kojoley commented on Sep 22, 2016

    @Kojoley
    MemberAuthor

    I'm seeing savefig side effects with 2.0.0b4

    Then you are commenting on a wrong issue.

  10. added 2 commits that reference this issue on Oct 22, 2016
    7fe52ac
    519b050
  11. added 2 commits that reference this issue on Nov 8, 2016
    548d120
    0505585
  12. modified the milestones: , on Dec 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions