实际上可以将数据(回调)从mpld3传递到ipython吗?

2024-09-26 17:45:55 发布

您现在位置:Python中文网/ 问答频道 /正文

使用mpld3创建动画图片有很多惊人的可能性。然而,似乎所有的“移动部件”都是JavaScript的责任。此外,在因特网上有很多请求和堆栈溢出,人们直接要求这种可能性。在

Retrieve Data From Dynamic mpld3 plot in python

Get point information after dragging

How to "dump" points selected with the LinkedBrush plugin for mpld3?

mpld3 ~ Select points and get their coordinates?

但所有的答案都是错误的,因为他们建议使用某种警告或说明。然而,第二个链接是最有趣的,因为它建议添加一些HTML表单,然后按下按钮将数据从“clientjavascript”发送到“serverpython”。还有一个有趣的笔记本

http://nbviewer.jupyter.org/gist/aflaxman/11156203

这被许多人认为是灵感的源泉——它保存了输出配置的.html文件。也许这个硬盘交换可以被python用来进一步处理这些信息。在

更进一步,我发现了IPYwidgets,其中有大量的示例,甚至还有真正交互客户机服务器的可能性。本质上,我们可以从基本的滑块和按钮开始,但是我们看到一些更复杂的包是基于这个基础构建的:主要是bqplot,以及其他一些继承的包。在

我想要的只是在图片上拖放一些点,然后将它们传递给iPython来绘制更多的图-这非常复杂,绝对不能移动到JavaScript中。但是,尽管bqplot团队已经做了大量的工作,但是您只能使用一些“预定义”的交互集,因此拖放行为再次不包括在内。在

当我试图(不是很深入地)输入mpld3的源代码并对其进行修改并可能与ipywidgets合并时,我发现很多东西都被弃用了,代码的发展非常快,这与互联网上现有的例子不符:大多数popular的都很老,查询也很古老。所以我什么也做不了,因为混乱,很多例子失败是因为缺乏向后兼容性。在

总结。如果有人提供某种方法来拖放点并将它们的坐标传递给python,我会很高兴的,但我更有用的是,能够以更“抽象的方式”从mpld3传递信息,这样就可以包括其他情况。在


Tags: data堆栈部件javascript可能性按钮建议责任
3条回答

自从这个问题被提出以来,已经快一年了。好吧,答案不是关于mpld3,但我不坚持那种特定的技术。用户@Drew建议使用bqplot,因此我发布了一个相关笔记本的链接

https://github.com/bloomberg/bqplot/blob/master/examples/Interactions/Interaction%20Layer.ipynb

来自bloomberg。如果您打开这个,我建议您找到右上角的链接,它会将您重定向到带有图片的外部nbviewer。几乎所有的东西都包含在那里,我只是试图重现一个极简的工作示例。在

请注意,为了启动扩展名为bqplotjupyter notebook,以及一些{},您可能需要做一些“魔术”来使其工作。您需要熟悉一些bash命令,如jupyter install nbextension和{}。我个人不得不与bqplot斗争几个小时才能使其工作。但这显然是另一个问题。在

让我们尝试启动函数observe。测试函数my_callback(...)只打印事件。在

%matplotlib inline
from bqplot import pyplot as plt

def my_callback(change):
    print change

scatt = plt.scatter([1,2,3],[4,5,6],enable_move=True)
scatt.observe(my_callback)
plt.show()

你得到了这样一个很好的情节: Random plot from bqplot

具有额外的拖动点的能力。一旦您拖动一个点,您将看到一个打印的更改列表,它是一个python结构,每个事件都在一个单独的行上。在

enter image description here

{'owner': , 'new': {u'hovered_point': 1}, 'old': traitlets.Undefined, 'name': '_property_lock', 'type': 'change'}

{'owner': , 'new': 1, 'old': None, 'name': 'hovered_point', 'type': 'change'}

{'owner': , 'new': {}, 'old': {u'hovered_point': 1}, 'name': '_property_lock', 'type': 'change'}

{'owner': , 'new': {u'y': {u'type': u'float', u'values': [4, 4.863453784620906, 6]}, u'x': {u'type': u'float', u'values': [1, 2.016078455307904, 3]}}, 'old': {}, 'name': '_property_lock', 'type': 'change'}

{'owner': , 'new': array([ 4. , 4.86345378, 6. ]), 'old': array([4, 5, 6]), 'name': 'y', 'type': 'change'}

{'owner': , 'new': array([ 1. , 2.01607846, 3. ]), 'old': array([1, 2, 3]), 'name': 'x', 'type': 'change'}

{'owner': , 'new': {}, 'old': {u'y': {u'type': u'float', u'values': [4, 4.863453784620906, 6]}, u'x': {u'type': u'float', u'values': [1, 2.016078455307904, 3]}}, 'name': '_property_lock', 'type': 'change'}

{'owner': , 'new': {u'hovered_point': None}, 'old': {}, 'name': '_property_lock', 'type': 'change'}

{'owner': , 'new': None, 'old': 1, 'name': 'hovered_point', 'type': 'change'}

{'owner': , 'new': {}, 'old': {u'hovered_point': None}, 'name': '_property_lock', 'type': 'change'}

我承认这个结构分解起来有点棘手,但是仔细浏览之后,我们注意到粗体行的'name'等于'_property_lock',然后'new'子结构包含字段u'x'和{},这是“x”和“y”的Unicode。在

你甚至可以在里面画一些新的东西,甚至可以用CDM来保存一些新的东西。在

这也不是mpld3,但是这里有一个在jupyter notebook中使用bqplot的快速示例,它的灵感来自于Sergey在Is it actually possible to pass data (callback) from mpld3 to ipython?的评论/问题,以及Sergey和Drew的答案。在

首先,在Python环境中安装bqplot,然后打开一个笔记本

(... do whatever to make anaconda work for you....)

conda install bqplot

jupyter notebook

然后将可调的交互式散射图代码粘贴到第一个块中:

^{pr2}$

然后,在绘图出现后,单击并拖动一两个数据点,然后在下一个块中查看绘图中的更改:

print([x_data-scatter_plot.x,y_data-scatter_plot.y])

我原以为https://github.com/bloomberg/bqplot/blob/master/examples/Introduction.ipynb中的回调函数是必需的,但只有当您想触发修改的代码时才需要它。在

为此,请尝试以下方法:

def foo(change):
    print('This is a trait change. Foo was called by the fact that we moved the Scatter')
    #print('In fact, the Scatter plot sent us all the new data: ')
    #print('To access the data, try modifying the function and printing the data variable')
    global pdata 
    pdata = [scatter_plot.x,scatter_plot.y]
    #print (pdata)

# Hook up our function `foo` to the coordinates attributes (or Traits) of the scatter plot
scatter_plot.observe(foo, ['y','x'])

然后对x,y坐标的更改触发foo,并更改全局变量{}。您将看到foo()的打印输出附加到第一个块的输出,更新后的pdata将可用于未来的代码块。在

您可以使用新的bqplotScatter和{}来实现这一点,它们都有一个enable_move参数,当您设置为True时,它们允许拖动点。此外,当您drag时,您可以observeScatterLabelx或{}值进行更改,并通过该更改触发一个python函数,从而生成一个新的绘图。在

明白了吗?在

相关问题 更多 >

    热门问题