为此,您需要知道:如何从Jupyter的Javascript与IPython内核交互
前端。现在是通过Jupyter.Kernel.execute(current
source code)。在
足够舒适。(如屏幕到绘图坐标转换。)
D3ViaPython库供您选择。mpld3用于此示例。在
Ipywidgets,正如您所说(据我所知),ipywidget是一种在使用IPython内核时将HTML input元素链接到Jupyter笔记本绘图的一种方法,因此并不完全是您想要的。但比我的提议简单一千倍。ipywidgets github repo的README链接到示例套件中的correct IPython notebook to start with。在
关于Jupyter笔记本电脑与IPython内核直接交互的最佳博客文章来自2013年的Jake Vanderplas。它是针对IPython<;=2.0的,几个月前(2015年8月)的评论者发布了IPython 2和{a12}的更新,但代码不能用于我的Jupyter 4笔记本。
问题似乎是javascript API for the Jupyter kernel在不断变化。在
我在一个要点中更新了mpld3 dragging example和Jake Vanderplas的例子(链接在这个回复的顶部),以尽可能简短地给出一个例子,因为这个例子已经很长了,但是下面的片段试图更简洁地传达这个想法。在
Python
Python回调可以有任意多个参数,甚至可以是原始代码。内核将通过一个eval语句运行它,并返回最后一个返回值。无论输出是什么类型,都将作为字符串(text/plain)传递给javascript回调。在def python_callback(arg):
"""The entire expression is evaluated like eval(string)."""
return arg + 42
Javascript
Javascript回调应该有一个参数,即Javascript
Object遵循结构documented here。在
^{pr2}$
{juyther>使用ipyther函数调用。将内容发送到
内核是documented here。在var kernel = Jupyter.notebook.kernel;
var callbacks = {shell: {reply: javascriptCallback }};
kernel.execute(
"print('only the success/fail status of this code is reported')",
callbacks,
{user_expressions:
{out1: "python_callback(" + 10 + ")"} // function call as a string
}
);
mpld3插件中的Javscript
修改mpld3库的插件以向
要更新的HTML元素,以便我们可以在中再次找到它们
未来。在import matplotlib as mpl
import mpld3
class DragPlugin(mpld3.plugins.PluginBase):
JAVASCRIPT = r"""
// Beginning content unchanged, and removed for brevity.
DragPlugin.prototype.draw = function(){
var obj = mpld3.get_element(this.props.id);
var drag = d3.behavior.drag()
.origin(function(d) { return {x:obj.ax.x(d[0]),
y:obj.ax.y(d[1])}; })
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended);
// Additional content unchanged, and removed for brevity
obj.elements()
.data(obj.offsets)
.style("cursor", "default")
.attr("name", "redrawable") // DIFFERENT
.call(drag);
// Also modify the 'dragstarted' function to store
// the starting position, and the 'dragended' function
// to initiate the exchange with the IPython kernel
// that will update the plot.
};
"""
def __init__(self, points):
if isinstance(points, mpl.lines.Line2D):
suffix = "pts"
else:
suffix = None
self.dict_ = {"type": "drag",
"id": mpld3.utils.get_id(points, suffix)}