[英]Plotly: How to display graph after clicking a button?
我想使用 plotly 僅在單擊按鈕后顯示圖形,但不確定如何使其工作。 我的圖存儲在以下代碼位中
fig1 = go.Figure(data=plot_data, layout=plot_layout)
然后我使用以下代碼位定義我的應用程序布局:
app.layout = html.Div([
#button
html.Div(className='submit', children=[
html.Button('Forecast', id='submit', n_clicks=0)
]),
#loading
dcc.Loading(
id="loading-1",
type="default",
children=html.Div(id="loading-output-1")
),
#graph
dcc.Graph(id= 'mpg-scatter',figure=fig),
#hoverdata
html.Div([
dcc.Markdown(id='hoverdata-text')
],style={'width':'50%','display':'inline-block'})
])
@app.callback(Output('hoverdata-text','children'),
[Input('mpg-scatter','hoverData')])
def callback_stats(hoverData):
return str(hoverData)
if __name__ == '__main__':
app.run_server()
但問題是我只想首先顯示按鈕。 然后當有人點擊預測按鈕時,加載功能出現,一秒鍾后圖表顯示。 我定義了一個 dcc.loading 組件,但不確定如何定義此功能的回調。
dcc.Store()
和dcc.Loading
這個建議使用一個dcc.Store()組件、一個html.Button()和一個dcc.Loading組件來生成我現在理解的所需設置:
啟動后,該應用程序將如下所示:
現在,您可以單擊一次Figures
以獲取下面的Figure 1
,但前提是享受以下加載圖標之一: ['graph', 'cube', 'circle', 'dot', or 'default']
其中'dot'
會觸發 ptsd,而'cube'
恰好是我的最愛:
現在您可以繼續單擊Figure 2
和Figure 3
。 我已將Figure 1
的加載時間設置為不少於 5 秒,然后為Figure 2
和Figure 3
為 2 秒。 但是你可以很容易地改變它。
當您單擊超過 3 次時,我們將重新從頭開始:
我希望我終於找到了您真正想要的解決方案。 以下代碼片段中的設置建立在此處描述的設置的基礎上,但已進行調整以希望滿足您的需要。 讓我知道這對你有什么作用!
import pandas as pd
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
import dash_table
from dash.exceptions import PreventUpdate
import dash_bootstrap_components as dbc
import time
time.sleep(5) # Delay for 5 seconds.
global_df = pd.DataFrame({'value1':[1,2,3,4],
'value2':[10,11,12,14]})
# app = JupyterDash(__name__)
app = JupyterDash(external_stylesheets=[dbc.themes.SLATE])
df = pd.DataFrame({'Value 1': [1,2,3],
'Value 2':[10,11,12],
'Value 3':[14,12,9]})
df.set_index('Value 1', inplace = True)
app.layout = html.Div([
# The memory store reverts to the default on every page refresh
dcc.Store(id='memory'),
# The local store will take the initial data
# only the first time the page is loaded
# and keep it until it is cleared.
# Same as the local store but will lose the data
# when the browser/tab closes.
html.Table([
html.Thead([
html.Tr(html.Th('Click to launch figure:')),
html.Tr([
html.Th(html.Button('Figures', id='memory-button')),
]),
]),
]),
dcc.Loading(id = "loading-icon",
#'graph', 'cube', 'circle', 'dot', or 'default'
type = 'cube',
children=[html.Div(dcc.Graph(id='click_graph'))])
])
# Create two callbacks for every store.
# add a click to the appropriate store.
@app.callback(Output('memory', 'data'),
[Input('memory-button', 'n_clicks')],
[State('memory', 'data')])
def on_click(n_clicks, data):
if n_clicks is None:
# prevent the None callbacks is important with the store component.
# you don't want to update the store for nothing.
raise PreventUpdate
# Give a default data dict with 0 clicks if there's no data.
data = data or {'clicks': 0}
data['clicks'] = data['clicks'] + 1
if data['clicks'] > 3: data['clicks'] = 0
return data
# output the stored clicks in the table cell.
@app.callback(Output('click_graph', 'figure'),
# Since we use the data prop in an output,
# we cannot get the initial data on load with the data prop.
# To counter this, you can use the modified_timestamp
# as Input and the data as State.
# This limitation is due to the initial None callbacks
# https://github.com/plotly/dash-renderer/pull/81
[Input('memory', 'modified_timestamp')],
[State('memory', 'data')])
def on_data(ts, data):
if ts is None:
#raise PreventUpdate
fig = go.Figure()
fig.update_layout(plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)',
yaxis = dict(showgrid=False, zeroline=False, tickfont = dict(color = 'rgba(0,0,0,0)')),
xaxis = dict(showgrid=False, zeroline=False, tickfont = dict(color = 'rgba(0,0,0,0)')))
return(fig)
data = data or {}
0
# plotly
y = 'Value 2'
y2 = 'Value 3'
fig = go.Figure()
fig.update_layout(plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)',
yaxis = dict(showgrid=False, zeroline=False, tickfont = dict(color = 'rgba(0,0,0,0)')),
xaxis = dict(showgrid=False, zeroline=False, tickfont = dict(color = 'rgba(0,0,0,0)')))
if data.get('clicks', 0) == 1:
fig = go.Figure(go.Scatter(name=y, x=df.index, y=df[y], mode = 'lines'))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode = 'lines'))
fig.update_layout(template='plotly_dark',
title = 'Plot number ' + str(data.get('clicks', 0)))
# delay only after first click
time.sleep(2)
if data.get('clicks', 0) == 2:
fig = go.Figure((go.Scatter(name=y, x=df.index, y=df[y], mode = 'lines')))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode = 'lines'))
fig.update_layout(template='seaborn',
title = 'Plot number ' + str(data.get('clicks', 0)))
if data.get('clicks', 0) == 3:
fig = go.Figure((go.Scatter(name=y, x=df.index, y=df[y], mode = 'lines')))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode = 'lines'))
fig.update_layout(template='plotly_white',
title = 'Plot number ' + str(data.get('clicks', 0)))
# Aesthetics
fig.update_layout(margin= {'t':30, 'b':0, 'r': 50, 'l': 50, 'pad': 0},
hovermode = 'x',
legend=dict(x=1,y=0.85),
uirevision='constant')
# delay for every figure
time.sleep(2)
return fig
app.run_server(mode='external', port = 8070, dev_tools_ui=True,
dev_tools_hot_reload =True, threaded=True)
經過一些交流,我們現在知道您想要:
我做了一個新的設置,應該滿足上述所有標准。 起初,只顯示控制選項。 然后您可以選擇要顯示的圖形: Fig1, Fig2 or Fig3
。 對我來說,如果您必須循環瀏覽圖形以選擇要顯示的圖形,這似乎是一個非最佳的用戶界面。 所以我選擇了這樣的單選按鈕:
現在您可以自由選擇要顯示的圖形,或返回不顯示任何內容,如下所示:
None
時顯示:Figure 1
被選中 您仍未提供數據樣本,因此我仍在使用Suggestion 1
合成數據,而是讓不同的布局指示顯示的是哪個圖。 我希望這適合您的需求,因為您似乎希望為不同的圖形使用不同的布局。
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, ClientsideFunction
import dash_bootstrap_components as dbc
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output
import numpy as np
from plotly.subplots import make_subplots
import plotly.express as px
pd.options.plotting.backend = "plotly"
from datetime import datetime
palette = px.colors.qualitative.Plotly
# sample data
df = pd.DataFrame({'Prices': [1,10,7,5, np.nan, np.nan, np.nan],
'Predicted_prices':[np.nan, np.nan, np.nan, 5, 8,6,9]})
# app setup
app = JupyterDash(external_stylesheets=[dbc.themes.SLATE])
# controls
controls = dbc.Card(
[dbc.FormGroup(
[
dbc.Label("Options"),
dcc.RadioItems(id="display_figure",
options=[ {'label': 'None', 'value': 'Nope'},
{'label': 'Figure 1', 'value': 'Figure1'},
{'label': 'Figure 2', 'value': 'Figure2'},
{'label': 'Figure 3', 'value': 'Figure3'}
],
value='Nope',
labelStyle={'display': 'inline-block', 'width': '10em', 'line-height':'0.5em'}
)
],
),
dbc.FormGroup(
[dbc.Label(""),]
),
],
body=True,
style = {'font-size': 'large'})
app.layout = dbc.Container(
[
html.H1("Button for predictions"),
html.Hr(),
dbc.Row([
dbc.Col([controls],xs = 4),
dbc.Col([
dbc.Row([
dbc.Col(dcc.Graph(id="predictions")),
])
]),
]),
html.Br(),
dbc.Row([
]),
],
fluid=True,
)
@app.callback(
Output("predictions", "figure"),
[Input("display_figure", "value"),
],
)
def make_graph(display_figure):
# main trace
y = 'Prices'
y2 = 'Predicted_prices'
# print(display_figure)
if 'Nope' in display_figure:
fig = go.Figure()
fig.update_layout(plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)',
yaxis = dict(showgrid=False, zeroline=False, tickfont = dict(color = 'rgba(0,0,0,0)')),
xaxis = dict(showgrid=False, zeroline=False, tickfont = dict(color = 'rgba(0,0,0,0)')))
return fig
if 'Figure1' in display_figure:
fig = go.Figure(go.Scatter(name=y, x=df.index, y=df[y], mode = 'lines'))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode = 'lines'))
fig.update_layout(template='plotly_dark')
# prediction trace
if 'Figure2' in display_figure:
fig = go.Figure((go.Scatter(name=y, x=df.index, y=df[y], mode = 'lines')))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode = 'lines'))
fig.update_layout(template='seaborn')
if 'Figure3' in display_figure:
fig = go.Figure((go.Scatter(name=y, x=df.index, y=df[y], mode = 'lines')))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode = 'lines'))
fig.update_layout(template='plotly_white')
# Aesthetics
fig.update_layout(margin= {'t':30, 'b':0, 'r': 0, 'l': 0, 'pad': 0})
fig.update_layout(hovermode = 'x')
fig.update_layout(showlegend=True, legend=dict(x=1,y=0.85))
fig.update_layout(uirevision='constant')
fig.update_layout(title = "Prices and predictions")
return(fig)
app.run_server(mode='external', port = 8005)
該建議將直接側重於:
我想使用 plotly 僅在單擊按鈕后顯示圖形
這意味着我不認為dcc.Loading()
必須是答案的一部分。
我發現dcc.Checklist()
是一個非常通用且用戶友好的組件。 如果設置正確,它將顯示為必須單擊的按鈕(或必須標記的選項)才能觸發某些功能或可視化。
這是一個基本設置:
dcc.Checklist(
id="display_columns",
options=[{"label": col + ' ', "value": col} for col in df.columns],
value=[df.columns[0]],
labelStyle={'display': 'inline-block', 'width': '12em', 'line-height':'0.5em'}
這是它的樣子:
除了以下幾行之外, dcc.Checklist()
組件將允許您根據需要打開和關閉Prediction
跟蹤。
# main trace
y = 'Prices'
fig = make_subplots(specs=[[{"secondary_y": True}]])
if 'Prices' in display_columns:
fig.add_trace(go.Scatter(name=y, x=df.index, y=df[y], mode = 'lines'), secondary_y=False)
# prediction trace
if 'Predicted_prices' in display_columns:
fig.add_trace(go.Scatter(name = 'predictions', x=df.index, y=df['Predicted_prices'], mode = 'lines'), secondary_y=False
除此之外,如果您想進一步擴展此示例,此設置將讓您輕松處理多個跟蹤的多個預測。 試一試,讓我知道它對你有用。 如果有什么不清楚的,那么我們可以在您找到時間時深入了解細節。
以下是應用程序在啟用和不啟用預測的情況下的外觀:
離開
在
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, ClientsideFunction
import dash_bootstrap_components as dbc
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output
import numpy as np
from plotly.subplots import make_subplots
import plotly.express as px
pd.options.plotting.backend = "plotly"
from datetime import datetime
palette = px.colors.qualitative.Plotly
# sample data
df = pd.DataFrame({'Prices': [1,10,7,5, np.nan, np.nan, np.nan],
'Predicted_prices':[np.nan, np.nan, np.nan, 5, 8,6,9]})
# app setup
app = JupyterDash(external_stylesheets=[dbc.themes.SLATE])
# input controls
controls = dbc.Card(
[dbc.FormGroup(
[
dbc.Label("Options"),
dcc.Checklist(
id="display_columns",
options=[{"label": col + ' ', "value": col} for col in df.columns],
value=[df.columns[0]],
labelStyle={'display': 'inline-block', 'width': '12em', 'line-height':'0.5em'}
#clearable=False,
#multi = True
),
],
),
dbc.FormGroup(
[dbc.Label(""),]
),
],
body=True,
style = {'font-size': 'large'})
app.layout = dbc.Container(
[
html.H1("Button for predictions"),
html.Hr(),
dbc.Row([
dbc.Col([controls],xs = 4),
dbc.Col([
dbc.Row([
dbc.Col(dcc.Graph(id="predictions")),
])
]),
]),
html.Br(),
dbc.Row([
]),
],
fluid=True,
)
@app.callback(
Output("predictions", "figure"),
[Input("display_columns", "value"),
],
)
def make_graph(display_columns):
# main trace
y = 'Prices'
fig = make_subplots(specs=[[{"secondary_y": True}]])
if 'Prices' in display_columns:
fig.add_trace(go.Scatter(name=y, x=df.index, y=df[y], mode = 'lines'), secondary_y=False)
# prediction trace
if 'Predicted_prices' in display_columns:
fig.add_trace(go.Scatter(name = 'predictions', x=df.index, y=df['Predicted_prices'], mode = 'lines'), secondary_y=False)
# Aesthetics
fig.update_layout(margin= {'t':30, 'b':0, 'r': 0, 'l': 0, 'pad': 0})
fig.update_layout(hovermode = 'x')
fig.update_layout(showlegend=True, legend=dict(x=1,y=0.85))
fig.update_layout(uirevision='constant')
fig.update_layout(template='plotly_dark',
plot_bgcolor='#272B30',
paper_bgcolor='#272B30')
fig.update_layout(title = "Prices and predictions")
return(fig)
app.run_server(mode='external', port = 8005)
我正在尋找一個非常相似的解決方案,我嘗試了您的建議 2。因為我想根據用戶對單擊按鈕的選擇來顯示圖像。 我在一個目錄下有 image_1、image_2、image_3 和 image_4。 我想更新您的解決方案並顯示圖像。 到目前為止,我已經嘗試過如下所示。 但由於錯誤無法繼續,因為這是我第一次嘗試使用 plotly 和 dash 以及初學者。 謝謝。
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output
import numpy as np
from plotly.subplots import make_subplots
import plotly.express as px
pd.options.plotting.backend = "plotly"
from datetime import datetime
palette = px.colors.qualitative.Plotly
# sample data
df = pd.DataFrame({'Prices': [1, 10, 7, 5, np.nan, np.nan, np.nan],
'Predicted_prices': [np.nan, np.nan, np.nan, 5, 8, 6, 9]})
# app setup
app = dash.Dash()
# controls
controls = dcc.Card(
[dcc.FormGroup(
[
dcc.Label("Options"),
dcc.RadioItems(id="display_figure",
options=[{'label': 'None', 'value': 'Nope'},
{'label': 'Figure 1', 'value': 'Figure1'},
{'label': 'Figure 2', 'value': 'Figure2'},
{'label': 'Figure 3', 'value': 'Figure3'}
],
value='Nope',
labelStyle={'display': 'inline-block', 'width': '10em', 'line-height': '0.5em'}
)
],
),
dcc.FormGroup(
[dcc.Label(""), ]
),
],
body=True,
style={'font-size': 'large'})
app.layout = dcc.Container(
[
html.H1("Button for predictions"),
html.Hr(),
dcc.Row([
dcc.Col([controls], xs=4),
dcc.Col([
dcc.Row([
dcc.Col(dcc.Graph(id="predictions")),
])
]),
]),
html.Br(),
dcc.Row([
]),
],
fluid=True,
)
@app.callback(
Output("predictions", "figure"),
[Input("display_figure", "value"),
],
)
def make_graph(display_figure):
# main trace
y = 'Prices'
y2 = 'Predicted_prices'
# print(display_figure)
if 'Nope' in display_figure:
fig = go.Figure()
fig.update_layout(plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)',
yaxis=dict(showgrid=False, zeroline=False, tickfont=dict(color='rgba(0,0,0,0)')),
xaxis=dict(showgrid=False, zeroline=False, tickfont=dict(color='rgba(0,0,0,0)')))
return fig
if 'Figure1' in display_figure:
fig = go.Figure(go.Scatter(name=y, x=df.index, y=df[y], mode='lines'))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode='lines'))
fig.update_layout(template='plotly_dark')
# prediction trace
if 'Figure2' in display_figure:
fig = go.Figure((go.Scatter(name=y, x=df.index, y=df[y], mode='lines')))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode='lines'))
fig.update_layout(template='seaborn')
if 'Figure3' in display_figure:
fig = go.Figure((go.Scatter(name=y, x=df.index, y=df[y], mode='lines')))
fig.add_traces(go.Scatter(name=y, x=df.index, y=df[y2], mode='lines'))
fig.update_layout(template='plotly_white')
# Aesthetics
fig.update_layout(margin={'t': 30, 'b': 0, 'r': 0, 'l': 0, 'pad': 0})
fig.update_layout(hovermode='x')
fig.update_layout(showlegend=True, legend=dict(x=1, y=0.85))
fig.update_layout(uirevision='constant')
fig.update_layout(title="Prices and predictions")
return (fig)
app.run_server(debug=True)
錯誤如下:第 24 行,在控件中 = dcc.Card( AttributeError: module 'dash_core_components' 沒有屬性 'Card'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.