python - 用于 Matplotlib 交互的 IPython Notebook 小部件

标签 python matplotlib ipython ipython-notebook

我想使用 ipython 笔记本小部件为内联 matplotlib 图添加一定程度的交互性。

一般来说,情节可能会很沉重,我只想更新情节的特定元素。我知道小部件有一个内置的节流功能,有助于避免内核溢出,但是当情节发生时,比如说 30 秒,我不想等这么久只是为了更新一行。

通过阅读 example notebooks我能够创建一个基本示例,其中我将十字光标(由 2 个 slider 驱动)添加到 mpl 轴。

问题是图形显示了两次。这是代码(单元格 1):

fig, ax = plt.subplots() 
ax.plot([3,1,2,4,0,5,3,2,0,2,4])

...显示的图形...,单元格 2(编辑:感谢 Thomas K 的改进):

vline = ax.axvline(1)
hline = ax.axhline(0.5)

def set_cursor(x, y):
    vline.set_xdata((x, x))
    hline.set_ydata((y, y))
    display(fig)

最后(单元格 3):

interact(set_cursor, x=(1, 9, 0.01), y=(0, 5, 0.01))

再次显示带有小部件的图形。

那么问题是:

  1. 如何禁止显示第一个数字?
  2. 这是正确的方法还是有更好的方法?

编辑

根据 this notebook,我发现了一个 ipython 配置旋钮, 允许禁止图形显示

%config InlineBackend.close_figures = False

虽然示例笔记本有效,但我无法弄清楚如何单独使用此选项(没有链接示例中提供的上下文管理器类)来隐藏图形显示。

编辑 2

我找到了 some documentation InlineBackend.close_figures 可配置。

编辑 3

由@shadanan 回答触发,我想澄清一下,我的目的是将光标添加到现有图形,而不是在每次光标移动时从头开始重新绘制绘图。将 3 个单元格合并为一个单元格:

fig, ax = plt.subplots()
ax.plot([3,1,2,4,0,5,3,2,0,2,4])

vline = ax.axvline(1)
hline = ax.axhline(0.5)

def set_cursor(x, y):
    vline.set_xdata((x, x))
    hline.set_ydata((y, y))
    display(fig)

interact(set_cursor, x=(1, 9, 0.01), y=(0, 5, 0.01))

它“应该”起作用,但实际上不起作用。单元格第一次执行时显示 2 个数字。小部件交互后仅显示 1 个图形。这是“奇怪的行为”,需要像@shadanan 回答中所示的解决方法。 ipython 开发人员可以对此发表评论吗?这是一个错误吗?

最佳答案

事实证明,解决方案非常简单。为了避免显示第一个图形,我们只需要在 interact 调用之前添加一个 close() 调用。

回想一下问题的例子,像这样的单元格将正确显示一个交互式图形(而不是两个):

fig, ax = plt.subplots()
ax.plot([3,1,2,4,0,5,3,2,0,2,4])
plt.close(fig)

vline = ax.axvline(1)
hline = ax.axhline(0.5)

def set_cursor(x, y):
    vline.set_xdata((x, x))
    hline.set_ydata((y, y))
    display(fig)

interact(set_cursor, x=(1, 9, 0.01), y=(0, 5, 0.01))

更简洁的方法是定义函数 add_cursor(在单独的单元格或脚本中):

def add_cursor(fig, ax):
    plt.close(fig)

    vline = ax.axvline(1, color='k')
    hline = ax.axhline(0.5, color='k')

    def set_cursor(x, y):
        vline.set_xdata((x, x))
        hline.set_ydata((y, y))
        display(fig)

    interact(set_cursor, x=ax.get_xlim(), y=ax.get_ylim())

然后每当我们想添加一个交互式游标时调用它:

fig, ax = plt.subplots()
ax.plot([3,1,2,4,0,5,3,2,0,2,4])
add_cursor(fig, ax)

关于python - 用于 Matplotlib 交互的 IPython Notebook 小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24961674/

相关文章:

python - 在微调预训练模型的同时在 Keras 中预处理图像的正确方法是什么

python - 'if type(x) == type(()):'是什么意思?

python - Matplotlib 基于值的条形图的不同颜色

python - 使用 Matplotlib 和 csv2rec 设置数据类型

python - IPython 3.5 返回 "bad interpreter: No such file or directory"

python-3.x - 大叶 map 未在 Spyder 中显示

python - 在 python 中显示 Youtube 剪辑

python - 如何在Python中知道日期格式的数据帧是否包含在时间间隔内(矢量化)

python - 我正在尝试在 Python 中创建一个按钮(导入 Tkinter),每次点击后颜色都会改变

python - Matplotlib x 轴日期格式化 ConciseDateFormatter 增加小刻度年份的字体大小