7

使用mpld3. 但是,似乎所有“移动部件”都是 JavaScript 的责任。此外,互联网和 Stack Overflow 上有很多请求,人们直接要求这种可能性。

从python中的动态mpld3图中检索数据

拖拽后获取点信息

如何“转储”使用 mpld3 的 LinkedBrush 插件选择的点?

mpld3 ~ 选择点并获取它们的坐标?

其中有参考,但所有答案都是错误的,因为他们建议使用某种警报或标题。然而,第二个链接最有趣,因为它建议添加一些 HTML 表单并按下按钮以将数据从“client-javascript”发送到“server-python”。还有一个有趣的笔记本

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

许多人提到它作为灵感来源 - 它将输出配置保存在 .html 文件中。也许这个硬盘交换可以被python用来进一步处理这些信息。

更进一步,我发现IPYwidgets了 TRUE 交互客户端-服务器的大量示例甚至可能性。本质上,我们可能从基本的滑块和按钮开始,但随后我们看到一些更复杂的包是在此基础上构建的:mainlybqplot和其他一些继承的包。

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

当我尝试(不是很深入)输入mpld3的源代码并对其进行修改并可能与ipywidgets合并时,我遇到了很多东西被弃用,代码发展非常快,这与互联网上现有的示例不符: 杨树大多很老,询盘也很老。所以我因为一团糟而无能为力,许多示例由于缺乏向后兼容性而失败。

概括。如果有人提供一些拖放点并将其坐标传递给 python 的方法,我会很高兴,但这对我更有帮助 - 是以更“抽象的方式”从 mpld3 传递信息的能力,以便其他可以包括案例。

4

3 回答 3

4

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

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

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

请注意,为了启动jupyter notebookwith extensionbqplot以及 some ipywidgets,您可能需要做一些“魔术”来使其工作。您需要熟悉一些 bash 命令,例如jupyter install nbextensionjupyter nbextension enable。我个人不得不挣扎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()

你得到一个像这样的好情节: 来自 bqplot 的随机图

具有拖动点的附加功能。拖动一个点后,您会观察到一个打印的更改列表,这是一个python结构,每个事件都在单独的行上。

在此处输入图像描述

{'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': '改变'}

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

{'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'u'y',这是“x”和“y”的Unicode。

然后您可以跟踪这些更改并相应地python在函数中运行一些代码my_callback(...),您甚至可以在该图中绘制一些东西,或创建一个新的,等等。令人惊讶的是,这以某种方式起作用,并且使用新的 jupyter,您甚至可以使用小部件保存笔记本这是完全令人兴奋的。

于 2017-05-11T14:06:37.673 回答
2

您可以使用 new 执行此操作,bqplot Scatter并且Label它们都有一个enable_move参数,当您设置为它们时,True它们允许拖动点。此外,当您drag可以observe更改xory的值ScatterLabel通过它触发 python 函数时,这又会生成一个新图。

明白了吗?

于 2016-08-08T15:33:02.583 回答
1

这也不是,但这是一个使用in ampld3的快速示例,灵感来自 Sergey 在Is it actually possible to pass data (callback) from mpld3 to ipython? 的评论/问题?以及 Sergey 和 Drew 的回答。bqplotjupyter notebook

一、bqplot在anaconda环境下安装,打开一个notebook

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

conda install bqplot

jupyter notebook

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

import numpy as np
from __future__ import print_function # So that this notebook becomes both Python 2 and Python 3 compatible
from bqplot import pyplot as plt

# And creating some random data
size = 10
np.random.seed(0)
x_data = np.arange(size)
y_data = np.cumsum(np.random.randn(size)  * 100.0)


# Creating a new Figure and setting it's title
plt.figure(title='An adjustable, extractable scatter plot')
# Let's assign the scatter plot to a variable
scatter_plot = plt.scatter(x_data, y_data)
plt.show()
scatter_plot.enable_move = True  # make the points movable

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

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并改变全局变量pdata。您将看到foo()附加到第一个块的输出的打印输出,并且更新的 pdata 将可用于未来的代码块。

于 2018-01-28T16:52:42.923 回答