Skip to content

Commit 6e0d751

Browse files
committed
Make draggable legends picklable.
1 parent 17db60b commit 6e0d751

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

lib/matplotlib/offsetbox.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1505,7 +1505,6 @@ def __init__(self, ref_artist, use_blit=False):
15051505
if not ref_artist.pickable():
15061506
ref_artist.set_picker(True)
15071507
self.got_artist = False
1508-
self.canvas = self.ref_artist.figure.canvas
15091508
self._use_blit = use_blit and self.canvas.supports_blit
15101509
self.cids = [
15111510
self.canvas.callbacks._connect_picklable(
@@ -1514,6 +1513,9 @@ def __init__(self, ref_artist, use_blit=False):
15141513
'button_release_event', self.on_release),
15151514
]
15161515

1516+
# A property, not an attribute, to maintain picklability.
1517+
canvas = property(lambda self: self.ref_artist.figure.canvas)
1518+
15171519
def on_motion(self, evt):
15181520
if self._check_still_parented() and self.got_artist:
15191521
dx = evt.x - self.mouse_x

lib/matplotlib/tests/test_pickle.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from io import BytesIO
22
import ast
33
import pickle
4+
import pickletools
45

56
import numpy as np
67
import pytest
@@ -88,16 +89,21 @@ def _generate_complete_test_figure(fig_ref):
8889

8990
plt.subplot(3, 3, 9)
9091
plt.errorbar(x, x * -0.5, xerr=0.2, yerr=0.4)
92+
plt.legend(draggable=True)
9193

9294

9395
@mpl.style.context("default")
9496
@check_figures_equal(extensions=["png"])
9597
def test_complete(fig_test, fig_ref):
9698
_generate_complete_test_figure(fig_ref)
9799
# plotting is done, now test its pickle-ability
98-
pkl = BytesIO()
99-
pickle.dump(fig_ref, pkl, pickle.HIGHEST_PROTOCOL)
100-
loaded = pickle.loads(pkl.getbuffer())
100+
pkl = pickle.dumps(fig_ref, pickle.HIGHEST_PROTOCOL)
101+
# FigureCanvasAgg is picklable, but GUI canvas are generally not, so we make sure
102+
# that it doesn't end up it the pickle. In order to keep the test independent of
103+
# GUI toolkits, just check that there's no reference to FigureCanvasAgg in the
104+
# pickle stream.
105+
assert "FigureCanvasAgg" not in [arg for op, arg, pos in pickletools.genops(pkl)]
106+
loaded = pickle.loads(pkl)
101107
loaded.canvas.draw()
102108

103109
fig_test.set_size_inches(loaded.get_size_inches())

0 commit comments

Comments
 (0)