Skip to content

Commit dc87ae6

Browse files
authored
Fix display of interactive Matplotlib (#6450)
* Fix display of interactive Matplotlib * Small fixes
1 parent 06f0318 commit dc87ae6

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

examples/reference/panes/Matplotlib.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@
286286
"cf = ax.contourf(x + dx/2., y + dy/2., z)\n",
287287
"fig.colorbar(cf, ax=ax)\n",
288288
"\n",
289-
"pn.pane.Matplotlib(fig, interactive=True, dpi=72)"
289+
"pn.pane.Matplotlib(fig, interactive=True)"
290290
]
291291
},
292292
{

panel/pane/plot.py

+28-14
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import sys
88

99
from contextlib import contextmanager
10+
from functools import partial
1011
from io import BytesIO
1112
from typing import (
1213
TYPE_CHECKING, Any, ClassVar, Dict, Mapping, Optional,
@@ -19,7 +20,7 @@
1920
)
2021
from bokeh.themes import Theme
2122

22-
from ..io import remove_root
23+
from ..io import remove_root, state
2324
from ..io.notebook import push
2425
from ..util import escape
2526
from ..viewable import Layoutable
@@ -250,6 +251,8 @@ class Matplotlib(Image, IPyWidget):
250251
'interactive', 'object', 'dpi', 'tight', 'high_dpi'
251252
]
252253

254+
_num = 0
255+
253256
@classmethod
254257
def applies(cls, obj: Any) -> float | bool | None:
255258
if 'matplotlib' not in sys.modules:
@@ -269,22 +272,21 @@ def _get_widget(self, fig):
269272
import matplotlib.backends
270273
old_backend = getattr(matplotlib.backends, 'backend', 'agg')
271274

272-
from ipympl.backend_nbagg import Canvas, FigureManager, is_interactive
275+
from ipympl.backend_nbagg import Canvas, FigureManager
273276
from matplotlib._pylab_helpers import Gcf
274277

275278
matplotlib.use(old_backend)
276279

277280
def closer(event):
278-
Gcf.destroy(0)
281+
canvas.mpl_disconnect(cid)
282+
Gcf.destroy(manager)
279283

280284
canvas = Canvas(fig)
281285
fig.patch.set_alpha(0)
282-
manager = FigureManager(canvas, 0)
283-
284-
if is_interactive():
285-
fig.canvas.draw_idle()
286-
287-
canvas.mpl_connect('close_event', closer)
286+
manager = FigureManager(canvas, self._num)
287+
self._num += 1
288+
cid = canvas.mpl_connect('close_event', closer)
289+
state.onload(partial(self._initialize_canvas, manager.canvas))
288290
return manager
289291

290292
@property
@@ -303,7 +305,6 @@ def filetype(self):
303305
def _transform_object(self, obj: Any) -> Dict[str, Any]:
304306
return self._img_type._transform_object(self, obj)
305307

306-
307308
def _imgshape(self, data):
308309
try:
309310
return self._img_type._imgshape(data)
@@ -315,6 +316,11 @@ def _format_html(
315316
):
316317
return self._img_type._format_html(self, src, width, height)
317318

319+
def _transform_object(self, obj: Any) -> Dict[str, Any]:
320+
if self.interactive:
321+
return {}
322+
return self._img_type._transform_object(self, obj)
323+
318324
def _get_model(
319325
self, doc: Document, root: Optional[Model] = None,
320326
parent: Optional[Model] = None, comm: Optional[Comm] = None
@@ -324,27 +330,35 @@ def _get_model(
324330
self.object.set_dpi(self.dpi)
325331
manager = self._get_widget(self.object)
326332
properties = self._get_properties(doc)
327-
del properties['text']
328333
model = self._get_ipywidget(
329334
manager.canvas, doc, root, comm, **properties
330335
)
336+
manager.canvas.draw()
331337
root = root or model
332338
self._models[root.ref['id']] = (model, parent)
333339
self._managers[root.ref['id']] = manager
334340
return model
335341

342+
def _initialize_canvas(self, canvas):
343+
canvas._device_pixel_ratio = 2 if self.high_dpi else 1
344+
canvas._handle_message(None, {'type': 'initialized'}, None)
345+
336346
def _update(self, ref: str, model: Model) -> None:
337347
if not self.interactive:
338-
model.update(**self._get_properties(model.document))
348+
props = self._get_properties(model.document)
349+
model.update(**props)
339350
return
340351
manager = self._managers[ref]
341352
if self.object is not manager.canvas.figure:
342353
self.object.set_dpi(self.dpi)
343354
self.object.patch.set_alpha(0)
344355
manager.canvas.figure = self.object
345356
self.object.set_canvas(manager.canvas)
346-
event = {'width': manager.canvas._width,
347-
'height': manager.canvas._height}
357+
if hasattr(manager.canvas, '_size'):
358+
cw, ch = manager.canvas._size
359+
elif hasattr(manager.canvas, '_width'):
360+
cw, ch = manager.canvas._width, manager.canvas._height
361+
event = {'width': cw, 'height': ch}
348362
manager.canvas.handle_resize(event)
349363
manager.canvas.draw_idle()
350364

0 commit comments

Comments
 (0)