2017-06-13 77 views
7

Za pomocą poniższego kodu mogę uzyskać wykres 2x2 z 4 działkami. Za pomocą pędzli mogę wybrać punkty danych. Mam pytanie, w jaki sposób uzyskać wybrane punkty danych jako tablicę JSON lub cvs. Ten kod używa mlpd3, ale bokeh może robić podobne wybory za pomocą pędzli. Ale nie ma przykładu wyboru punktów danych. Próbuję uzyskać wybrane dane jako obiekt, aby kontynuować przetwarzanie za pomocą Pythona. Byłoby miło zobaczyć dane w komórce.Python: Jak uzyskać dane z połączonych pędzli w mlpd3, Bokeh, Plotly?

%matplotlib inline 
import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib as mat 
import mpld3 

mpld3.enable_notebook() 


from mpld3 import plugins 

fig, ax = plt.subplots(2, 2, figsize=(10, 8)) 
fig.subplots_adjust(hspace=0.1, wspace=0.1) 
ax = ax[::-1] 

X = np.random.normal(size=(2, 100)) 
for i in range(2): 
    for j in range(2): 
     ax[i, j].xaxis.set_major_formatter(plt.NullFormatter()) 
     ax[i, j].yaxis.set_major_formatter(plt.NullFormatter()) 
     points = ax[i, j].scatter(X[j], X[i]) 

plugins.connect(fig, plugins.LinkedBrush(points)) 

Bokeh ma podobne zachowanie w CustomJS podczas wyboru

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction/callbacks.html#userguide-interaction-jscallbacks-customjs-interactions

Którykolwiek z nich jest łatwiej wyodrębnić wybrany element - będzie działać .. Jeśli istnieje rozwiązanie Plotly, które również działają .

+2

Nie ma sposobu, aby to zrobić w mpld3: wyjście mpld3 jest statyczną wizualizacją javascript, która nie wymaga (ani nie zna) zaplecza Pythona. Z tego powodu ten rodzaj komunikacji między frontendem a backendem wymagałby prawie całkowitego przerobienia biblioteki. Proponuję użyć Bokeh. – jakevdp

+0

@jakevdp dzięki! Zmiana pytania. – Merlin

Odpowiedz

1

Jest poza ipython ale można uruchomić flask lub django w połączeniu z d3.js i jquery aby uzyskać dane z powrotem do pytona.

+0

FWIW - Jest to ogólne podejście, które podejmuje Dash, używając 'flask' ​​jako serwera Pythona,' Plotly.js' jako biblioteki graficznej front-end oraz 'fetch' jako biblioteki żądań HTTP. –

3

Możesz pobrać wybrane dane z wykresu Plotly za pomocą nowego Plotly's Dash framework.

Jest przykładem w docs tutaj pod „Graph Crossfiltering” https://plot.ly/dash/getting-started-part-2

mam wklejony pełny przykład poniżej tylko dla zachowania historii.

W każdym z poniższych połączeń zwrotnych masz dostęp do wybranych punktów, punktów, które właśnie przewróciłeś, lub punktów, które właśnie kliknąłeś. Ta aplikacja wyświetla wartości punktów w aplikacji, ale możesz zrobić wszystko za pomocą punktów (np. Obliczyć coś innego).

example gif of selecting data in a Dash app

import dash 
from dash.dependencies import Input, Output 
import dash_core_components as dcc 
import dash_html_components as html 
import json 

app = dash.Dash(__name__) 

app.layout = html.Div([ 
    dcc.Graph(
     id='basic-interactions', 
     figure={ 
      'data': [ 
       { 
        'x': [1, 2, 3, 4], 
        'y': [4, 1, 3, 5], 
        'text': ['a', 'b', 'c', 'd'], 
        'customdata': ['c.a', 'c.b', 'c.c', 'c.d'], 
        'name': 'Trace 1', 
        'mode': 'markers', 
        'marker': {'size': 12} 
       }, 
       { 
        'x': [1, 2, 3, 4], 
        'y': [9, 4, 1, 4], 
        'text': ['w', 'x', 'y', 'z'], 
        'customdata': ['c.w', 'c.x', 'c.y', 'c.z'], 
        'name': 'Trace 2', 
        'mode': 'markers', 
        'marker': {'size': 12} 
       } 
      ] 
     } 
    ), 

    html.Div([ 
     dcc.Markdown(""" 
      **Hover Data** 

      Mouse over values in the graph. 
     """.replace(' ', '')), 
     html.Pre(id='hover-data') 
    ], style=styles['column']), 

    html.Div([ 
     dcc.Markdown(""" 
      **Click Data** 

      Click on points in the graph. 
     """.replace(' ', '')), 
     html.Pre(id='click-data'), 
    ], style=styles['column']), 

    html.Div([ 
     dcc.Markdown(""" 
      **Selection Data** 

      Choose the lasso or rectangle tool in the graph's menu 
      bar and then select points in the graph. 
     """.replace(' ', '')), 
     html.Pre(id='selected-data'), 
    ]) 
]) 


@app.callback(
    Output('hover-data', 'children'), 
    [Input('basic-interactions', 'hoverData')]) 
def display_hover_data(hoverData): 
    # 
    # This is where you can access the hover data 
    # This function will get called automatically when you hover over points 
    # hoverData will be equal to an object with that data 
    # You can compute something off of this data, and return it to the front-end UI 
    # 


    return json.dumps(hoverData, indent=2) 


@app.callback(
    Output('click-data', 'children'), 
    [Input('basic-interactions', 'clickData')]) 
def display_click_data(clickData): 
    # Similarly for data when you click on a point 
    return json.dumps(clickData, indent=2) 


@app.callback(
    Output('selected-data', 'children'), 
    [Input('basic-interactions', 'selectedData')]) 
def display_selected_data(selectedData): 
    # Similarly for data when you select a region 
    return json.dumps(selectedData, indent=2) 


if __name__ == '__main__': 
    app.run_server(debug=True) 
+0

Możesz napisać ten kod w jupyter i wykonać komorę po komórce, ale ostatecznie nie wiąże się z jądrem jądra w inny sposób. Oto przykład aplikacji Dash opracowanej w Jupyter: https://plot.ly/~jackp/17610 –

+0

Czy możesz wyizolować kod, który odpowiada na powyższe pytanie dla notatnika jupyter i dodać do odpowiedzi. Wygląda na to, że jest dużo kodu, który nie jest potrzebny. – Merlin

+0

Sure - Właśnie usunąłem zmienne stylu. Dodałem także kilka komentarzy, gdzie dokładnie można uzyskać dostęp do danych po najechaniu kursorem, kliknięciu lub wybraniu zdarzeń. –