如何正确地为 Dash 网络应用程序执行回调和函数
How to properly do a callback and function for Dash web app
非常感谢有关如何为我的 Dash 网络应用程序进行正确回调的帮助。我在下面有以下代码。它应该是 return 一张图表,其中包含关于股票财务状况的各种线条。它从 API 中获取数据。但我不确定如何为应用程序回调定义我的函数。我试过按照在线教程进行操作,但都取得了成功。如果它太混乱或效率低下,我深表歉意,我是新手。
'''
#!/usr/bin/env python
import pandas as pd
import requests
import json
import plotly
import chart_studio.plotly as py
import plotly.graph_objs as go
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input
ticker = input("Insert company ticker: ")
qoy = input("QUARTERLY or YEARLY: ")
if qoy == "Yearly" or qoy == "yearly" or qoy == "YEARLY":
IS = requests.get("https://financialmodelingprep.com/api/v3/financials/income-statement/" + ticker)
elif qoy == "Quarterly" or qoy == "quarterly" or qoy == "QUARTERLY":
IS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/income-statement/" + ticker + "?period=quarter")
IS = IS.json()
IS = IS['financials']
IS = pd.DataFrame.from_dict(IS)
IS = IS.set_index("date")
if qoy == "Yearly" or qoy == "yearly" or qoy == "YEARLY":
BS = requests.get("https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/" + ticker)
elif qoy == "Quarterly" or qoy == "quarterly" or qoy == "QUARTERLY":
BS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/" + ticker + "?period=quarter")
BS = BS.json()
BS = BS['financials']
BS = pd.DataFrame.from_dict(BS)
BS = BS.set_index("date")
if qoy == "Yearly" or qoy == "yearly" or qoy == "YEARLY":
CF = requests.get("https://financialmodelingprep.com/api/v3/financials/cash-flow-statement/" + ticker)
elif qoy == "Quarterly" or qoy == "quarterly" or qoy == "QUARTERLY":
CF = requests.get(
"https://financialmodelingprep.com/api/v3/financials/cash-flow-statement/" + ticker + "?period=quarter")
CF = CF.json()
CF = CF['financials']
CF = pd.DataFrame.from_dict(CF)
CF = CF.set_index("date")
df_FS = pd.concat([IS, BS, CF], axis=1, sort=True)
Date = df_FS.index
df_FS.fillna(0, inplace=True)
print(df_FS)
from plotly.subplots import make_subplots
# EARNINGS & REVENUE
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Scatter(x=Date, y=df_FS['Revenue'],
mode='lines+markers',
name='Revenue'), secondary_y=False, )
fig.add_trace(go.Bar(x=Date, y=df_FS['Profit Margin'],
opacity=0.2,
name='Profit Margin'), secondary_y=True, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Consolidated Income'],
mode='lines+markers',
name='Earnings'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Operating Cash Flow'],
mode='lines+markers',
name='Operating Cash Flow'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Free Cash Flow'],
mode='lines+markers',
name='Free Cash Flow'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Operating Expenses'],
mode='lines+markers',
name='Operating Expenses'), secondary_y=False, )
fig.update_layout(title="EARNINGS & REVENUE", barmode='group', hovermode='x')
fig.update_yaxes(title_text="in USD", secondary_y=False)
fig.update_yaxes(title_text="Profit Margin", secondary_y=True)
fig.update_xaxes(rangeslider_visible=True)
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
# Input the stock ticker
html.Div([
dcc.Input(id="stock-input", value=ticker, type="text"),
dcc.RadioItems(
id="quarterlyoryearly",
options=[
{'label': 'Quarterly', 'value': 'quarterly'},
{'label': 'Yearly', 'value': 'yearly'}
],
value=qoy
)
]),
# Banner of app
html.Div([
html.H2("Stock App")
], className="banner"),
# Graphs
html.Div([
# Earnings & Revenue Graph
html.Div([
dcc.Graph(
id="Earnings & Revenue",
figure=fig
)
], className="six columns"),
], className="row")
])
app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"})
@app.callback(dash.dependencies.Output("Earnings & Revenue","figure"),
[dash.dependencies.Input("stock-input","value"),
dash.dependencies.Input("quarterlyoryearly","value")]
)
#def update_fig(ticker,qoy):
if __name__ == '__main__':
app.run_server(debug=False)
'''
您必须在回调中执行所有数据处理,因为它们需要输入和按钮值。根据您希望应用程序如何响应输入,有多种方法可以解决此问题。一种方法是这样的。在这里,主要输入是 qoy
,回调使用 stock input
的状态。因此,在您选择 qoy
之前,输入股票不会更新应用程序。
#!/usr/bin/env python
from plotly.subplots import make_subplots
import pandas as pd
import requests
import json
import plotly
import chart_studio.plotly as py
import plotly.graph_objs as go
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input, State
from dash.exceptions import PreventUpdate
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
# Input the stock ticker
html.Div([
dcc.Input(id="stock-input",
placeholder='Please insert stock', type="text"),
dcc.RadioItems(
id="quarterlyoryearly",
options=[
{'label': 'Quarterly', 'value': 'quarterly'},
{'label': 'Yearly', 'value': 'yearly'}
]
)
]),
# Banner of app
html.Div([
html.H2("Stock App")
], className="banner"),
# Graphs
html.Div([
# Earnings & Revenue Graph
html.Div([
dcc.Graph(
id="Earnings & Revenue",
# figure=fig
)
], className="six columns"),
], className="row")
])
@app.callback(Output("quarterlyoryearly", "value"),
[Input("stock-input", "n_submit")],
[State("quarterlyoryearly", "value")])
def enter_key(n_sub, qoy):
if n_sub:
return qoy
@app.callback(dash.dependencies.Output("Earnings & Revenue", "figure"),
[dash.dependencies.Input("quarterlyoryearly", "value")],
[dash.dependencies.State("stock-input", "value")]
)
def update_fig(*args):
if not any(args):
raise PreventUpdate
else:
qoy, ticker = args
if qoy.lower() == "yearly":
IS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/income-statement/" + ticker)
elif qoy.lower() == "quarterly":
IS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/income-statement/" + ticker + "?period=quarter")
IS = IS.json()
IS = IS['financials']
IS = pd.DataFrame.from_dict(IS)
IS = IS.set_index("date")
if qoy == "Yearly" or qoy == "yearly" or qoy == "YEARLY":
BS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/" + ticker)
elif qoy == "Quarterly" or qoy == "quarterly" or qoy == "QUARTERLY":
BS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/" + ticker + "?period=quarter")
BS = BS.json()
BS = BS['financials']
BS = pd.DataFrame.from_dict(BS)
BS = BS.set_index("date")
if qoy == "Yearly" or qoy == "yearly" or qoy == "YEARLY":
CF = requests.get(
"https://financialmodelingprep.com/api/v3/financials/cash-flow-statement/" + ticker)
elif qoy == "Quarterly" or qoy == "quarterly" or qoy == "QUARTERLY":
CF = requests.get(
"https://financialmodelingprep.com/api/v3/financials/cash-flow-statement/" + ticker + "?period=quarter")
CF = CF.json()
CF = CF['financials']
CF = pd.DataFrame.from_dict(CF)
CF = CF.set_index("date")
df_FS = pd.concat([IS, BS, CF], axis=1, sort=True)
Date = df_FS.index
df_FS.fillna(0, inplace=True)
# EARNINGS & REVENUE
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Scatter(x=Date, y=df_FS['Revenue'],
mode='lines+markers',
name='Revenue'), secondary_y=False, )
fig.add_trace(go.Bar(x=Date, y=df_FS['Profit Margin'],
opacity=0.2,
name='Profit Margin'), secondary_y=True, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Consolidated Income'],
mode='lines+markers',
name='Earnings'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Operating Cash Flow'],
mode='lines+markers',
name='Operating Cash Flow'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Free Cash Flow'],
mode='lines+markers',
name='Free Cash Flow'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Operating Expenses'],
mode='lines+markers',
name='Operating Expenses'), secondary_y=False, )
fig.update_layout(title="EARNINGS & REVENUE",
barmode='group', hovermode='x')
fig.update_yaxes(title_text="in USD", secondary_y=False)
fig.update_yaxes(title_text="Profit Margin", secondary_y=True)
fig.update_xaxes(rangeslider_visible=True)
return fig
if __name__ == '__main__':
app.run_server(debug=False)
您可以尝试输入和状态选项,看看应用程序如何响应。干杯!
PS:我添加了另一个回调,因此在第一个 qoy
和 ticker
值之后,您只需在输入字段中更改 ticker
并点击回车按钮(因为 qoy
已经被选中) 更新您的应用程序。希望这能让您更深入地了解回调的工作原理。
非常感谢有关如何为我的 Dash 网络应用程序进行正确回调的帮助。我在下面有以下代码。它应该是 return 一张图表,其中包含关于股票财务状况的各种线条。它从 API 中获取数据。但我不确定如何为应用程序回调定义我的函数。我试过按照在线教程进行操作,但都取得了成功。如果它太混乱或效率低下,我深表歉意,我是新手。
'''
#!/usr/bin/env python
import pandas as pd
import requests
import json
import plotly
import chart_studio.plotly as py
import plotly.graph_objs as go
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input
ticker = input("Insert company ticker: ")
qoy = input("QUARTERLY or YEARLY: ")
if qoy == "Yearly" or qoy == "yearly" or qoy == "YEARLY":
IS = requests.get("https://financialmodelingprep.com/api/v3/financials/income-statement/" + ticker)
elif qoy == "Quarterly" or qoy == "quarterly" or qoy == "QUARTERLY":
IS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/income-statement/" + ticker + "?period=quarter")
IS = IS.json()
IS = IS['financials']
IS = pd.DataFrame.from_dict(IS)
IS = IS.set_index("date")
if qoy == "Yearly" or qoy == "yearly" or qoy == "YEARLY":
BS = requests.get("https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/" + ticker)
elif qoy == "Quarterly" or qoy == "quarterly" or qoy == "QUARTERLY":
BS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/" + ticker + "?period=quarter")
BS = BS.json()
BS = BS['financials']
BS = pd.DataFrame.from_dict(BS)
BS = BS.set_index("date")
if qoy == "Yearly" or qoy == "yearly" or qoy == "YEARLY":
CF = requests.get("https://financialmodelingprep.com/api/v3/financials/cash-flow-statement/" + ticker)
elif qoy == "Quarterly" or qoy == "quarterly" or qoy == "QUARTERLY":
CF = requests.get(
"https://financialmodelingprep.com/api/v3/financials/cash-flow-statement/" + ticker + "?period=quarter")
CF = CF.json()
CF = CF['financials']
CF = pd.DataFrame.from_dict(CF)
CF = CF.set_index("date")
df_FS = pd.concat([IS, BS, CF], axis=1, sort=True)
Date = df_FS.index
df_FS.fillna(0, inplace=True)
print(df_FS)
from plotly.subplots import make_subplots
# EARNINGS & REVENUE
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Scatter(x=Date, y=df_FS['Revenue'],
mode='lines+markers',
name='Revenue'), secondary_y=False, )
fig.add_trace(go.Bar(x=Date, y=df_FS['Profit Margin'],
opacity=0.2,
name='Profit Margin'), secondary_y=True, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Consolidated Income'],
mode='lines+markers',
name='Earnings'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Operating Cash Flow'],
mode='lines+markers',
name='Operating Cash Flow'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Free Cash Flow'],
mode='lines+markers',
name='Free Cash Flow'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Operating Expenses'],
mode='lines+markers',
name='Operating Expenses'), secondary_y=False, )
fig.update_layout(title="EARNINGS & REVENUE", barmode='group', hovermode='x')
fig.update_yaxes(title_text="in USD", secondary_y=False)
fig.update_yaxes(title_text="Profit Margin", secondary_y=True)
fig.update_xaxes(rangeslider_visible=True)
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
# Input the stock ticker
html.Div([
dcc.Input(id="stock-input", value=ticker, type="text"),
dcc.RadioItems(
id="quarterlyoryearly",
options=[
{'label': 'Quarterly', 'value': 'quarterly'},
{'label': 'Yearly', 'value': 'yearly'}
],
value=qoy
)
]),
# Banner of app
html.Div([
html.H2("Stock App")
], className="banner"),
# Graphs
html.Div([
# Earnings & Revenue Graph
html.Div([
dcc.Graph(
id="Earnings & Revenue",
figure=fig
)
], className="six columns"),
], className="row")
])
app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"})
@app.callback(dash.dependencies.Output("Earnings & Revenue","figure"),
[dash.dependencies.Input("stock-input","value"),
dash.dependencies.Input("quarterlyoryearly","value")]
)
#def update_fig(ticker,qoy):
if __name__ == '__main__':
app.run_server(debug=False)
'''
您必须在回调中执行所有数据处理,因为它们需要输入和按钮值。根据您希望应用程序如何响应输入,有多种方法可以解决此问题。一种方法是这样的。在这里,主要输入是 qoy
,回调使用 stock input
的状态。因此,在您选择 qoy
之前,输入股票不会更新应用程序。
#!/usr/bin/env python
from plotly.subplots import make_subplots
import pandas as pd
import requests
import json
import plotly
import chart_studio.plotly as py
import plotly.graph_objs as go
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input, State
from dash.exceptions import PreventUpdate
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
# Input the stock ticker
html.Div([
dcc.Input(id="stock-input",
placeholder='Please insert stock', type="text"),
dcc.RadioItems(
id="quarterlyoryearly",
options=[
{'label': 'Quarterly', 'value': 'quarterly'},
{'label': 'Yearly', 'value': 'yearly'}
]
)
]),
# Banner of app
html.Div([
html.H2("Stock App")
], className="banner"),
# Graphs
html.Div([
# Earnings & Revenue Graph
html.Div([
dcc.Graph(
id="Earnings & Revenue",
# figure=fig
)
], className="six columns"),
], className="row")
])
@app.callback(Output("quarterlyoryearly", "value"),
[Input("stock-input", "n_submit")],
[State("quarterlyoryearly", "value")])
def enter_key(n_sub, qoy):
if n_sub:
return qoy
@app.callback(dash.dependencies.Output("Earnings & Revenue", "figure"),
[dash.dependencies.Input("quarterlyoryearly", "value")],
[dash.dependencies.State("stock-input", "value")]
)
def update_fig(*args):
if not any(args):
raise PreventUpdate
else:
qoy, ticker = args
if qoy.lower() == "yearly":
IS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/income-statement/" + ticker)
elif qoy.lower() == "quarterly":
IS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/income-statement/" + ticker + "?period=quarter")
IS = IS.json()
IS = IS['financials']
IS = pd.DataFrame.from_dict(IS)
IS = IS.set_index("date")
if qoy == "Yearly" or qoy == "yearly" or qoy == "YEARLY":
BS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/" + ticker)
elif qoy == "Quarterly" or qoy == "quarterly" or qoy == "QUARTERLY":
BS = requests.get(
"https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/" + ticker + "?period=quarter")
BS = BS.json()
BS = BS['financials']
BS = pd.DataFrame.from_dict(BS)
BS = BS.set_index("date")
if qoy == "Yearly" or qoy == "yearly" or qoy == "YEARLY":
CF = requests.get(
"https://financialmodelingprep.com/api/v3/financials/cash-flow-statement/" + ticker)
elif qoy == "Quarterly" or qoy == "quarterly" or qoy == "QUARTERLY":
CF = requests.get(
"https://financialmodelingprep.com/api/v3/financials/cash-flow-statement/" + ticker + "?period=quarter")
CF = CF.json()
CF = CF['financials']
CF = pd.DataFrame.from_dict(CF)
CF = CF.set_index("date")
df_FS = pd.concat([IS, BS, CF], axis=1, sort=True)
Date = df_FS.index
df_FS.fillna(0, inplace=True)
# EARNINGS & REVENUE
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Scatter(x=Date, y=df_FS['Revenue'],
mode='lines+markers',
name='Revenue'), secondary_y=False, )
fig.add_trace(go.Bar(x=Date, y=df_FS['Profit Margin'],
opacity=0.2,
name='Profit Margin'), secondary_y=True, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Consolidated Income'],
mode='lines+markers',
name='Earnings'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Operating Cash Flow'],
mode='lines+markers',
name='Operating Cash Flow'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Free Cash Flow'],
mode='lines+markers',
name='Free Cash Flow'), secondary_y=False, )
fig.add_trace(go.Scatter(x=Date, y=df_FS['Operating Expenses'],
mode='lines+markers',
name='Operating Expenses'), secondary_y=False, )
fig.update_layout(title="EARNINGS & REVENUE",
barmode='group', hovermode='x')
fig.update_yaxes(title_text="in USD", secondary_y=False)
fig.update_yaxes(title_text="Profit Margin", secondary_y=True)
fig.update_xaxes(rangeslider_visible=True)
return fig
if __name__ == '__main__':
app.run_server(debug=False)
您可以尝试输入和状态选项,看看应用程序如何响应。干杯!
PS:我添加了另一个回调,因此在第一个 qoy
和 ticker
值之后,您只需在输入字段中更改 ticker
并点击回车按钮(因为 qoy
已经被选中) 更新您的应用程序。希望这能让您更深入地了解回调的工作原理。