matplotlib / matplotlib/ipympl

blitting doesn't work - would be useful to speed up graph draw for faster realtime-graphs

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

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

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

説明

I have the following code in jupyterlab. This allows me to move a slider and update a graph in realtime. However the framerate is quite low (1fps) if I call fig.canvas.draw(). I therefore tried blitting, however it does not seem to affect the graph. Is this supposed to work with ipympl?

Many thanks for your help.

Environment:
Jupyterlab==1.2.6
ipympl==0.5.6
jupyter labextension list:

@ibqn/jupyterlab-codecellbtn v0.1.3 enabled ok
@jupyter-widgets/jupyterlab-manager v1.1.0 enabled ok
@jupyterlab/google-drive v1.0.0 enabled ok
@jupyterlab/toc v1.0.1 enabled ok
jupyter-matplotlib v0.7.2 enabled ok
jupyterlab-plotly v1.5.2 enabled ok
plotlywidget v1.5.2 enabled ok

import pandas as pd, numpy as np
import time
import matplotlib.pyplot as plt

from ipywidgets import interact, interactive, fixed, interact_manual, Layout, VBox, HBox
import ipywidgets as widgets

from itertools import count
%matplotlib widget


blit = False # False works, True doesn't.

plt.close('all')
plt.ioff()

output = widgets.Output(layout={'width': '700px', 'height': '300px'})
fig, axs= plt.subplots(3, 2, figsize=(10, 8), sharex=True)
fig.canvas.header_visible = False
fig.canvas.toolbar_visible = False


for i in range(3):    
    axs[i,0].set_ylim(-1.5,1.5)
    axs[i,0].set_xlim(0,20)
    
# index giver
x_value = count()

# expanding dataset
x, y = [], []

# initialise dummy data
[x.append(next(x_value)) for i in range(2)]
[y.append([1]*3) for i in range(2)]

# setup desired and actual angle plots
col_names = ['col1', 'col2', 'col3']
ax_df = pd.DataFrame(index=x,columns=col_names, data=y).plot(subplots=True, ax=axs[:,0])

if blit:
    bgs = []
    for ax in ax_df:
        # cache the background
        ax_background = fig.canvas.copy_from_bbox(ax.bbox)
        bgs.append(ax_background)
    
    fig.canvas.draw()  # initial draw required

# monitor framerate
t_start = time.time()   

# event handler
def on_value_changed(change):    
    with output:    
        next_x = next(x_value) # generate next x axis value
        x.append(next_x)
        y.append([change.new]*3) 

        for i in range(3):            
            if blit:              
                # update data
                line = ax_df[i].get_lines()[0]
                line.set_data(x, pd.DataFrame(y).iloc[:,i])
                
                # restore background
                fig.canvas.restore_region(bgs[i])
                
                # redraw just the points
                ax_df[i].draw_artist(line)

                # fill in the axes rectangle
                fig.canvas.blit(ax_df[i].bbox)
                
            else:
                # update data
                ax_df[i].get_lines()[0].set_data(x, pd.DataFrame(y).iloc[:,i])

                # rescale view
                ax_df[i].autoscale_view(None,'x',None)
                ax_df[i].relim()
            
        fig.canvas.flush_events()
        
        if not blit:
            fig.canvas.draw() # this slows down framerate, not required for blit

        print(f"FPS: {round(next_x/(time.time() - t_start),2)}", end=", ")

sliders = []
int_slider = widgets.FloatSlider(description="test", 
                                 min=-1, max=1, 
                                 value = 0, continuous_update=True,
                                 orientation="horizontal",                                      
                                 layout=widgets.Layout(width="500px", height="20px"))    
int_slider.observe(on_value_changed, names="value")
sliders = widgets.VBox([int_slider, fig.canvas, output])
display(sliders)


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

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

はじめの一歩

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

調査の方向性

まず、記載されている JupyterLab と ipympl のバージョンで提供された notebook を再現し、fig.canvas.draw() と blitting パスを比較します。copy_from_bbox、restore_region、draw_artist、blit がどのように処理されるかを追跡し、その後、slider の更新によって完全な draw を行わずに、改善されたフレームレートでグラフが目に見えて更新されることを確認します。

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

評価

技術スタック
jupyter-notebook, python
領域
frontend, performance
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
32/100

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

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