幾天來我一直試圖理解這一點。我要求用戶輸入 X_axis 資料、Y_axis 資料和他們想要顯示的圖形。
我當前的版本僅根據用戶的選擇顯示一張圖表。我希望它能夠同時顯示多個圖形(例如:餅圖和折線圖)。我添加了 'multi=True' 以選擇多個圖形(現在注釋掉,因為它給出了錯誤:“回呼錯誤更新 my_graph.figure”,UnboundLocalError:分配之前參考的區域變數 'fig')。我知道我需要從回呼函式創建多個輸出,但我不知道如何。有人可以幫我嗎?謝謝!!
import dash
import dash_core_components as dcc
import dash_html_components as HTML
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
from dash.exceptions import PreventUpdate
df_data = pd.read_json("test.json")
app = dash.Dash(__name__)
app.layout = html.Div([
html.P("Choose data1:"),
dcc.Dropdown(
id='x_axis',
options=[{'value': x, 'label': x}
for x in df_data.keys()],
clearable=False,
style={'width':'40%'}
),
html.P("Choose data2:"),
dcc.Dropdown(
id='y_axis',
options=[{'value': x, 'label': x}
for x in df_data.keys()],
clearable=False,
style={'width':'40%'}
),
html.P("Choose a graph to display:"),
dcc.Dropdown(
id='graph',
options=[{'value': 'pie', 'label': 'Pie chart'},
{'value': 'line', 'label': 'Line chart'},
{'value': 'bar', 'label': 'Bar chart'},
{'value': 'scatter', 'label': 'Scatter chart'},
{'value': '2dhistogram', 'label': '2dhistogram chart'}],
clearable=False,
style={'width':'40%'},
#multi=True
),
dcc.Graph(id='my_graph', figure={}),
])
@app.callback(
Output("my_graph", "figure"),
[Input("x_axis", "value"),
Input("y_axis", "value"),
Input("graph", "value")])
def generate_chart(x_axis, y_axis, graph):
if not x_axis:
raise PreventUpdate
if not y_axis:
raise PreventUpdate
if not graph:
raise PreventUpdate
dff = df_data
if graph=="pie":
fig = px.pie(dff, values=y_axis, names=x_axis, title="Pie Chart")
elif graph=="line":
fig = px.line(dff, x=x_axis, y=y_axis, title="Line Chart")
elif graph=="bar":
fig = px.bar(dff, x=x_axis, y=y_axis, title="Bar Chart")
elif graph=="scatter":
fig = px.scatter(dff, x=x_axis, y=y_axis, title="Scatter Chart")
elif graph=="2dhistogram":
fig = px.density_heatmap(dff, x=x_axis, y=y_axis, nbinsx=20, nbinsy=20,
color_continuous_scale="Viridis", title="2D Histogram Chart")
else:
fig = px.pie(dff, values=y_axis, names=x_axis, title="Pie Chart")
return fig
app.run_server(debug=True)
示例 json 檔案:
{
"Names": {
"0": "Alice",
"1": "Robert",
"2": "Garry",
"3": "Nate",
"4": "Karen",
"5": "Nick"
},
"Address": {
"0": "21 Main St",
"1": "19 Third St",
"2": "4 Church St",
"3": "5 High St",
"4": "9 Elm St",
"5": "06 Washingtom St"
},
"AreaCode": {
"0": "777",
"1": "421",
"2": "768",
"3": "345",
"4": "888",
"5": "123"
}}
uj5u.com熱心網友回復:
您已添加multi=True以從用戶那里獲取多個輸入,但它仍然不會改變該函式僅回傳帶有單個繪圖的圖形物件的事實。
我覺得子圖是解決方案。
你可以像這樣創建子圖
fig = make_subplots(rows=1, cols=len(graph))
counter = 1
然后使用單獨的 if 條件并通過使用計數器添加跟蹤。
if "scatter" in graph:
fig.add_trace(
go.Scatter(x=dff['x_axis'], y=dff['y_axis']),
row=1, col=counter )
counter = 1
if "pie" in graph:
fig.add_trace(
go.Pie(labels=dff['x_axis'], values=dff['y_axis']),
row=1, col=counter )
counter = 1
...
...
...
uj5u.com熱心網友回復:
好吧,您已經接近了,您提供的代碼運行良好,并且正確設定了大多數所需的一切!(我在下面首先展示的一些小事情需要更正)
您的作業代碼原樣 - 一次繪圖
import dash
from dash import dcc
from dash import html
import pandas as pd
import plotly.express as px
from dash.dependencies import Input
from dash.dependencies import Output
from dash.exceptions import PreventUpdate
df_data = pd.read_json("test.json")
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.P("Choose data1:"),
dcc.Dropdown(
id="x_axis",
options=[{"value": x, "label": x} for x in df_data.keys()],
clearable=False,
style={"width": "40%"},
),
html.P("Choose data2:"),
dcc.Dropdown(
id="y_axis",
options=[{"value": x, "label": x} for x in df_data.keys()],
clearable=False,
style={"width": "40%"},
),
html.P("Choose a graph to display:"),
dcc.Dropdown(
id="graph",
options=[
{"value": "pie", "label": "Pie chart"},
{"value": "line", "label": "Line chart"},
{"value": "bar", "label": "Bar chart"},
{"value": "scatter", "label": "Scatter chart"},
{"value": "2dhistogram", "label": "2dhistogram chart"},
],
clearable=False,
style={"width": "40%"},
# multi=True
),
dcc.Graph(id="my_graph", figure={}),
]
)
@app.callback(
Output("my_graph", "figure"),
[
Input("x_axis", "value"),
Input("y_axis", "value"),
Input("graph", "value"),
],
)
def generate_chart(x_axis, y_axis, graph):
if not x_axis:
raise PreventUpdate
if not y_axis:
raise PreventUpdate
if not graph:
raise PreventUpdate
dff = df_data
if graph == "pie":
fig = px.pie(dff, values=y_axis, names=x_axis, title="Pie Chart")
elif graph == "line":
fig = px.line(dff, x=x_axis, y=y_axis, title="Line Chart")
elif graph == "bar":
fig = px.bar(dff, x=x_axis, y=y_axis, title="Bar Chart")
elif graph == "scatter":
fig = px.scatter(dff, x=x_axis, y=y_axis, title="Scatter Chart")
elif graph == "2dhistogram":
fig = px.density_heatmap(
dff,
x=x_axis,
y=y_axis,
nbinsx=20,
nbinsy=20,
color_continuous_scale="Viridis",
title="2D Histogram Chart",
)
else:
fig = px.pie(dff, values=y_axis, names=x_axis, title="Pie Chart")
return fig
app.run_server(debug=True, dev_tools_hot_reload=True)

下拉選項更改:

下拉選項更改和資料 x、y 選項更改:

All I had to change were a couple indentation mistakes, the importing of the dash component library html (lower case not upper), and yeah otherwise it just needed a little fixing as far as proper indentation (which may have just been a copy paste onto SO issue) — great job! Of course it doesn't really make any sense to display pie charts for area codes because they are nominal values, not truly quantitative measurements, but as far as proof of principle goes for making a decently complex interactive Dash web app you set it up all correctly, it seems to me.
But now for the multiple graphs at once...a few more changes will be needed.
Modification of code to implement display of up to 5 possible total graphs
Now this isn't 100% ideal (e.g., it'd be better if no blank graphs were displayed) but hopefully it helps get you on the right track and progressing with the customization of your project ??
import sys
import dash
from dash import dcc
from dash import html
from dash import no_update
import pandas as pd
import plotly.express as px
from dash.dependencies import Input
from dash.dependencies import Output
from dash.exceptions import PreventUpdate
df_data = pd.read_json("test.json")
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.P("Choose data1:"),
dcc.Dropdown(
id="x_axis",
options=[{"value": x, "label": x} for x in df_data.keys()],
clearable=False,
style={"width": "40%"},
),
html.P("Choose data2:"),
dcc.Dropdown(
id="y_axis",
options=[{"value": x, "label": x} for x in df_data.keys()],
clearable=False,
style={"width": "40%"},
),
html.P("Choose a graph to display:"),
dcc.Dropdown(
id="graph",
options=[
{"value": "pie", "label": "Pie chart"},
{"value": "line", "label": "Line chart"},
{"value": "bar", "label": "Bar chart"},
{"value": "scatter", "label": "Scatter chart"},
{"value": "2dhistogram", "label": "2dhistogram chart"},
],
clearable=True,
style={"width": "40%"},
multi=True,
),
dcc.Graph(id="my_graph_1", figure={}),
dcc.Graph(id="my_graph_2", figure={}),
dcc.Graph(id="my_graph_3", figure={}),
dcc.Graph(id="my_graph_4", figure={}),
dcc.Graph(id="my_graph_5", figure={}),
]
)
@app.callback(
[
Output("my_graph_1", "figure"),
Output("my_graph_2", "figure"),
Output("my_graph_3", "figure"),
Output("my_graph_4", "figure"),
Output("my_graph_5", "figure"),
],
[
Input("x_axis", "value"),
Input("y_axis", "value"),
Input("graph", "value"),
],
)
def generate_chart(x_axis, y_axis, graph):
if not all([x_axis, y_axis]):
raise PreventUpdate
if not graph:
return [{}] * 5
dff = df_data
graphs = []
print(graph, file=sys.stderr) # used for debugging help
if "pie" in graph:
fig = px.pie(dff, values=y_axis, names=x_axis, title="Pie Chart")
graphs.append(fig)
if "line" in graph:
fig = px.line(dff, x=x_axis, y=y_axis, title="Line Chart")
graphs.append(fig)
if "bar" in graph:
fig = px.bar(dff, x=x_axis, y=y_axis, title="Bar Chart")
graphs.append(fig)
if "scatter" in graph:
fig = px.scatter(dff, x=x_axis, y=y_axis, title="Scatter Chart")
graphs.append(fig)
if "2dhistogram" in graph:
fig = px.density_heatmap(
dff,
x=x_axis,
y=y_axis,
nbinsx=20,
nbinsy=20,
color_continuous_scale="Viridis",
title="2D Histogram Chart",
)
graphs.append(fig)
graphs = (5 - len(graphs)) * [{}] # or can use `[no_update]` here
g1, g2, g3, g4, g5 = graphs
return g1, g2, g3, g4, g5
app.run_server(debug=True, dev_tools_hot_reload=True)
Let me know if you have any questions about what I did — I think it's pretty self-explanatory from the code itself (I basically just made four more graph objects in the layout, and return 5 graphs in the callback -- if a user hasn't chosen all five options, then the difference between the number of dropdown options chosen and total graphs possible (five) is returned as "no_update"'s. I switched the clearable parameter of the dcc.Dropdown to true, and this allows graphs to disappear. Just eliminating an option after having chosen it wont eliminate that graph (it just results in a no_update being sent), but if you clear all with the "x" mark in the dropdown, then you can erase all graphs and start over with new options. As I'm sure you're aware, not all possible options for "data1" and "data2" result in possible graphs.

→ Use red "x" shown below to clear all:

resulting in ability to try out different options graph(s) combos:

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/329216.html
