【问题标题】:在 Python 中使用 Dash 绘制并行类别链接刷(交叉过滤器)
【发布时间】:2022-01-20 15:55:52
【问题描述】:

我想在 plotly 中创建一个平行类别,将刷牙作为 plotly 的文档链接。

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

但是,在里面,它只显示了如何在没有 plotly-dash 的情况下做到这一点。

如何结合go.Pract和dash?有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: python plotly plotly-dash


    【解决方案1】:

    让我自己回答这个问题,希望可以节省某人的开发时间。

    在跳转代码之前有两个关键点要带走:

    1. 需要一个破折号回调在两个图表之间传递选定的索引。 Reference to plotly docs.
    2. go.Parcat 不支持selectedData 回调,需要使用clickData。这有点棘手。

    这是我的方法。

    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)
    

    【讨论】:

      【解决方案2】:
      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)
      

      【讨论】:

        猜你喜欢
        • 2021-06-07
        • 2016-12-29
        • 2012-01-22
        • 1970-01-01
        • 2015-09-03
        • 2016-01-01
        • 1970-01-01
        • 2018-11-28
        • 2014-03-28
        相关资源
        最近更新 更多