简体   繁体   English

Plotly 并行类别链接刷(交叉过滤器)与 Python 中的 Dash

[英]Plotly parallel category linked brushing(cross filter) with Dash in Python

I want to create a parallel category in plotly that have linked brushing as the documentation from plotly.我想在 plotly 中创建一个并行类别,该类别已链接刷作为 plotly 的文档。

https://plotly.com/python/parallel-categories-diagram/#parallel-categories-linked-brushing https://plotly.com/python/parallel-categories-diagram/#parallel-categories-linked-brushing

However, inside, it only show how to do it without plotly-dash.然而,在里面,它只展示了如何在没有情节破折号的情况下做到这一点。

How to combine go.Pract and dash?如何结合 go.Pract 和 dash? Can someone help me with this?有人可以帮我弄这个吗?

Let myself answer this question, hopefully can save someone's developing time.让我自己回答这个问题,希望可以节省某人的开发时间。

Two key point to take away before jump to code,跳转到代码之前要带走的两个关键点,

  1. Need to use dash callback to pass the selected index between two graphs.需要使用破折号回调在两个图表之间传递选定的索引。 please refer to https://dash.plotly.com/interactive-graphing请参考https://dash.plotly.com/interactive-graphing
  2. go.Parcat dose not support "selectedData" for callback, instead, you need to use "clickData". go.Parcat 不支持“selectedData”回调,需要使用“clickData”。 This is a bit tricky.这有点棘手。

Here is my approach.这是我的方法。

import plotly.graph_objects as go
import pandas as pd
import numpy as np
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output

cars_df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/imports-85.csv')


# Build figure as FigureWidget
def get_parcat_fig(selected_index, cars_df):  # create function to update fig object
    # Build parcats dimensions
    categorical_dimensions = ['body-style', 'drive-wheels', 'fuel-type']
    dimensions = [dict(values=cars_df[label], label=label) for label in categorical_dimensions]

    color = np.zeros(len(cars_df), dtype='uint8')
    colorscale = [[0, 'gray'], [1, 'firebrick']]
    color[selected_index] = 1

    fig = go.FigureWidget(
        data=[go.Scatter(x=cars_df.horsepower, y=cars_df['highway-mpg'],
                         marker={'color': 'gray'}, mode='markers', selected={'marker': {'color': 'firebrick'}},
                         unselected={'marker': {'opacity': 0.3}}, selectedpoints=selected_index),
              go.Parcats(
                  domain={'y': [0, 0.4]}, dimensions=dimensions,
                  line={'colorscale': colorscale, 'cmin': 0,
                        'cmax': 1, 'color': color, 'shape': 'hspline'})
              ])

    fig.update_layout(
        height=800, xaxis={'title': 'Horsepower'},
        yaxis={'title': 'MPG', 'domain': [0.6, 1]},
        dragmode='lasso', hovermode='closest')
    return fig


app = dash.Dash(__name__)
app.layout = html.Div([
    dcc.Graph(
        id='parallel_category'
    )
])


@app.callback(
    Output("parallel_category", "figure"),
    Input("parallel_category", "selectedData"),
    Input("parallel_category", "clickData")
)
def get_fig_callback(selected_data, click_data):
    ctx = dash.callback_context
    if (ctx.triggered[0]['prop_id'] == "parallel_category.selectedData") \
            or (ctx.triggered[0]['prop_id'] == "parallel_category.clickData"):
        selected_data = [point['pointNumber'] for point in ctx.triggered[0]['value']['points']]
    else:
        selected_data = []
    return get_parcat_fig(selected_data, cars_df)


if __name__ == '__main__':
    app.run_server(debug=True)
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output

cars_df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/imports-85.csv')


# Build figure as FigureWidget
def get_parcat_fig(selected_index, cars_df):  # create function to update fig object
    # Build parcats dimensions
    categorical_dimensions = ['body-style', 'drive-wheels', 'fuel-type']
    dimensions = [dict(values=cars_df[label], label=label) for label in categorical_dimensions]

    color = np.zeros(len(cars_df), dtype='uint8')
    colorscale = [[0, 'gray'], [1, 'firebrick']]
    color[selected_index] = 1

    fig = go.FigureWidget(
        data=[go.Scatter(x=cars_df.horsepower, y=cars_df['highway-mpg'],
                         marker={'color': 'gray'}, mode='markers', selected={'marker': {'color': 'firebrick'}},
                         unselected={'marker': {'opacity': 0.3}}, selectedpoints=selected_index),
              go.Parcats(
                  domain={'y': [0, 0.4]}, dimensions=dimensions,
                  line={'colorscale': colorscale, 'cmin': 0,
                        'cmax': 1, 'color': color, 'shape': 'hspline'})
              ])

    fig.update_layout(
        height=800, xaxis={'title': 'Horsepower'},
        yaxis={'title': 'MPG', 'domain': [0.6, 1]},
        dragmode='lasso', hovermode='closest')
    return fig


app = dash.Dash(__name__)
app.layout = html.Div([
    dcc.Graph(
        id='parallel_category'
    )
])


@app.callback(
    Output("parallel_category", "figure"),
    Input("parallel_category", "selectedData"),
    Input("parallel_category", "clickData")
)
def get_fig_callback(selected_data, click_data):
    ctx = dash.callback_context
    if (ctx.triggered[0]['prop_id'] == "parallel_category.selectedData") \
            or (ctx.triggered[0]['prop_id'] == "parallel_category.clickData"):
        selected_data = [point['pointNumber'] for point in ctx.triggered[0]['value']['points']]
    else:
        selected_data = []
    return get_parcat_fig(selected_data, cars_df)


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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM