使用mpld3
制作动画图片有很多惊人的可能性。然而,似乎所有的"移动部件"是JavaScript的责任。此外,互联网和Stack Overflow上有很多请求,人们直接要求这种可能性。
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表单并按下按钮将数据发送到" server-python"来自" client-javascript"。还有另一个有趣的笔记本
http://nbviewer.jupyter.org/gist/aflaxman/11156203
很多人都提到了作为灵感来源 - 它将输出配置保存为.html文件。也许这个硬盘交换可以用来通过python进一步处理这些信息。
进一步发展,我发现了IPYwidgets
,其中包含大量示例甚至是TRUE交互客户端 - 服务器的可能性。从本质上讲,我们可以从基本的滑块和按钮开始,但后来我们看到在此基础上构建了一些更复杂的包:主要是bqplot
,以及其他一些继承的包。
我想要的 - 只是拖放图片上的一些点,然后将它们传递给iPython以制作更多的图表 - 它非常复杂,绝对无法移动到JavaScript。但似乎尽管bqplot
的团队做了大量的工作,但你只能使用一些"预定义的"交互集,因此再次不包括拖放行为。
当我尝试(不是非常深入)输入mpld3的源代码并修改它并可能与ipywidgets合并时,我遇到很多东西都被弃用了,代码发展得非常快,这并不符合互联网上现有的例子:大多数杨树都很老,查询也很老。所以由于混乱,我无法做任何事情,许多例子由于缺乏向后兼容性而失败。
摘要。如果有人提供某种方法来拖放点并将其坐标传递给python,我会很高兴,但这对我来说更有帮助 - 是从mpld3采用更抽象的方式",以便可以包含其他案例。
答案 0 :(得分:4)
问题问题已经过去差不多一年了。好吧,答案不是mpld3
,但我并不坚持这种特殊的技术。用户@Drew建议使用bqplot
,因此我发布了相关笔记本的链接
https://github.com/bloomberg/bqplot/blob/master/examples/Interactions/Interaction%20Layer.ipynb
来自bloomberg
。如果您打开它,我建议您找到右上角的链接,该链接会将您重定向到带有图片的外部nbviewer。几乎所有内容都包含在那里,我只是尝试重现一个简约的工作示例。
请注意,为了推出扩展名为jupyter notebook
的{{1}},以及某些bqplot
,您可能需要执行某种" magic"使它工作。您需要熟悉一些bash命令,例如ipywidgets
和jupyter install nbextension
。我个人不得不与jupyter 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()
结构,每个事件都在一个单独的行上。
{'所有者':,'新':{u' hovered_point':1},' old&#39 ;: traitlets.Undefined,& #39;姓名':' _property_lock','输入':'更改'}
{'所有者':,'新':1,'旧':无,'名称':' hovered_point& #39;,'键入':'更改'}
{'所有者':,'新':{},' old':{u' hovered_point':1},&# 39;姓名':' _property_lock','输入':'更改'}
{'所有者':,'新':{u' y':{u' type':u'浮动',你':[4,4.863453784620906,6]},你':{u'输入':你'浮动' ,u'值':[1,2.016078455307904,3]}},' old':{},' name':' _property_lock', '键入':'更改'}
{'所有者':,'新':数组([4.,4.86345378,6。]),' old':数组([4, 5,6],'名称':' y','键入':'更改'}
{'所有者':,'新':数组([1.,2.01607846,3。]),' old':数组([1, 2,3],'姓名':' x','输入':'更改'}
{'所有者':,'新':{},' old':{u' y':{u'键入':你'浮动','价值':[4,4.863453784620906,6]},u' x':{u' type' :u' float',u'值':[1,20016078455307904,3]}},' name':' _property_lock',&#39 ;键入':'更改'}
{'所有者':,'新':{u' hovered_point':无},' old':{},&# 39;姓名':' _property_lock','输入':'更改'}
{'所有者':,'新':无,'旧':1,'名称':' hovered_point& #39;,'键入':'更改'}
{'所有者':,' new':{},' old':{u' hovered_point':无},&# 39;姓名':' _property_lock','输入':'更改'}
我承认结构分解有点棘手,但经过一些仔细的扫视后,我们注意到粗线的python
等于'name'
,然后'_property_lock'
子结构包含字段'new'
和u'x'
,这是" x"的Unicode和" y"。
然后你可以跟踪这些变化并相应地在函数u'y'
中运行一些python
代码,你甚至可以在这个图中绘制一些东西,或者创建一个新的等等。令人惊讶的是,这在某种程度上有效,使用新的jupyter,您甚至可以使用小部件保存笔记本,这是完全令人费解的。
答案 1 :(得分:2)
您可以使用新的bqplot
Scatter
和Label
执行此操作,这两个参数都有enable_move
参数,当您设置为True
时,它们允许点被拖。此外,当您drag
时,observe
或x
y
或Scatter
的{{1}}或Label
值会发生变化ColorPicker
并触发python函数通过它,反过来又产生了一个新的情节。
那是清楚的吗?
答案 2 :(得分:1)
这也不是import * as ko from 'knockout';
import 'isomorphic-fetch';
interface Item {
name: KnockoutObservable<string>;
itemNumber: KnockoutObservable<string>;
amount: KnockoutObservable<number>;
unitPrice: KnockoutObservable<number>;
}
interface Invoice {
dateFormatted: KnockoutObservable<string>;
invoiceNumber: KnockoutObservable<string>;
items: KnockoutObservableArray<Item>;
}
class InvoiceViewModel {
public invoice: KnockoutObservable<Invoice> = ko.observable<Invoice>();
public test: KnockoutObservable<string> = ko.observable<string>("test");
constructor() {
fetch('api/SampleData/GetInvoice')
.then(response => response.json() as Promise<Invoice>)
.then(data => {
this.invoice(data);
});
}
public changeDateFormatted = () => {
this.test('123');
this.invoice().dateFormatted('123');
}
}
export default { viewModel: InvoiceViewModel, template:
require('./invoice.html') };
,但这里有一个在mpld3
中使用bqplot
的简单示例,受到谢尔盖在Is it actually possible to pass data (callback) from mpld3 to ipython?的评论/问题以及谢尔盖和德鲁的启发答案。
首先,在anaconda环境中安装jupyter notebook
并打开笔记本
bqplot
然后将这个可调整的交互式散点图代码粘贴到第一个块中:
(... 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
我原以为https://github.com/bloomberg/bqplot/blob/master/examples/Introduction.ipynb中的回调内容是必需的,但如果你想在修改上触发一些代码,你只需要这样做。
为此,尝试类似:
print([x_data-scatter_plot.x,y_data-scatter_plot.y])
然后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
的打印输出附加到第一个块的输出,更新的pdata将可用于未来的代码块。