使用 ipywidget 更新时在 Jupyter 中刷新 matplotlib

refresh matplotlib in Jupyter when updating with ipywidget

我想在 Jupyter 笔记本中画一条线,可以使用 ipywidget 滑块移动它。我还想显示鼠标坐标,为此我使用 %matplotlib notebook。这是我目前所拥有的:

%matplotlib notebook
from ipywidgets import interact


fig, ax = plt.subplots()

@interact(n=(-200, 0))
def show(n):
    # fig.clear() #doesn't show anything
    y = -n+x
    ax.plot(x, y)
    
    plt.show()

使用滑块移动线时,绘图不刷新,线的所有先前位置 保持可见:

我尝试使用 fig.clear() 进行刷新,但随后注意到显示。

我该如何解决这个问题?

我在这里有一个广泛的答案:Matplotlib figure is not updating with ipywidgets slider

但我的建议是:

  1. 使用 ipympl %matplotlib ipympl 而不是 notebook 因为这会更好地与 ipywidgets
  2. 使用mpl-interactions来处理由滑块控制的绘图。
    • 它会为您使用 set_data 做最优化的事情,而不是清除和重新绘制线条。
    • 它还以一种(我认为)在制作绘图时更有意义的方式来解释数字的 shorthand(例如,使用 linspace 而不是 arange),请参阅 https://mpl-interactions.readthedocs.io/en/stable/comparison.html 了解更多详细信息。

因此,对于您的示例,我建议您这样做:

安装库

pip install ipympl mpl-interactions
%matplotlib ipympl
from ipywidgets import interact
import matplotlib.pyplot as plt
from mpl_interactions import ipyplot as iplt

x = np.linspace(0,100)
fig, ax = plt.subplots()

def y(x, n):
    return x - n
ctrls = iplt.plot(x, y, n=(-200,0))

它变长了一点,因为我添加了你在问题中遗漏的导入,并且还定义了 x。

这给了你这个:

也就是说,如果您不想使用那些,我认为您想要的是 ax.cla() 我认为当您使用 fig.clear 时,您也会删除轴,这就是什么都没有显示的原因。

%matplotlib notebook
from ipywidgets import interact


fig, ax = plt.subplots()

@interact(n=(-200, 0))
def show(n):
    y = -n+x
    ax.cla()
    ax.plot(x, y)

    plt.show()