尝试添加下拉列表以显示饼图时,plotly dash 仪表板上的回调错误
Callback error on plotly dash dashboard when trying to add a dropdown to show pie charts
我对 dash 还很陌生,但我正在尝试组装一个数据仪表板。我想要的是一个下拉列表,它基于输入呈现两个饼图之一。构造饼图的逻辑包含在我的回调函数中。它说它期待 1 个输出但它有两个。我在网上看过并尝试了不同的建议。我想我已经非常接近让它工作了,只是有些愚蠢的事情我没有做。
我知道这里的人都是巫师,所以我希望有人能帮助我。另外,如果有人精通 Dash,你能给我指出良好文档的方向,以了解如何定位它,这样我就可以更改布局,使这些图更适合仪表板,而不仅仅是网页吗?
太有爱了
谢谢
import pandas as pd
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash
import plotly.graph_objects as go
import plotly.express as px
from dash import no_update
import plotly.figure_factory as ff
app = dash.Dash(__name__)
df = pd.read_csv('nyc-jobs.csv')
#top job categories
counts = df['Job Category'].value_counts()
counts = pd.DataFrame(counts)
counts = counts.head(10)
counts.sort_values(['Job Category'],ascending=True, inplace = True)
fig = px.bar(df, y=counts.index, x=counts['Job Category'])
#Salary range distribution
salary_counts = df['Salary Range To'].value_counts()
salary_counts = pd.DataFrame(counts)
group_labels = ['Salary Range From','Salary Range To']
fig3 = ff.create_distplot([df['Salary Range From'],df['Salary Range To']], group_labels, bin_size= 10000)
fig4 = go.Figure()
fig4.add_trace(go.Box(y=df['Salary Range From'], name='Salary Range From',
marker_color = 'indianred'))
fig4.add_trace(go.Box(y=df['Salary Range To'], name = 'Salary Range To',
marker_color = 'lightseagreen'))
# # of positions
df.sort_values(by = ['# Of Positions'], ascending = True, inplace = True)
df_group = df.groupby(['Business Title']).mean(['# Of Positions'])
df_group.sort_values('# Of Positions', ascending = True, inplace = True)
df_group.index = df_group.index.str.capitalize()
fig5 = px.bar(df, y=df_group.index[-5:], x=df_group['# Of Positions'][-5:])
app.layout = html.Div([
html.H1("New York City Job Postings", style = {'text-align': 'center', 'font-family': 'Helvetica'}),
#Job postings graph
dcc.Graph(
id='Top Job Postings',
figure=fig
),
html.Div([html.H2('Report Type:', style={'margin-right': '2em', 'font-family': 'Helvetica'}),]),
dcc.Dropdown(id='input-type',
options=[
{'label': 'Full vs part time report ', 'value': 'OPT1'},
{'label': 'Posting type', 'value': 'OPT2'}
],
placeholder='Select a report type',
multi=False,
clearable=False,
style={'width':800, 'padding':3, 'font-size':20, 'text-align-last':'center', 'font-family': 'Helvetica'}),
html.Div(id='output_container', children=[]),
html.Div(dcc.Graph(id='pie_chart_reports')),
#Salary Distributions
dcc.Graph(
id="Salary Distribution",
figure = fig3),
dcc.Graph(
id="Salary Distribution boxplot",
figure = fig4),
dcc.Graph(
id='Highest number of positions',
figure=fig5
)
])
@app.callback(
[Output(component_id='pie_chart_reports', component_property='figure')],
[Input(component_id='input-type', component_property='value')]
)
def update_graph(report_type):
dff = df
container = "The chosen report was: {}".format(report_type)
if report_type == 'OPT1':
#full time vs part time
ft_pt = dff['Full-Time/Part-Time indicator']
ft_pt.fillna('Not listed', inplace = True)
ft_pt.replace('F', 'Full Time', inplace = True)
ft_pt.replace('P', 'Part Time', inplace = True)
value_counts_ft_pt = dff['Full-Time/Part-Time indicator'].value_counts()
labels_ft_pt = value_counts_ft_pt.index.tolist()
fig1 = px.pie(dff,
values = value_counts_ft_pt,
names = labels_ft_pt)
return container, dcc.Graph(id='pie_chart_reports',figure=fig1)
else:
#internal vs externl
value_counts_posting_type = dff['Posting Type'].value_counts()
labels_posting_type = value_counts_posting_type.index.tolist()
fig2 = px.pie(
df,
values = value_counts_posting_type,
names = labels_posting_type,
color_discrete_sequence=px.colors.sequential.Bluyl)
return container, dcc.Graph(id='pie_chart_reports',figure=fig2)
if __name__ == '__main__':
app.run_server(debug=True)
第一个问题是你的回调有一个输出,但是你 return 一个包含两个东西的元组。因此,您可以添加一个 Output
来定位您希望其值为 content
的元素,我猜该元素是 ID 为 output_container
的元素。另一种选择是从 return 语句中删除 content
。
第二个问题是 Output
被列表包围,因此 dash 期望 return 值是一个包含一个值的列表。您可以删除 Ouput
周围的列表,因此它需要一个元组
Output(component_id='pie_chart_reports', component_property='figure')
或者您可以用列表包围您的 return 值。
第三个问题是您的目标是 component_property
figure
,但您 return 是 Graph
组件。例如,您应该 return fig1
而不是 dcc.Graph(id='pie_chart_reports', figure=fig1)
。
我对 dash 还很陌生,但我正在尝试组装一个数据仪表板。我想要的是一个下拉列表,它基于输入呈现两个饼图之一。构造饼图的逻辑包含在我的回调函数中。它说它期待 1 个输出但它有两个。我在网上看过并尝试了不同的建议。我想我已经非常接近让它工作了,只是有些愚蠢的事情我没有做。
我知道这里的人都是巫师,所以我希望有人能帮助我。另外,如果有人精通 Dash,你能给我指出良好文档的方向,以了解如何定位它,这样我就可以更改布局,使这些图更适合仪表板,而不仅仅是网页吗?
太有爱了
谢谢
import pandas as pd
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash
import plotly.graph_objects as go
import plotly.express as px
from dash import no_update
import plotly.figure_factory as ff
app = dash.Dash(__name__)
df = pd.read_csv('nyc-jobs.csv')
#top job categories
counts = df['Job Category'].value_counts()
counts = pd.DataFrame(counts)
counts = counts.head(10)
counts.sort_values(['Job Category'],ascending=True, inplace = True)
fig = px.bar(df, y=counts.index, x=counts['Job Category'])
#Salary range distribution
salary_counts = df['Salary Range To'].value_counts()
salary_counts = pd.DataFrame(counts)
group_labels = ['Salary Range From','Salary Range To']
fig3 = ff.create_distplot([df['Salary Range From'],df['Salary Range To']], group_labels, bin_size= 10000)
fig4 = go.Figure()
fig4.add_trace(go.Box(y=df['Salary Range From'], name='Salary Range From',
marker_color = 'indianred'))
fig4.add_trace(go.Box(y=df['Salary Range To'], name = 'Salary Range To',
marker_color = 'lightseagreen'))
# # of positions
df.sort_values(by = ['# Of Positions'], ascending = True, inplace = True)
df_group = df.groupby(['Business Title']).mean(['# Of Positions'])
df_group.sort_values('# Of Positions', ascending = True, inplace = True)
df_group.index = df_group.index.str.capitalize()
fig5 = px.bar(df, y=df_group.index[-5:], x=df_group['# Of Positions'][-5:])
app.layout = html.Div([
html.H1("New York City Job Postings", style = {'text-align': 'center', 'font-family': 'Helvetica'}),
#Job postings graph
dcc.Graph(
id='Top Job Postings',
figure=fig
),
html.Div([html.H2('Report Type:', style={'margin-right': '2em', 'font-family': 'Helvetica'}),]),
dcc.Dropdown(id='input-type',
options=[
{'label': 'Full vs part time report ', 'value': 'OPT1'},
{'label': 'Posting type', 'value': 'OPT2'}
],
placeholder='Select a report type',
multi=False,
clearable=False,
style={'width':800, 'padding':3, 'font-size':20, 'text-align-last':'center', 'font-family': 'Helvetica'}),
html.Div(id='output_container', children=[]),
html.Div(dcc.Graph(id='pie_chart_reports')),
#Salary Distributions
dcc.Graph(
id="Salary Distribution",
figure = fig3),
dcc.Graph(
id="Salary Distribution boxplot",
figure = fig4),
dcc.Graph(
id='Highest number of positions',
figure=fig5
)
])
@app.callback(
[Output(component_id='pie_chart_reports', component_property='figure')],
[Input(component_id='input-type', component_property='value')]
)
def update_graph(report_type):
dff = df
container = "The chosen report was: {}".format(report_type)
if report_type == 'OPT1':
#full time vs part time
ft_pt = dff['Full-Time/Part-Time indicator']
ft_pt.fillna('Not listed', inplace = True)
ft_pt.replace('F', 'Full Time', inplace = True)
ft_pt.replace('P', 'Part Time', inplace = True)
value_counts_ft_pt = dff['Full-Time/Part-Time indicator'].value_counts()
labels_ft_pt = value_counts_ft_pt.index.tolist()
fig1 = px.pie(dff,
values = value_counts_ft_pt,
names = labels_ft_pt)
return container, dcc.Graph(id='pie_chart_reports',figure=fig1)
else:
#internal vs externl
value_counts_posting_type = dff['Posting Type'].value_counts()
labels_posting_type = value_counts_posting_type.index.tolist()
fig2 = px.pie(
df,
values = value_counts_posting_type,
names = labels_posting_type,
color_discrete_sequence=px.colors.sequential.Bluyl)
return container, dcc.Graph(id='pie_chart_reports',figure=fig2)
if __name__ == '__main__':
app.run_server(debug=True)
第一个问题是你的回调有一个输出,但是你 return 一个包含两个东西的元组。因此,您可以添加一个 Output
来定位您希望其值为 content
的元素,我猜该元素是 ID 为 output_container
的元素。另一种选择是从 return 语句中删除 content
。
第二个问题是 Output
被列表包围,因此 dash 期望 return 值是一个包含一个值的列表。您可以删除 Ouput
周围的列表,因此它需要一个元组
Output(component_id='pie_chart_reports', component_property='figure')
或者您可以用列表包围您的 return 值。
第三个问题是您的目标是 component_property
figure
,但您 return 是 Graph
组件。例如,您应该 return fig1
而不是 dcc.Graph(id='pie_chart_reports', figure=fig1)
。