matplotlib / matplotlib/ipympl

issue computing repr of `Figure`

Offen
#115 14 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Vorherrschende Sprache
Jupyter Notebook
Sterne
1.7k
Forks
234
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

Due to https://github.com/matplotlib/matplotlib/pull/10292 during a save operation we temporarily remove the manager

%matplotlib widget
import matplotlib.pyplot as plt
plt.plot(range(5))
fig = plt.gcf()

## new cell
fig

and you will get a traceback that looks like:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
~/.virtualenvs/bleeding/lib/python3.9/site-packages/IPython/core/formatters.py in __call__(self, obj)
    339                 pass
    340             else:
--> 341                 return printer(obj)
    342             # Finally look for special method names
    343             method = get_real_method(obj, self.print_method)

~/.virtualenvs/bleeding/lib/python3.9/site-packages/IPython/core/pylabtools.py in <lambda>(fig)
    242 
    243     if 'png' in formats:
--> 244         png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
    245     if 'retina' in formats or 'png2x' in formats:
    246         png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))

~/.virtualenvs/bleeding/lib/python3.9/site-packages/IPython/core/pylabtools.py in print_figure(fig, fmt, bbox_inches, **kwargs)
    126 
    127     bytes_io = BytesIO()
--> 128     fig.canvas.print_figure(bytes_io, **kw)
    129     data = bytes_io.getvalue()
    130     if fmt == 'svg':

~/source/p/mpl-master/lib/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, **kwargs)
   2058             if bbox_inches:
   2059                 if bbox_inches == "tight":
-> 2060                     renderer = _get_renderer(
   2061                         self.figure,
   2062                         functools.partial(

~/source/p/mpl-master/lib/matplotlib/backend_bases.py in _get_renderer(figure, print_method)
   1546     with cbook._setattr_cm(figure, draw=_draw):
   1547         try:
-> 1548             print_method(io.BytesIO())
   1549         except Done as exc:
   1550             figure._cachedRenderer, = exc.args

~/source/p/mpl-master/lib/matplotlib/backends/backend_agg.py in print_png(self, filename_or_obj, metadata, pil_kwargs, *args, **kwargs)
    533 
    534         else:
--> 535             FigureCanvasAgg.draw(self)
    536             renderer = self.get_renderer()
    537             with cbook._setattr_cm(renderer, dpi=self.figure.dpi), \

~/source/p/mpl-master/lib/matplotlib/backends/backend_agg.py in draw(self)
    391         self.renderer = self.get_renderer(cleared=True)
    392         # Acquire a lock on the shared font cache.
--> 393         with RendererAgg.lock, \
    394              (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    395               else nullcontext()):

~/source/other_source/cpython/Lib/contextlib.py in __enter__(self)
    111         del self.args, self.kwds, self.func
    112         try:
--> 113             return next(self.gen)
    114         except StopIteration:
    115             raise RuntimeError("generator didn't yield") from None

~/source/p/mpl-master/lib/matplotlib/backend_bases.py in _wait_cursor_for_draw_cm(self)
   2732         if self._draw_time - last_draw_time > 1:
   2733             try:
-> 2734                 self.set_cursor(cursors.WAIT)
   2735                 yield
   2736             finally:

~/source/p/mpl-master/lib/matplotlib/backends/backend_webagg_core.py in set_cursor(self, cursor)
    379     def set_cursor(self, cursor):
    380         if cursor != self.cursor:
--> 381             self.canvas.send_event("cursor", cursor=cursor)
    382         self.cursor = cursor
    383 

~/source/p/mpl-master/lib/matplotlib/backends/backend_webagg_core.py in send_event(self, event_type, **kwargs)
    344 
    345     def send_event(self, event_type, **kwargs):
--> 346         self.manager._send_event(event_type, **kwargs)
    347 
    348 

AttributeError: 'NoneType' object has no attribute '_send_event'

I thought we should be going through https://github.com/matplotlib/matplotlib/blob/59b5e0e873dd3420758498c90b15f7f70cb007da/lib/matplotlib/figure.py#L403-L408 but it looks like we are going trough a lambda from IPython core....

I think this could legitimately go against IPython, Matplotlib, or here. Leaving here as the "middle ground" ;)

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Reproduziere den Traceback in einem Notebook mit %matplotlib widget. Untersuche anschließend den Figure-repr-Pfad in figure.py um die Zeilen 403-408, die IPython-pylabtools-Formatter-Lambda und backend_webagg_core.py im Bereich von set_cursor und send_event. Als erledigt gilt die Aufgabe, wenn nach Abschluss des Plottens fig angezeigt wird, ohne dass während des Renderings der managerbezogene AttributeError auftritt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
jupyter, matplotlib, python
Bereich
frontend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.