matplotlib / matplotlib/ipympl

issue computing repr of `Figure`

オープン
#115 コメント 14 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
Jupyter Notebook
スター
1.7k
フォーク
234
PR マージ指標
30日以内にマージされた PR はありません

説明

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" ;)

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

%matplotlib widget を使ってノートブックで traceback を再現し、その後、figure.py の 403-408 行付近にある Figure の repr パス、IPython pylabtools の formatter lambda、および set_cursor と send_event 付近の backend_webagg_core.py を調べます。プロットの完了後に、レンダリング中に manager 関連の AttributeError が発生せず fig が表示されれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
jupyter, matplotlib, python
領域
frontend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
説明が足りない
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。