Is it possible to transfer data (callback) from mpld3 to ipython?

There are many amazing possibilities for creating animated images using mpld3 . However, it seems that all the “moving parts” are the responsibility of JavaScript. In addition, there are many requests on the Internet and a stack overflow where people directly ask for this opportunity.

Extract data from mpld3 dynamic portion in python

Get information about points after dragging

How to "dump" points selected using the LinkedBrush plugin for mpld3?

mpld3 ~ Select points and get their coordinates?

with links to them, but all the answers are WRONG, as they suggest using some kind of warnings or signatures. The second link, however, is most interesting, since it is proposed to add some HTML form and click a button to send data to "server-python" from "client-javascript". Another interesting laptop

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

which is mentioned by many people as a source of inspiration - it saves the output configuration of the .html file. Perhaps this hard drive exchange can be used to further process this information with python.

Moving on, I discovered IPYwidgets , with many examples and even interoperability options with TRUE client-server. Essentially, we can start with the main sliders and buttons, but then we see that some more complex packages are built on this basis: mainly bqplot and some other inherited packages.

What I want is to simply drag and drop some points on the image and then transfer them to iPython to make some additional graphics - it is very difficult and definitely cannot be moved to JavaScript. But it seems that even though the bqplot team bqplot done a great job, you can only use some of the “predefined” interaction groups, so the drag and drop behavior does not turn on again.

When I tried (not very deeply) to introduce the mpld3 source code and modify it and possibly combine it with ipywidgets, I found that many things are outdated, the code develops very quickly, which does not correspond to existing examples on the Internet: most poplars are very old, and requests are also very old. Thus, I could not do anything because of the mess, many examples fail due to the lack of backward compatibility.

Summary. I would be glad if someone provided some way to drag the points and pass their coordinates to python, but which could help me, is the ability to transfer information from mpld3 in a more abstract way, so other cases might be included.

+6
source share
3 answers

Almost a year has passed since the question was asked. Well, the answer is not about mpld3 , but I do not stick to this particular technology. User @Drew suggested using bqplot , so I post a link to a connected laptop

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

from bloomberg . If you open this, I recommend finding a link in the upper right corner that redirects you to an external nbviewer with images. Almost everything is contained there, I'm just trying to reproduce a minimalistic working example.

Please note that to run jupyter notebook with the bqplot extension, as well as for some ipywidgets you may need to do something like “magic” to make it work. You should be familiar with some bash commands like jupyter install nbextension and jupyter nbextension enable . I personally had to fight bqplot for several hours to get it working. But this is certainly a separate issue.

Make a trial attempt to run the observe function. The test function my_callback(...) simply prints events.

 %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() 

you will get a good plot like this: Random story from bqplot

with the additional ability to drag points. After you drag the point, you will see a printed change list, which is a python structure, each event on a separate line.

enter image description here

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

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

{'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 '}

I admit that the structure is a little complicated to decompose, but after some careful searching, note that the bold line has a 'name' equal to '_property_lock' , then the substructure 'new' contains the fields u'x' and u'y' , which is Unicode for "x" and "y".

Then you can track these changes and, accordingly, run some python code inside the my_callback(...) function, you can even draw something inside this plot or create a new one, etc. Surprisingly, this somehow works, and with the new jupyter you can even save your laptop with widgets that are completely blurry.

+4
source

You can do this with the new bqplot Scatter and Label , both of which have an enable_move parameter, which, when set to True , allows you to drag points. In addition, when you drag , you can observe changing the value of x or y Scatter or Label and run through it the python function, which in turn generates a new graph.

- it is clear?

+2
source

This is also not mpld3 , but here is a brief example of using bqplot in a jupyter notebook , inspired by Sergey's comment on the question Is this possible (callback) from mpld3 to ipython? and the answers of Sergey and Drew.

First install bqplot in anaconda environment and open laptop

 (... do whatever to make anaconda work for you....) conda install bqplot jupyter notebook 

Then paste this custom interactive scatterplot code into the first block:

 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 title plt.figure(title='An adjustable, extractable scatter plot') # Let 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 

Then, after the graph appears, click and drag the data point or two around, and in the next block look at the changes inside the graph:

 print([x_data-scatter_plot.x,y_data-scatter_plot.y]) 

I thought that you need to use the callback function in https://github.com/bloomberg/bqplot/blob/master/examples/Introduction.ipynb , but you only need this if you want to call some code on the modifications.

To do this, try something like:

 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']) 

Then changes in the x,y coordinates start foo and change the global variable pdata . You will see foo() printed result added to the first output block, and updated pdata will be available for future code blocks.

+1
source

All Articles