2016-06-15 3 views
5

Существует множество потрясающих возможностей для создания анимированных изображений с использованием mpld3. Однако, похоже, что все «движущиеся части» - это ответственность JavaScript. Более того, есть много запросов в Интернете и переполнение стека, где люди прямо просят эту возможность.Возможно ли передавать данные (обратные вызовы) из mpld3 в ipython?

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 с большим количеством примеров и даже возможностей ИСТИННОГО взаимодействия клиент-сервер. По сути, мы можем начать с основных слайдеров и кнопок, но потом мы видим, что на этой основе построены более сложные пакеты: в основном bqplot и некоторые другие унаследованные пакеты.

Что я хочу - это просто перетащить несколько точек на изображение, а затем передать их на iPython, чтобы сделать некоторые дополнительные сюжеты - это очень сложно и определенно нельзя переместить на JavaScript. Но похоже, что несмотря на то, что команда bqplot проделала огромную работу, вы можете использовать только некоторые «предопределенные» группы взаимодействий, поэтому поведение перетаскивания снова не включается.

Когда я попытался (не очень глубоко) ввести исходный код mpld3 и изменить его и, возможно, объединить с ipywidgets, я столкнулся с тем, что многие вещи устарели, код развивается очень быстро, что не соответствует существующим примеры в Интернете: большинство тополей очень старые, и запросы тоже очень старые. Поэтому я не мог ничего сделать из-за беспорядка, многие примеры терпят неудачу из-за отсутствия обратной совместимости.

Резюме. Я был бы рад, если бы кто-нибудь предоставил какой-то способ перетаскивания точек и передать их координаты на python, но который мог бы мне помочь, - это возможность передавать информацию из mpld3 более абстрактным образом, так что другие случаи могут быть включены.

+0

UPD: Кстати, через некоторое время после публикации исходного вопроса я нашел довольно корректное решение для переполнения стека: [Интерактивные сюжеты в ноутбуке jupyter с перетаскиваемыми точками] (http://stackoverflow.com/questions/30207912/interactive-plot-in-jupyter-ipython-notebook-with-draggable-points-that-call? rq = 1), он работал для меня, но с некоторыми ошибками отображения, которые я не мог исправить. Ответ почему-то не принят. Во всяком случае, вся процедура довольно сложная. –

ответ

3

Прошло почти год с тех пор, как был задан вопрос. Ну, ответ не о mpld3, но я не придерживаюсь этой конкретной технологии. Пользователь @Drew предложил использовать bqplot, поэтому я разместить ссылку на соответствующий ноутбук

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

из bloomberg. Если вы откроете это, я рекомендую найти ссылку в правом верхнем углу, которая перенаправляет вас на внешний nbviewer с изображениями. Почти все там содержится, я просто пытаюсь воспроизвести минималистический рабочий пример.

Обратите внимание, что для того, чтобы запустить jupyter notebook с расширением bqplot, а также некоторые ipywidgets, вам может понадобиться, чтобы сделать какой-то «магии», чтобы заставить его работать. Вы должны быть знакомы с некоторыми командами bash, такими как 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() 

вы получите хороший сюжет так: Random plot from bqplot

с дополнительной возможностью перетаскивать точки. Как только вы перетащите точку, вы увидите распечатанный список изменений, который представляет собой структуру python, каждое событие на отдельной строке.

enter image description here

{ 'владелец': 'новый': тип _property_lock ' ''{u'hovered_point': 1}, 'старый':: traitlets.Undefined, 'имя'': 'изменение'}

{ 'владелец': 'нового': 1, 'старого': Нет, 'имя': 'hovered_point', 'типа': 'изменение'}

{ 'владелец' :, '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 '}

Я признаю, что структура немного сложна для разложения, но после некоторого тщательного взгляда отметим, что жирная линия имеет 'name', равную '_property_lock', то подструктура 'new' содержит поля u'x' и u'y', что является Unicode для «x» и «y».

Затем вы можете отслеживать эти изменения и, соответственно, запустить некоторые python код внутри функции my_callback(...), вы можете даже нарисовать что-то внутри этого участка, или создать новый, и т.д. Удивительно, но это как-то работает, и с новым jupyter вы можете даже сохранить ноутбук с виджетами, который полностью раздувает.

+0

Это замечательно - вы видели код, который выполняет извлечение измененных данных? –

+0

Я перешел на другой домен, поэтому я больше не работаю с этим объектом. Так что вообще, нет, к сожалению нет, таких примеров я не видел. Теперь вы можете создать свой собственный :) –

+0

Я поиграл с ним в bqplot в ноутбуке jupyter. Вы можете получить функцию обратного вызова для изменения глобальных или нелокальных переменных и использовать измененные данные в другом месте. Вы можете 'scatt.observe (foo, ['x', 'y']) и получить данные, затем в обратном вызове используйте' global pdata' и 'pdata = [scatter_plot.x, scatter_plot.y]' для обновления глобальная переменная. –

2

Вы можете сделать это с новым bqplotScatter и Label оба они имеют enable_move параметр, который при установке на True они позволяют точки тащиться. Кроме того, когда вы drag вы можете observe изменить значение x или y значения Scatter или Label и вызвать функцию python через это, что, в свою очередь, создает новый график.

- это ясно?

+0

Это хорошая новость. Позвольте мне проверить это, мне нужно некоторое время, чтобы сделать это, потому что это очень старая проблема для меня, я перешел к другим вещам. Я считаю, что это важно для многих людей, поэтому я прокомментирую это, как только я его проверю. Приветствия. –

+0

Кстати, спустя некоторое время после публикации исходного вопроса, я нашел довольно правильное решение для переполнения стека: [Интерактивные сюжеты в ноутбуке jupyter с перетаскиваемыми точками] (http://stackoverflow.com/questions/30207912/interactive-plots -in-jupyter-ipython-notebook-with-draggable-points-that-call? rq = 1), он работал для меня, но с некоторыми ошибками отображения, которые я не мог исправить. Ответ почему-то не принят. Во всяком случае, вся процедура довольно сложная. –

+1

Звучит неплохо. Виджеты bqplot созданы для создания бесшовной связи между JavaScript и python, так что каждый компонент графика является виджетами. Позволяет создавать довольно сложные графические интерфейсы. – Drew

0

Это также не mpld3, но вот быстрый пример использования bqplot в jupyter notebook, вдохновленный Сергей комментарию/вопрос на Is it actually possible to pass data (callback) from mpld3 to ipython? и Сергей и ответы Дрю.

Во-первых, установить 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 

Затем, после того, как появляется сюжет, нажмите и перетащите точку данных или два вокруг, а в следующем блоке просмотрите изменения в пределах графика:

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

Я подумал, что необходимо использовать обратный вызов в https://github.com/bloomberg/bqplot/blob/master/examples/Introduction.ipynb, но вам нужно только это, если вы хотите вызвать какой-то код на модификациях.

Для этого, попробовать что-то вроде:

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. Вы увидите вывод foo(), прикрепленный к выходу первого блока, и обновленные pdata будут доступны для будущих блоков кода.

Смежные вопросы