Jupyter Notebook:使用小部件进行交互式绘图

61

我正在尝试生成一个依赖于小部件的交互式图表。 我的问题是,当我使用滑块更改参数时,会在之前的图表后创建一个新的图表,而不是只有一个根据参数变化的图表。

例子:

from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets

import matplotlib.pyplot as plt
%matplotlib inline

import numpy as np

def plot_func(freq):
    x = np.linspace(0, 2*np.pi)
    y = np.sin(x * freq)
    plt.plot(x, y)

interact(plot_func, freq = widgets.FloatSlider(value=7.5,
                                               min=1,
                                               max=5.0,
                                               step=0.5))

将滑块移动到4.0后,我得到了:

enter image description here

然而当我移动滑块时,我只想要一个数字改变。如何实现呢?

(我使用的是Python 2.7、matplotlib 2.0,而且我刚刚更新了notebook和jupyter到最新版本。如果需要更多信息,请告诉我。)

3个回答

73

如果你想要修改图形而不是创建一个新的,我建议尝试以下方法:

  1. 使用交互式后端:%matplotlib notebook
  2. 更新图中的线条,而不是绘制新的线条。

这样代码可能会像这样:

%matplotlib notebook
from ipywidgets import *
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(x, np.sin(x))

def update(w = 1.0):
    line.set_ydata(np.sin(w * x))
    fig.canvas.draw_idle()

interact(update);

输入图像描述

或者您可以像这个答案中所示,使用plt.show()


1
line, = ax.plot(x, np.sin(x))这一行中,为什么在line后面有一个逗号? - Boris Yakubchik
1
@BorisYakubchik 请查看此链接:这个尾随逗号是逗号运算符吗? - ImportanceOfBeingErnest
@ImportanceOfBeingErnest 当我点击小部件并尝试滑动它时,它会消失。有任何想法吗?Jupyter版本信息:笔记本服务器的版本为4.3.1,正在运行Python 3.6.6,IPython 5.1.0。 - vestland
2
@vestland 我刚刚使用Python 3.6.6、jupyter core 4.4.0、notebook server 5.6.0、jupyter_client 5.2.3、jupyter_console 5.2.0、Ipython 6.5.0、ipywidgets 7.4.2(不确定哪个是相关的),测试了一下,结果符合预期。 - ImportanceOfBeingErnest
1
对我来说,fig.canvas.draw_idle() 更好,因为快速参数更改不会留下“幽灵”图。 - norok2
这是一个非常好的简单例子。谢谢! - twinturbotom

3

为了完整起见,这里提供一个答案,它使用了多个滑动条,并设置了默认参数以及间隔长度。

%matplotlib notebook
from ipywidgets import *
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-10, 10,100)

def f(x, A, B, C):
    return A*x**2 + B*x + C

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(x, f(x, A=1, B=1, C=1))

def update(A = 1, B = 0, C = 0):
    line.set_ydata(f(x,A,B,C))
    fig.canvas.draw_idle()
    
interact(update, A = (-4,4,0.1), B = (-4,4,0.1), C = (-4,4,0.1));

enter image description here


更新散点图怎么样? - Ziyuan

2

这是在最新版本的jupyter和/或ipywidgets中引入的问题。我找到的一个解决方法是在plot_func的结尾添加一行plt.show()


1
这会在每次滑块更新时创建一个新的图形,对吗?所以,看起来这是所有解决方案中最低效的? - ImportanceOfBeingErnest
@ImportanceOfBeingErnest 每次滑块更新都创建一个新的图形显然不是高效的。你的方法很好(+1)。我之所以添加这个答案,是因为它解决了原始帖子中低效的方法。说实话,我发现这种低效的方法更方便快速地查看函数属性。 - Stelios
我明白了,也许你可以把那个参数加到答案里? - ImportanceOfBeingErnest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接