Search Results

Search found 1 results on 1 pages for 'sjp14051'.

Page 1/1 | 1 

  • Creating a new plugin for mpld3

    - by sjp14051
    Toward learning how to create a new mpld3 plugin, I took an existing example, LinkedDataPlugin (http://mpld3.github.io/examples/heart_path.html), and modified it slightly by deleting references to lines object. That is, I created the following: class DragPlugin(plugins.PluginBase): JAVASCRIPT = r""" mpld3.register_plugin("drag", DragPlugin); DragPlugin.prototype = Object.create(mpld3.Plugin.prototype); DragPlugin.prototype.constructor = DragPlugin; DragPlugin.prototype.requiredProps = ["idpts", "idpatch"]; DragPlugin.prototype.defaultProps = {} function DragPlugin(fig, props){ mpld3.Plugin.call(this, fig, props); }; DragPlugin.prototype.draw = function(){ var patchobj = mpld3.get_element(this.props.idpatch, this.fig); var ptsobj = mpld3.get_element(this.props.idpts, this.fig); var drag = d3.behavior.drag() .origin(function(d) { return {x:ptsobj.ax.x(d[0]), y:ptsobj.ax.y(d[1])}; }) .on("dragstart", dragstarted) .on("drag", dragged) .on("dragend", dragended); patchobj.path.attr("d", patchobj.datafunc(ptsobj.offsets, patchobj.pathcodes)); patchobj.data = ptsobj.offsets; ptsobj.elements() .data(ptsobj.offsets) .style("cursor", "default") .call(drag); function dragstarted(d) { d3.event.sourceEvent.stopPropagation(); d3.select(this).classed("dragging", true); } function dragged(d, i) { d[0] = ptsobj.ax.x.invert(d3.event.x); d[1] = ptsobj.ax.y.invert(d3.event.y); d3.select(this) .attr("transform", "translate(" + [d3.event.x,d3.event.y] + ")"); patchobj.path.attr("d", patchobj.datafunc(ptsobj.offsets, patchobj.pathcodes)); } function dragended(d, i) { d3.select(this).classed("dragging", false); } } mpld3.register_plugin("drag", DragPlugin); """ def __init__(self, points, patch): print "Points ID : ", utils.get_id(points) self.dict_ = {"type": "drag", "idpts": utils.get_id(points), "idpatch": utils.get_id(patch)} However, when I try to link the plugin to a figure, as in plugins.connect(fig, DragPlugin(points[0], patch)) I get an error, 'module' is not callable, pointing to this line. What does this mean and why doesn't it work? Thanks. I'm adding additional code to show that linking more than one Plugin might be problematic. But this may be entirely due to some silly mistake on my part, or there is a way around it. The following code based on LinkedViewPlugin generates three panels, in which the top and the bottom panel are supposed to be identical. Mouseover in the middle panel was expected to control the display in the top and bottom panels, but updates occur in the bottom panel only. It would be nice to be able to figure out how to reflect the changes in multiple panels. Thanks. import matplotlib import matplotlib.pyplot as plt import numpy as np import mpld3 from mpld3 import plugins, utils class LinkedView(plugins.PluginBase): """A simple plugin showing how multiple axes can be linked""" JAVASCRIPT = """ mpld3.register_plugin("linkedview", LinkedViewPlugin); LinkedViewPlugin.prototype = Object.create(mpld3.Plugin.prototype); LinkedViewPlugin.prototype.constructor = LinkedViewPlugin; LinkedViewPlugin.prototype.requiredProps = ["idpts", "idline", "data"]; LinkedViewPlugin.prototype.defaultProps = {} function LinkedViewPlugin(fig, props){ mpld3.Plugin.call(this, fig, props); }; LinkedViewPlugin.prototype.draw = function(){ var pts = mpld3.get_element(this.props.idpts); var line = mpld3.get_element(this.props.idline); var data = this.props.data; function mouseover(d, i){ line.data = data[i]; line.elements().transition() .attr("d", line.datafunc(line.data)) .style("stroke", this.style.fill); } pts.elements().on("mouseover", mouseover); }; """ def __init__(self, points, line, linedata): if isinstance(points, matplotlib.lines.Line2D): suffix = "pts" else: suffix = None self.dict_ = {"type": "linkedview", "idpts": utils.get_id(points, suffix), "idline": utils.get_id(line), "data": linedata} class LinkedView2(plugins.PluginBase): """A simple plugin showing how multiple axes can be linked""" JAVASCRIPT = """ mpld3.register_plugin("linkedview", LinkedViewPlugin2); LinkedViewPlugin2.prototype = Object.create(mpld3.Plugin.prototype); LinkedViewPlugin2.prototype.constructor = LinkedViewPlugin2; LinkedViewPlugin2.prototype.requiredProps = ["idpts", "idline", "data"]; LinkedViewPlugin2.prototype.defaultProps = {} function LinkedViewPlugin2(fig, props){ mpld3.Plugin.call(this, fig, props); }; LinkedViewPlugin2.prototype.draw = function(){ var pts = mpld3.get_element(this.props.idpts); var line = mpld3.get_element(this.props.idline); var data = this.props.data; function mouseover(d, i){ line.data = data[i]; line.elements().transition() .attr("d", line.datafunc(line.data)) .style("stroke", this.style.fill); } pts.elements().on("mouseover", mouseover); }; """ def __init__(self, points, line, linedata): if isinstance(points, matplotlib.lines.Line2D): suffix = "pts" else: suffix = None self.dict_ = {"type": "linkedview", "idpts": utils.get_id(points, suffix), "idline": utils.get_id(line), "data": linedata} fig, ax = plt.subplots(3) # scatter periods and amplitudes np.random.seed(0) P = 0.2 + np.random.random(size=20) A = np.random.random(size=20) x = np.linspace(0, 10, 100) data = np.array([[x, Ai * np.sin(x / Pi)] for (Ai, Pi) in zip(A, P)]) points = ax[1].scatter(P, A, c=P + A, s=200, alpha=0.5) ax[1].set_xlabel('Period') ax[1].set_ylabel('Amplitude') # create the line object lines = ax[0].plot(x, 0 * x, '-w', lw=3, alpha=0.5) ax[0].set_ylim(-1, 1) ax[0].set_title("Hover over points to see lines") linedata = data.transpose(0, 2, 1).tolist() plugins.connect(fig, LinkedView(points, lines[0], linedata)) # second set of lines exactly the same but in a different panel lines2 = ax[2].plot(x, 0 * x, '-w', lw=3, alpha=0.5) ax[2].set_ylim(-1, 1) ax[2].set_title("Hover over points to see lines #2") plugins.connect(fig, LinkedView2(points, lines2[0], linedata)) mpld3.show()

    Read the article

1