Python: Reactive Visualization (Interactivity)

Rendering reactive components.

Adapted from User Guide

In [1]:
import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc
import plotly.graph_objs as go
In [2]:
import pandas as pd
import json
In [3]:
# For Jupyter notebook only
import plotly
plotly.offline.init_notebook_mode()

Hello Interactivity

In [4]:
app = dash.Dash()

app.layout = html.Div([
    dcc.Input(id='text1', value='Enter name', type='text'),
    html.Div(id='greet')
])


@app.callback(
    Output('greet', 'children'),
    [Input('text1', 'value')]
)
def update_greet(val):
    return f"Hello, {val}!"
In [5]:
app.server.run()
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Enter ESC-I-I to interrupt before proceeding.

Reactive plots

In [7]:
url = 'https://raw.githubusercontent.com/pandas-dev/pandas/master/pandas/tests/data/iris.csv'
iris = pd.read_csv(url)
cols = iris.columns[:-1].tolist()
In [8]:
app = dash.Dash()

app.layout = html.Div([
    dcc.Graph(id='scatter', animate=True),

    dcc.Dropdown(id='x-axis',
                 options=[{'label': c,'value': c} for c in cols],
                 value=cols[0]),

    dcc.Dropdown(id='y-axis',
                 options=[{'label': c,'value': c} for c in cols],
                 value=cols[1]),
])

@app.callback(
    Output('scatter', 'figure'),
    [
        Input('x-axis', 'value'),
        Input('y-axis', 'value')
    ]
)
def update_sccatter(xlab, ylab):
    return {
        'data': [
                go.Scatter(
                    x = iris.loc[iris['Name'] == name, xlab],
                    y = iris.loc[iris['Name'] == name, ylab],
                    text = iris.loc[iris['Name'] == name, 'Name'],
                    mode = 'markers',
                    marker = go.Marker(
                        size = 10
                        ),
                    name = name,
                    )
                for name in iris['Name'].unique()
            ],
        'layout': go.Layout(
                width = 500,
                height = 500,
                xaxis = dict(
                    title=xlab,
                    range=[0, 10],
                ),
                yaxis = dict(
                    title=ylab,
                    range=[0, 10],
                ),
                hovermode = 'closest'
            )
    }
In [9]:
app.server.run()
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Enter ESC-I-I to interrupt before proceeding.

Graph Crossfiltering

In [11]:
app = dash.Dash()

styles = {
    'column': {
        'display': 'inline-block',
        'width': '29%',
        'padding': 10,
        'boxSizing': 'border-box',
        'minHeight': '200px',
        'float': 'right'
    },
    'pre': {'border': 'thin lightgrey solid'}
}

app.layout = html.Div([
    html.Div([
        dcc.Graph(id='scatter',
                  figure={
                    'data': [
                            go.Scatter(
                                x = iris.loc[iris['Name'] == name, 'SepalLength'],
                                y = iris.loc[iris['Name'] == name, 'SepalWidth'],
                                text = iris.loc[iris['Name'] == name, 'Name'],
                                mode = 'markers',
                                marker = go.Marker(
                                    size = 10
                                    ),
                                name = name,
                                )
                            for name in iris['Name'].unique()
                        ],
                    'layout': go.Layout(
                            xaxis = dict(
                                title='SepalLength',
                            ),
                            yaxis = dict(
                                title='SepalWidth',
                            ),
                            hovermode = 'closest'
                        )
                  })],
    style={'width': '69%', 'display': 'inline-block'}),

    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', style=styles['pre']),
    ],
    style=styles['column']),
])

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

app.server.run()
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Enter ESC-I-I to interrupt before proceeding.