仪表板上显示错误'An object was provided as `children` instead of a component....'



示例csv数据:

日期,数据中心,客户,公司ID,来源,目标,价值

我运行以下代码,将sankey图表放在仪表板中,然后可以通过应用过滤器相应地更新图表。但仪表板上出现错误。问题出在哪里?

对象被提供为children,或编号(或列表(。检查看起来的children属性类似于:

import io
from base64 import b64encode
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import plotly.io as pio
import pandas as pd
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
dataset = pd.read_csv('leanSankey.csv')
labelListTemp1 = list(set(dataset.source.values))
labelListTemp2 = list(set(dataset.target.values))
labelList = labelListTemp1 + labelListTemp2
sankey_node = list(dict.fromkeys(labelList))

fig = go.Figure(data=[go.Sankey( node = dict( pad=15,thickness=20,line = dict(color = "black", width = 0.5),label = labelList,color = 'black' ),
link = dict(source = dataset.source.apply(lambda x: labelList.index(x)),
target = dataset.target.apply(lambda x: labelList.index(x)),
value = dataset.value))])
#fig.update_layout(autosize=False,width = 3000,height = 1000,hovermode = 'x',title="test user behavior monitor",font=dict(size=16, color='blue'))

#fig.write_html('test.html', auto_open=True)
#fig.show()

app.layout = html.Div([
dcc.Dropdown(
id='dataCenter_dropdown',
options=[ {'label': i, 'value': i} for i in dataset['Data Center'].unique()] + [{'label': 'Select all', 'value': 'allID'}],
multi=True, placeholder='Please select Data Center'),
dcc.Dropdown(
id='customer_dropdown',
options=[{'label': i, 'value': i} for i in dataset['Customer'].unique()]  + [{'label': 'Select all', 'value': 'allID'}],
multi=True, placeholder='Please select Customer'),

dcc.Dropdown(
id='companyID_dropdown',
options=[{'label': i, 'value': i} for i in dataset['companyID'].unique()] + [{'label': 'Select all', 'value': 'allID'}],
multi=True, placeholder='Please select companyID'),


#    html.Div(id='dd-output-container'),
dcc.Graph(id='uxrPerfGoalSankey',figure=fig)
])
@app.callback(
#    Output('dd-output-container', 'children'),
Output('uxrPerfGoalSankey', 'figure'),
[Input('dataCenter_dropdown', 'value'),
Input('customer_dropdown', 'value'),
Input('companyID_dropdown', 'value')])

def update_graph(dataCenter, customer, companyID):
if dataCenter=='Select all' and customer=='Select all' and companyID=='Select all':
df=dataset.copy()
else:
df = dataset.loc[dataset['Data Center'].isin([dataCenter]) & dataset['Customer'].isin([customer]) & dataset['companyID'].isin([companyID])]

labelListTemp1 = list(set(df.source.values))
labelListTemp2 = list(set(df.target.values))
labelList = labelListTemp1 + labelListTemp2
sankey_node = list(dict.fromkeys(labelList))

fig = go.Figure(data=[go.Sankey( node = dict( pad=15,thickness=20,line = dict(color = "black", width = 0.5),label = labelList,color = "blue" ),
link = dict(source = df.source.apply(lambda x: labelList.index(x)),
target = df.target.apply(lambda x: labelList.index(x)),
value = df.value))])
return fig


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

回调函数返回一个figure,并试图将其分配给html.Divchildren属性。据我所知不能那样做。div的子级应该是错误消息中所述的其他组件、字符串或数字。

你是想写吗

Output('uxrPerfGoalSankey', 'figure'),

相反?

如果没有,并且您需要向该div返回一个新的fig,请在div中创建一个dcc.Graph,并返回该图的fig值。

编辑:

您还可以覆盖回调函数顶部的输入值。无论您选择什么,df最终都会被相同的值过滤。也就是说,你在下拉列表中选择了数据中心"A",但在第一行中,你将数据中心设置为数据帧["数据中心"],那么选择一个数据中心有什么意义呢?如果不是这样,删除那些作业?

顺便说一句,一个迫在眉睫的陷阱是:多个下拉列表通过单个值值列表。为了使你的df选择一致,强制所有输入都是列表:

if not isinstance(dataCenter, list):
dataCenter = [dataCenter]
# etc

编辑2:

问题是如何处理参数列表与单个值以及"全选"的选择。我调整了逻辑,将"无"(dd选择为空(和"全选"视为所选的所有值。如果您不想在选择为空时绘制任何内容,请执行以下操作:

from dash.exceptions import PreventUpdate

然后回调函数中的第一件事:

if dataCenter is None or customer is None or companyID is None:
raise PreventUpdate

总之,这是我描述的带有逻辑的代码:

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objects as go
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)
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
dataset = pd.read_csv('values.csv')

def generate_graph(df):
labels = list(set(df.source.values)) + list(set(df.target.values))
fig = go.Figure(data=[
go.Sankey(node=dict(pad=15, thickness=20, line=dict(color="black", width=0.5), label=labels, color="blue"),
link=dict(source=df.source.apply(lambda x: labels.index(x)),
target=df.target.apply(lambda x: labels.index(x)),
value=df.value))
])
return fig

app.layout = html.Div([
dcc.Dropdown(
id='dataCenter_dropdown',
options=[{'label': i, 'value': i} for i in dataset['Data Center'].unique()] + [
{'label': 'Select all', 'value': 'allID'}],
multi=True, placeholder='Please select Data Center'),
dcc.Dropdown(
id='customer_dropdown',
options=[{'label': i, 'value': i} for i in dataset['Customer'].unique()] + [
{'label': 'Select all', 'value': 'allID'}],
multi=True, placeholder='Please select Customer'),
dcc.Dropdown(
id='companyID_dropdown',
options=[{'label': i, 'value': i} for i in dataset['companyID'].unique()] + [
{'label': 'Select all', 'value': 'allID'}],
multi=True, placeholder='Please select companyID'),
dcc.Graph(id='uxrPerfGoalSankey', figure=generate_graph(dataset))
])

@app.callback(
Output('uxrPerfGoalSankey', 'figure'),
[Input('dataCenter_dropdown', 'value'),
Input('customer_dropdown', 'value'),
Input('companyID_dropdown', 'value')])
def update_graph(dataCenter, customer, companyID):
if dataCenter is None or len(dataCenter) == 0 or 'allID' in dataCenter:
dataCenter = dataset['Data Center']
elif not isinstance(dataCenter, list):
dataCenter = [dataCenter]
if customer is None or len(customer) == 0 or 'allID' in customer:
customer = dataset['Customer']
elif not isinstance(customer, list):
customer = [customer]
if companyID is None or len(companyID) == 0 or 'allID' in companyID:
companyID = dataset['companyID']
elif not isinstance(companyID, list):
companyID = [companyID]
df = dataset[
(dataset['Data Center'].isin(dataCenter)) &
(dataset['Customer'].isin(customer)) &
(dataset['companyID'].isin(companyID))
]
return generate_graph(df)

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

运行对我来说很好,如果出现任何其他问题,请告诉我。

最新更新