1

---Update--- 1/27/2018

After looking into it. I have figured that I need to go a little different direction. Python Dash looks like the best option to go but I am still having some problems figuring out how to make the graph dynamic and add annotations to the graph as I click on data points.

I want to take the example from dash interactive graph first example and combine it with annotation functionality - an example of Annotation.

This is exactly what I want but I'm not sure how to implement it in the python version of dash - Styling and Formatting Annotations


1/20/2018

I have been looking for a way to program a datatip tool or script similar to Matlab's datatip as a python plotly version. I haven't been successful since it seems like the on_click or mouse_event feature in plotly are not documented really well. I am trying to create a script or class that will interface with plotly using python to do similar functionality as Matlab's datatip tool.

This is what I have found so far.

This example shows clicking on a bar graph to visit url on click.

This example creates data points upon clicking Plotly.js create a point on click.

This one is mouse event handling - mouse-events

This is the best example but it's for javascript and I'm not sure if there is one for python - plotlyjs-events

I am using Plotly's standard example to perform test scripts, but haven't been successful yet. Any advice or help is appreciated.

Below is plotly's standard example.

import plotly
import plotly.graph_objs as go
import plotly.widgets.graph_widget as gw
# Create random data with numpy
import numpy as np

N = 1000
random_x = np.random.randn(N)
random_y = np.random.randn(N)

# Create a trace
trace = go.Scatter(
    x = random_x,
    y = random_y,
    mode = 'markers'
)

data = [trace]
plotly.offline.plot(data, filename='basic-scatter')
Nate
  • 21
  • 6

1 Answers1

0

After searching through the plotly and dash source code, along with examples. I was able to come up with some simple functionality. Its a start but it gets me where I want to go.

import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, Event
from textwrap import dedent as d
import json


import plotly.graph_objs as go

N = 1000
random_x = np.random.randn(N)
random_y = np.random.randn(N)

#Dash appliction boiler plate
app = dash.Dash()

app.css.config.serve_locally = True
app.scripts.config.serve_locally = True

styles = {
    'pre': {
        'border': 'thin lightgrey solid',
        'overflowX': 'scroll'
    }
}


# Edit your markup here
app.layout = html.Div([
    html.H1('Wielding Data'),
    dcc.Graph(id='basic-interactions'), 


    html.Div(className='row', children=[
        html.Div([
            dcc.Markdown(d("""
                **Hover Data**

                Mouse over values in the graph.
            """)),
            html.Pre(id='hover-data', style=styles['pre'])
        ], className='three columns'),

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

                Click on points in the graph.
            """)),
            html.Pre(id='click-data', style=styles['pre']),
        ], className='three columns'),

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

                Choose the lasso or rectangle tool in the graph's menu
                bar and then select points in the graph.
            """)),
            html.Pre(id='selected-data', style=styles['pre']),
        ], className='three columns'),

        html.Div([
            dcc.Markdown(d("""
                **Zoom and Relayout Data**

                Click and drag on the graph to zoom or click on the zoom
                buttons in the graph's menu bar.
                Clicking on legend items will also fire
                this event.
            """)),
            html.Pre(id='relayout-data', style=styles['pre']),
        ], className='three columns')
    ])
])

@app.callback(
        Output('basic-interactions','figure'),
        [Input('basic-interactions','clickData')
         ])
def update_graph(clickData):
    if not clickData:
        x_value=[]
        y_value=[]

    else:
        x_value = clickData['points'][0]['x']
        y_value = clickData['points'][0]['y']

    return{'data': [go.Scatter(
                x=random_x,
                y=random_y,
                mode = 'markers'
                )          

            ],
            'layout': {'hovermode': 'closest',
                       'annotations':[{
                               'x':x_value,
                               'y':y_value,
                               'arrowhead': 6,
                               'xref':'x',
                               'yref':'y',
                               'text':'X:' + str(x_value) + '\n' + 'Y:' + str(y_value),
                               'ax':0,
                               'ay':-20}]}}


@app.callback(
    Output('hover-data', 'children'),
    [Input('basic-interactions', 'hoverData')])
def display_hover_data(hoverData):
    return json.dumps(hoverData, indent=2)


@app.callback(
    Output('click-data', 'children'),
    [Input('basic-interactions', 'clickData')])
def display_click_data(clickData): 
    print(clickData)
    return json.dumps(clickData, indent=2)


@app.callback(
    Output('selected-data', 'children'),
    [Input('basic-interactions', 'selectedData')])
def display_selected_data(selectedData):
    return json.dumps(selectedData, indent=2)

@app.callback(
    Output('relayout-data', 'children'),
    [Input('basic-interactions', 'relayoutData')])
def display_selected_data(relayoutData):
    return json.dumps(relayoutData, indent=2)

if __name__ == '__main__':
    app.run_server(debug=False)
Nate
  • 21
  • 6