5

There is the amazing mpld3 for interactive matplotlib-plots in IPython Notebooks. mpld3 also features plugins. One is especially interesting for me: You can pick a point in the plot and drag it around - it is presented here:

http://mpld3.github.io/examples/drag_points.html.

The source code in the link generates the plot below. I would like to have the information back from the plugin where I have dragged my points to. But I really get lost in the javascript part and how I could get information back from it.

Here I have dragged some points to new positions. I would like to get the information where to I have dragged them.

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Anna Christine
  • 860
  • 1
  • 6
  • 14

1 Answers1

3

I have wondered about this and wanted to do something similar. This is what I have found. First, I wanted to know the mouse coordinates are. To be able to read the coordinates, I inserted the following "alert" statement, similar to "print", in drag_points.py:

    var startx = 0;
    var starty = 0;
    function dragstarted(d) {
      d3.event.sourceEvent.stopPropagation();
      d3.select(this).classed("dragging", true);
      startx = obj.ax.x(d[0]);
      starty = obj.ax.y(d[1]);
    }
    var endx = 0;
    var endy = 0;
    function dragended(d) {
      d3.select(this).classed("dragging", false);
      endx = obj.ax.x(d[0]);
      endy = obj.ax.y(d[1]);
      alert(endx-startx);
      d3.select("input")
          .attr("value",endx-startx)
    }

Upon mouse click and release, it opens an alert diag with the x-distance traveled. This allows accessing the coordinate information.

Next, I tested if I can encode this coordinate information into the underlying html dynamically, thus allowing further backend processing. I learned that d3.js allows you to modify the content of an html tag. I therefore modified the "jinja templates" in _display.py (found in the same directory as "plugins.py". Specifically, I entered the following into the template:

<table width=300 height=200 border=5>
<tr>
  <form method="POST" action="/plot" class="">
  <input type="submit" name="submit" value="PLOT">
  </form>
</tr>
</table>

and modified the "drag_points.py" so that instead of opening an alert box, it modified the value of the "input" value from "post" to endx-startx. That is,

      d3.select("input")
          .attr("value",endx-startx)

The end result was, when a ball is dragged and released, the alert box displays the x-displacement and this value is used to update the value of the "input" button. If some other tag besides the input button is used to set the value, it should be possible to utilize the information downstream.

sjp14051
  • 99
  • 9
  • could you please explain how to move read the value generated from the alert back to the python input? I think this is what you were explaining in the last bit of provided code, but I'm missing something... – Docuemada Oct 23 '14 at 16:01
  • 1
    I'm sorry if this wasn't clear. To recap what I did: 1. display the mpld3 plot in an html containing some tag (e.g. an tag in the above example, which by the way may be made hidden using font-style="display:none"); 2. move the dots inside the figure; 3. inside the javascript, the coordinates are read and then used to update the tag value using d3.js; and 4. finally, when you press the "submit" button, the information is sent back to the server where the coordinate information is decoded using python script. I hope this helps. – sjp14051 Oct 23 '14 at 17:41