0
votes

I asked this on the Plotly forum but unfortunately got no answer, maybe I'll have better luck here?

I’ve only quickly went through the tutorials for Dash so I need some confirmation before I’m ready to commit on Dash to fulfill a goal. So basically I worked on a tool which drew specific common graphs using Plotly Python. So now I have to work on a dashboard feature where I can display all those graphs together with cross-filtering/linked brushing i.e. basically selecting a point in one graph would also highlight the same data point in other visualizations if possible. Also, there’s only one dataframe so that makes it simpler too.

Now my question is simply this; is it possible to achieve this with Dash Python?

In the tutorials, Dash seemed more for like static Dashboards where you already know how you want to layout your dashboard. Is there some trick I could use to achieve this? Because I only have to support like 15 visualization types so some kind of ‘hacks’ would be welcome too. I do not have to do anything detailed like saving/loading old graphs. It would be more like I have this list:

line_chart: col1, col2
bar_chart: col2, col3
scatterplot: col1, col2, col3

and I would make new charts in Dash from scratch WITH linked brushing/cross-filtering or whatever it’s called, but basically just 'select in one, reflect in others’. If so, any helpful links would be appreciated as well, or a just a general direction on how I can achieve this.

Thanks in advance!

1

1 Answers

0
votes

This website may help : Using CrossFiltering in Plotly

To brief what was put in this discussion, the code that helped resolve the issue looked like:

import dash
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
import pandas as pd
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

# make a sample data frame with 6 columns
np.random.seed(0)
df = pd.DataFrame({"Col " + str(i+1): np.random.rand(30) for i in range(6)})

total_clicks = 0 # keep track of total clicks

app.layout = html.Div([
    html.Button('Reset selections', id='reset'), # add a button
    html.Div(
        dcc.Graph(id='g1', config={'displayModeBar': False}),
        className='four columns'
    ),
    html.Div(
        dcc.Graph(id='g2', config={'displayModeBar': False}),
        className='four columns'
        ),
    html.Div(
        dcc.Graph(id='g3', config={'displayModeBar': False}),
        className='four columns'
    )
], className='row')

def get_figure(df, x_col, y_col, selectedpoints, selectedpoints_local):

    if selectedpoints_local and selectedpoints_local['range']:
        ranges = selectedpoints_local['range']
        selection_bounds = {'x0': ranges['x'][0], 'x1': ranges['x'][1],
                            'y0': ranges['y'][0], 'y1': ranges['y'][1]}
    else:
        selection_bounds = {'x0': np.min(df[x_col]), 'x1': np.max(df[x_col]),
                            'y0': np.min(df[y_col]), 'y1': np.max(df[y_col])}

    # set which points are selected with the `selectedpoints` property
    # and style those points with the `selected` and `unselected`
    # attribute. see
    # https://medium.com/@plotlygraphs/notes-from-the-latest-plotly-js-release-b035a5b43e21
    # for an explanation
    return {
        'data': [{
            'x': df[x_col],
            'y': df[y_col],
            'text': df.index,
            'textposition': 'top',
            'selectedpoints': selectedpoints,
            'customdata': df.index,
            'type': 'scatter',
            'mode': 'markers+text',
            'marker': { 'color': 'rgba(0, 116, 217, 0.7)', 'size': 12 },
            'unselected': {
                'marker': { 'opacity': 0.3 },
                # make text transparent when not selected
                'textfont': { 'color': 'rgba(0, 0, 0, 0)' }
            }
        }],
        'layout': {
            'margin': {'l': 20, 'r': 0, 'b': 15, 't': 5},
            'dragmode': 'select',
            'hovermode': False,
            # Display a rectangle to highlight the previously selected region
            'shapes': [dict({
                'type': 'rect',
                'line': { 'width': 1, 'dash': 'dot', 'color': 'darkgrey' }
            }, **selection_bounds
            )]
        }
    }