具有多个下拉选项的饼图

Pie chart with multiple dropdown options

我正在尝试制作一个包含 3 个选项的饼图:

  1. 在没有 select 下拉选项的情况下为所有项目创建图表
  2. 显示每个项目的每个图表 select离子。
  3. 为多个项目选项创建图表。它是项目选项的总和。

下面是我的代码:

import pandas as pd
import numpy as np
import plotly.express as px
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import plotly.graph_objects as go

df = pd.DataFrame({
    'invoiceTotal': [123.25,237.55,220.13,211.35,135.46],
    'itemType': ['item','service','service','service','item'],
    'Channel':['In Store','Phone Order','In Store','E-mail','Website']})

app = dash.Dash(__name__,external_stylesheets=[dbc.themes.LUX])
app.layout = html.Div([
                dbc.Row([
                        dcc.Dropdown(id='channel_type',placeholder="Channel", # Dropdown for heatmap color
                                options=[{'label':y,'value':y} for y in df.sort_values('Channel')['Channel'].unique()], 
                                multi=False,
                                disabled=False,
                                clearable=True,
                                searchable=True), 
                        dcc.Graph(id='pie-chart',figure={},style={'height':400,'width':'auto'})
                        ])
])

@app.callback(Output('pie-chart', 'figure'),
             [Input('channel_type', 'value')])

def build_graph(channeltype):
    if not channeltype or 'Select' in channeltype:    
        df1 = df.copy()
        df1_1 = pd.pivot_table(df1,('invoiceTotal'),index=['itemType'],aggfunc=np.sum).reset_index()
        df1_1['Channel'] = 'All channel'            
    else:
        df1 = df.copy()
        df1_1 = pd.pivot_table(df1,('invoiceTotal'),index=['itemType','Channel'],aggfunc=np.sum).reset_index()
        df1_1 = df1_1[(df1_1['Channel'] == channeltype)]

           
    pie_chart = px.pie(df1_1,values='invoiceTotal',names='itemType',
               color_discrete_sequence=px.colors.qualitative.Prism,hole=.3)
    pie_chart.update_traces(textinfo='percent+label',
                    title_position="top center",
                    title_font_size=18,
                    showlegend=True)
    pie_chart.update_layout(plot_bgcolor='white',margin=dict(l=20, r=20, t=20, b=20))
    pie_chart.update_yaxes(showline=False,showgrid=False)
    pie_chart.update_xaxes(showline=False,showgrid=False)     
    return pie_chart

if __name__ == "__main__":
    app.run_server(debug=False,port=1200)

它只适用于选项 1 和选项 2。当我将下拉选项从 False 更改为 True 时,它引发了错误:ValueError: ('Lengths must match to compare', (5,), (1,))

我很好奇无论如何都要选择选项 3。谢谢。

下拉列表中的多项选择应设置为 multi=positive 并且接收到的值将是单个值和多个值的混合,因此需要更改格式以使用 isin 包含的值提取条件。我还添加了一个设置作为初始图表。由于我们尚未验证所有数据,请自行验证数据。

import dash
from dash import html
from dash import dcc
import dash_bootstrap_components as dbc
from jupyter_dash import JupyterDash
from dash.dependencies import Input, Output, State
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd

df = pd.DataFrame({
    'invoiceTotal': [123.25,237.55,220.13,211.35,135.46],
    'itemType': ['item','service','service','service','item'],
    'Channel':['In Store','Phone Order','In Store','E-mail','Website']})

app = dash.Dash(__name__,external_stylesheets=[dbc.themes.LUX])
#app = JupyterDash(__name__,external_stylesheets=[dbc.themes.LUX])

app.layout = html.Div([
                dbc.Row([
                        dcc.Dropdown(id='channel_type',placeholder="Channel", # Dropdown for heatmap color
                                options=[{'label':y,'value':y} for y in df.sort_values('Channel')['Channel'].unique()], 
                                multi=True, # update
                                disabled=False,
                                clearable=True,
                                searchable=True), 
                        dcc.Graph(id='pie-chart',figure=pie_chart, style={'height':400,'width':'auto'}) # update
                        ])
])

@app.callback(Output('pie-chart', 'figure'),
             [Input('channel_type', 'value')])

def build_graph(channeltype):
    if not channeltype or 'Select' in channeltype:    
        df1 = df.copy()
        df1_1 = pd.pivot_table(df1,('invoiceTotal'),index=['itemType'],aggfunc=np.sum).reset_index()
        df1_1['Channel'] = 'All channel'            
    else:
        df1 = df.copy()
        df1_1 = pd.pivot_table(df1,('invoiceTotal'),index=['itemType','Channel'],aggfunc=np.sum).reset_index()
        df1_1 = df1_1[df1_1['Channel'].isin(channeltype)] # update

           
    pie_chart = px.pie(df1_1,values='invoiceTotal',names='itemType',
               color_discrete_sequence=px.colors.qualitative.Prism,hole=.3)
    pie_chart.update_traces(textinfo='percent+label',
                    title_position="top center",
                    title_font_size=18,
                    showlegend=True)
    pie_chart.update_layout(plot_bgcolor='white',margin=dict(l=20, r=20, t=20, b=20))
    pie_chart.update_yaxes(showline=False,showgrid=False)
    pie_chart.update_xaxes(showline=False,showgrid=False)     
    return pie_chart

if __name__ == "__main__":
    app.run_server(debug=False, port=1200)# mode='inline'