Slow matplotlib and ipywidgets image refresh

我只是一个虾纸丫 提交于 2021-01-07 01:29:04

问题


I'm trying to scroll through some magnetic resonance slices using plt.show() and ipywidgets interact() function. I've found no problem by slowly moving the slider, but an important delay is found when sliding through the slices a little bit faster.

Here below is the code I'm using.

def dicom_animation(x, volume):
    fig = plt.figure(figsize=(8,8))
    plt.imshow(volume['slices'][x]['pixel_array'], cmap=plt.cm.gray)


interact(dicom_animation, volume = fixed(a), x=IntSlider(round(len(a['slices'])/2,0), 0, (len(a['slices'])-1), layout=Layout(width='500px')))

And this is the result.

Is there anything I can do to make the sliding a little bit faster without this important delay?


回答1:


Remaking the figure and calling plt.imshow are both pretty expensive operations which is what is slowing this down. Instead you need to use an interactive matplotlib backend and then use methods like set_data.

Install ipympl

ipympl is an interactive backend for matplotlbi that works in both jupyter nobteook and jupyterlab. It has a nice example notebook that explains things like how to interact with other widgets here: https://github.com/matplotlib/ipympl/blob/0.6.1/examples/ipympl.ipynb

Installing this is significantly easier for JupyterLab 3+ So:

pip install --upgrade jupyterlab ipympl

manually create a slider

While interact is convenient it doesn't tend to play well with ipympl as it expects to completely regenerate the output everytime the slider changes.

%matplotlib ipympl

# the rest of your setup code

fig, ax = plt.figure()
img = ax.imshow(volume['slices'][x]['pixel_array'], cmap=plt.cm.gray)

def update_plot(change):
    img.set_data(volume['slices'][change['new']['pixel_array']
    fig.canvas.draw_idle()

x_slider = IntSlider(round(len(a['slices'])/2,0), 0, (len(a['slices'])-1)
x_slider.observe(update_plot, names='value')

Use mpl-interactions

Manually setting up the slider can be a real hassle. So I wrote a library that to make it easy to control interactive plots using widgets. It handles creating the sliders and does all the correct things such as using set_data for you. It also will use matplotlib sliders if you aren't in a jupyter notebook so it is more portable.

In your case you would be interested in the imshow example or depending on how your data is structured you may also be able to use the hyperslicer.

Your example would then be:

%matplotlib ipympl

import mpl_interactions.ipyplot as iplt
# other setup stuff
volume = a

def f(x):
    return volume['slices'][x]['pixel_array']

fig, ax = plt.subplots()
controls = iplt.imshow(f, cmap=plt.cm.gray, x = np.arange(0, len(a)-1))


来源:https://stackoverflow.com/questions/65264185/slow-matplotlib-and-ipywidgets-image-refresh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!