Repository navigation
Closed
Milestone
Description
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
Metadata
Metadata
Assignees
Labels
No labels
Activity
[-]Figure is unpickable after `savefig`[/-][+]Figure is unpicklable after `savefig`[/+]Kojoley commentedon Jul 31, 2016
I have tracked down the problem in the svg backend.
XMLWriter(locates infig._cachedRenderer._renderer.writer) keeps reference to the file object. The easiest solution is to addself.writer = Noneordel self.writerto theRendererSVG.finalizehere, but I still do not know if it is the right solution.tacaswell commentedon Aug 1, 2016
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.Kojoley commentedon Aug 1, 2016
But then that warning from pytest will not be solved.
Kojoley commentedon Aug 1, 2016
I see not reason why renderer should have reference to the file object passed to
savefigtacaswell commentedon Aug 4, 2016
Yes, you are correct, we should drop the reference to the file object in in the finalize step.
jrbrodie77 commentedon Sep 22, 2016
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?
Kojoley commentedon Sep 22, 2016
Then you are commenting on a wrong issue.
Don't pickle Axes' cached renderer.
Don't pickle Axes' cached renderer.
Don't pickle Axes' cached renderer.
Don't pickle Axes' cached renderer.