用于Matplotlib交互的IPython Notebook小部件 [英] IPython Notebook widgets for Matplotlib interactivity

查看:149
本文介绍了用于Matplotlib交互的IPython Notebook小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to use the ipython notebook widgets to add some degree of interactivity to inline matplotlib plots.

一般情况下,情节可能很重,我只想更新情节的特定元素。我知道小部件内置的限制功能有助于不会泛滥内核,但是当情节需要30秒时,我不想等待这么长时间来更新一行。

In general the plot can be quite heavy and I want to only update a specific element of the plot. I understand that widgets have a throttling feature built-in that helps to don't flood the kernel, but when the plot takes let say 30s I don't want to wait so long just to update a line.

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

By reading the example notebooks I was able to create a basic example in which I add a cross cursor (driven by 2 sliders) to a mpl axis.

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

The problem is that the figure is displayed twice. Here is the code (cell 1):

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

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

... figure displayed ..., cell 2 (edit: thanks Thomas K for the improvement):

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))

再次显示小部件的数字。

shows again the figure with the widgets.

所以问题是:


  1. 如何禁止显示第一个数字?

  2. 是正确的做法还是有更好的方法?

编辑

根据这个笔记本,允许禁止数字显示

I found an ipython config knob that, according to this notebook, allows inhibiting the figure display

%config InlineBackend.close_figures = False

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

While the example notebook works, I can't figure out how to use this option by itself (without the context manager class provided in the linked example) to hide a figure display.

编辑2

我找到了<$ c的一些文档 $ c> InlineBackend.close_figures 可配置。

I found some documentation of the InlineBackend.close_figures configurable.

编辑3

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

Triggered by @shadanan answer, I want to clarify that my purpose is to add a cursor to an existing figure without redrawing the plot from scratch at each cursor movement. Merging the 3 cells in a single cell:

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开发者可以对此发表评论吗?这是一个错误吗?

it "should" work but it doesn't. The first time the cell is executed it shows 2 figures. After widget interaction only 1 figure is displayed. This is the "strange behavior" that requires a workaround like the one shown in @shadanan answer. Can an ipython dev comment on this? Is it a bug?

推荐答案

解决方案结果非常简单。为了避免显示第一个数字,我们只需要在交互调用之前添加 close()调用。

The solution turns out to be really simple. To avoid showing the first figure we just need to add a close() call before the interact call.

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

Recalling the example of the question, a cell like this will correctly show a single interactive figure (instead of two):

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 (在单独的单元格或脚本中):

A cleaner approach is defining the function add_cursor (in a separate cell or script):

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())

然后在我们想要添加交互式光标时调用它:

and then call it whenever we want to add an interactive cursor:

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

这篇关于用于Matplotlib交互的IPython Notebook小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆