ValueError: Invalid property specified for object of type plotly.graph_objs.Scatter: ‘y1
Python code
«»»import dash
import sqlite3
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go
from collections import deque
import pandas as pd
import pyodbc
def connectSQLServer():
connSQLServer = sqlite3.connect(‘/home/pi/Documents/datalogger/datalogger.db’)
return connSQLServer
name_title = ‘Stats from SQL Server’
app = dash.Dash(name)
app.layout = html.Div(children=[
html.H1(children='Temperature Data '),
dcc.Graph(
id='example-graph',animate=True),dcc.Interval(id='graph-update',interval=1*500),])
@app.callback(Output(‘example-graph’, ‘figure’),
[Input(‘graph-update’, ‘n_interval’)])
def update_graph_scatter(input_data):
dataSQL = [] #set an empty list
X = deque(maxlen=10)
Y = deque(maxlen=10)
Z = deque(maxlen=10)
sql_conn = connectSQLServer()
cursor = sql_conn.cursor()
cursor.execute("SELECT date,pv,sp FROM temp")
rows = cursor.fetchall()
for row in rows:
dataSQL.append(list(row))
labels = ['date','pv','sp']
df = pd.DataFrame.from_records(dataSQL, columns=labels)
X = df['date']
Y = df['pv']
Z = df['sp']
data = plotly.graph_objs.Scatter(
x=list(X),
y=list(Y),
y1=list(Z),
name='Scatter',
mode= 'lines+markers',
)
return {'data': [data],'layout' : go.Layout(xaxis=dict(range=[min(X),max(X)]),
yaxis=dict(range=[min(Y),max(Y)]), y1axis=dict(range=[min(Z),max(Z)]),)}
if name == «main«:
app.run_server(debug=True)
«»»
can you please help on this issue
UPDATE: Solution found ~ error still not totally understood
As /u/ DYGAZ noted, the 404s seemed like they indicated that the urls were not valid. After some additional testing, I realized that it only gave callback errors when the input showed characters that were not valid tickers (e.g. «IE» is not the ticker code for any companies registered with the New York Stock Exchange [https://www.nyse.com/listings_directory/stock], so between when I was inputting «I» and «IEX» (both valid tickers), the callback function would have the error for «IE»).
This took a while to figure out, because I was mostly testing on tickers that begin with «A» and there are a lot of those, so the errors seemed more random.
Solution:
Dash has a parameter, debounce, for their Input function, which allows you to require that a user hit enter (or just click somewhere else on screen) before the callback function processes the input [https://dash.plot.ly/dash-core-components/input]. Adding that to the Input call and putting in a default value for my ticker got rid of the callback errors.
So I only had to change line 33 to the below:
dcc.Input(id='input',value='AMZN',type='text',debounce=TRUE)
I’m still not sure why none of the tutorials that I have seen (including the one by Sentdex linked below) seem to have had this issue. Maybe earlier versions had delays by default, but I did not find anything on that.
Original post below:
————————————————————————————
Hello
Software versions:
Python version: I just re-installed Anaconda this morning, and am using the most updated version, which uses Python version 3.7 [64 bit] (url: https://www.anaconda.com/distribution/#windows)
Browser: Firefox version 73.0.1 [64 bit]
Background:
I am following Sentdex’s Dash tutorial. Specifically, I am on part 3 (url: https://www.youtube.com/watch?v=wv2MXJIdKRY&list=PLQVvvaa0QuDfsGImWNt1eUEveHOepkjqt&index=3), which is where we make our graph dynamic based on user input.
The app lets the user input a company’s ticker symbol, and will display the stock closings as a line graph.
Issue:
When I run the app, once I move the mouse towards the input, I get a callback error ( full error below). When I type a ticker into the input, the graph will appear like it is supposed to; however, I will then get another callback error.
Code:
# Import libraries
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import pandas_datareader.data as web
import datetime as dt
app = dash.Dash()
app.layout = html.Div(children=[
html.Div(children='''
Symbol to graph:
'''),
dcc.Input(id='input', value='', type='text'),
html.Div(id='output-graph')
])
@app.callback(
Output(component_id='output-graph',component_property='children'),
[Input(component_id='input',component_property='value')]
)
def update_graph(input_data):
start = dt.datetime(2015,1,1)
end = dt.datetime.now()
df = web.DataReader(input_data,'yahoo',start,end)
return dcc.Graph(
id='example-graph',
figure={
'data':[
{'x':df.index,'y':df.Close,'type':'line','name':input_data},
],
'layout': {
'title': input_data
}
}
)
if __name__ == '__main__':
app.run_server(debug=True)
Full Error:
pandas_datareader._utils.RemoteDataError: Unable to read URL: https://finance.yahoo.com/quote//history?period1=1420102800&period2=1583053199&interval=1d&frequency=1d&filter=history Response Text: b'<html>n<meta charset=’utf-8′>n<script>nvar u=’https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory’;nif(window!=window.top){n document.write(‘<p>Content is currently unavailable.</p><img src=»//geo.yahoo.com/p?s=1197757039&t=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’+new Date().getTime()+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’&\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_R=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’+encodeURIComponent(document.referrer)+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’&err=404&err\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_url=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’+u+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'» width=»0px» height=»0px»/>’);n}else{n window.location.replace(u);n}n</script>n<noscript><META http-equiv=»refresh» content=»0;URL=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’\\\\\\\[\\\[\[[[https://www.yahoo.com/?err=404&err\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)))](https://www.yahoo.com/?err=404&err\\\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))))](https://www.yahoo.com/?err=404&err\\\\\\\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\\\\\\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)))](https://www.yahoo.com/?err=404&err\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)))))</noscript>n</html>n’
Traceback (most recent call last)
-
File «pathDesktopPythonfirst_finance_dashboard.py», line 43, in update_graphdf = web.DataReader(input_data,’yahoo’,start,end)
-
File «pathAnaconda3libsite-packagespandasutil_decorators.py», line 208, in wrapperreturn func(*args, **kwargs)
-
File «pathAnaconda3libsite-packagespandas_datareaderdata.py», line 387, in DataReadersession=session,
-
File «pathAnaconda3libsite-packagespandas_datareaderbase.py», line 251, in readdf = self._read_one_data(self.url, params=self._get_params(self.symbols))
-
File «pathAnaconda3libsite-packagespandas_datareaderyahoodaily.py», line 153, in _read_one_dataresp = self._get_response(url, params=params)
-
File «pathAnaconda3libsite-packagespandas_datareaderbase.py», line 179, in _get_responseraise RemoteDataError(msg)
pandas_datareader._utils.RemoteDataError: Unable to read URL: https://finance.yahoo.com/quote//history?period1=1420102800&period2=1583053199&interval=1d&frequency=1d&filter=history Response Text: b'<html>n<meta charset=’utf-8′>n<script>nvar u=’https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory’;nif(window!=window.top){n document.write(‘<p>Content is currently unavailable.</p><img src=»//geo.yahoo.com/p?s=1197757039&t=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’+new Date().getTime()+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’&\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_R=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’+encodeURIComponent(document.referrer)+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’&err=404&err\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_url=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’+u+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'» width=»0px» height=»0px»/>’);n}else{n window.location.replace(u);n}n</script>n<noscript><META http-equiv=»refresh» content=»0;URL=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’\\\\\\\[\\\[\[[[https://www.yahoo.com/?err=404&err\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)))](https://www.yahoo.com/?err=404&err\\\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))))](https://www.yahoo.com/?err=404&err\\\\\\\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\\\\\\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)))](https://www.yahoo.com/?err=404&err\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)))))</noscript>n</html>n’
Traceback (most recent call last): File «pathfirst_finance_dashboard.py», line 43, in update_graph df = web.DataReader(input_data,’yahoo’,start,end) File «pathAnaconda3libsite-packagespandasutil_decorators.py», line 208, in wrapper return func(*args, **kwargs) File «pathAnaconda3libsite-packagespandas_datareaderdata.py», line 387, in DataReader session=session, File «pathAnaconda3libsite-packagespandas_datareaderbase.py», line 251, in read df = self._read_one_data(self.url, params=self._get_params(self.symbols)) File «pathAnaconda3libsite-packagespandas_datareaderyahoodaily.py», line 153, in _read_one_data resp = self._get_response(url, params=params) File «pathAnaconda3libsite-packagespandas_datareaderbase.py», line 179, in _get_response raise RemoteDataError(msg) pandas_datareader._utils.RemoteDataError: Unable to read URL: https://finance.yahoo.com/quote//history?period1=1420102800&period2=1583053199&interval=1d&frequency=1d&filter=history Response Text: b'<html>n<meta charset=’utf-8′>n<script>nvar u=’https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory’;nif(window!=window.top){n document.write(‘<p>Content is currently unavailable.</p><img src=»//geo.yahoo.com/p?s=1197757039&t=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’+new Date().getTime()+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’&\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_R=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’+encodeURIComponent(document.referrer)+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’&err=404&err\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_url=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’+u+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'» width=»0px» height=»0px»/>’);n}else{n window.location.replace(u);n}n</script>n<noscript><META http-equiv=»refresh» content=»0;URL=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\’\\\\\\\[\\\[\[[[https://www.yahoo.com/?err=404&err\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)))](https://www.yahoo.com/?err=404&err\\\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))))](https://www.yahoo.com/?err=404&err\\\\\\\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\\\\\\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)))](https://www.yahoo.com/?err=404&err\_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory\\'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>))](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>](https://www.yahoo.com/?err=404&err_url=https%3a%2f%2ffinance.yahoo.com%2fquote%2f%2fhistory%3fperiod1%3d1420102800%26period2%3d1583053199%26interval%3d1d%26frequency%3d1d%26filter%3dhistory'»>)))))</noscript>n</html>n’
Edit:
Sorry for the poor formatting. I am making updates so that it is more readable.
Продолжаем изучать Python-фреймворк визуализации данных Dash. Сегодня мы расскажем о работе обратных вызовов (callback) в Dash. Читайте у нас: игнорирование обновления, частичное обновление callback, а также выяснение момента выполнения callback.
Игнорирование обновления обратного вызова
В некоторых ситуациях не нужно отображать результат на веб-странице сразу, т.е. декорируемая функция не должна ничего возвращать. Например, только после нажатия на кнопку должно что-то появиться. Тогда используется исключение PreventUpdate. Ниже представлен код на Python, где обновление callback не происходит, пока не нажата кнопка.
import dash import dash_html_components as html from dash.dependencies import Input, Output from dash.exceptions import PreventUpdate app = dash.Dash(__name__) app.layout = html.Div([ html.Button('Нажмите, чтобы посмотреть', id='show-secret'), html.Div(id='body-div') ]) @app.callback( Output(component_id='body-div', component_property='children'), [Input(component_id='show-secret', component_property='n_clicks')] ) def update_output(n_clicks): if n_clicks is None: raise PreventUpdate else: return f"Было произведено {n_clicks} кликов" app.run_server(debug=True)
В этом примере можно возвращать None — результат будет тот же. Но в случае если имеется множество Output’ов, то придётся возвращать такое же количество None, поэтому лучше воспользоваться PreventUpdate. К тому же, отлаживать callback с None будет гораздо сложнее, особенно если ваш Data Science проект начнет разрастаться, поэтому также стоит обратить внимание на частичное обновление.
Частичное обновление обратных вызовов
В Dash если у вас имеется несколько Output’ов, но при определённых условиях вы хотите обновлять только один из них, то dash.no_update
заменит вам None. Ниже пример callback’а на Python, где при значении Input равным 1, обновляется только второй Output.
@app.callback( [Output('out', 'children'), Output('err', 'children')], [Input('num', 'value')] ) def show_factors(num): if num is None: raise dash.exceptions.PreventUpdate if num == 1: return dash.no_update, '{} - это единица!'.format(num) return '{} - это больше единицы!'.format(num), ''
Определяем, какой Input был задействован
В Dash есть глобальная переменная dash.callback_context
, доступная только внутри callback. У нее есть атрибуты:
triggered
— список текущих обновляемых компонент. Он изменяется каждый раз, когда происходит переключение с одного Input на другой.inputs
иstates
позволяют получить доступ к идентификатору и к значению (id) Input или State.
Ниже пример Dash-приложения, где имеется 3 кнопки, а на странице отображаются текущее количество кликов, а также dash.callback_context
в формате JSON (JavaScript Object Notation).
app.layout = html.Div([ html.Button('Button 1', id='btn-1'), html.Button('Button 2', id='btn-2'), html.Button('Button 3', id='btn-3'), html.Div(id='container') ]) @app.callback(Output('container', 'children'), [Input('btn-1', 'n_clicks'), Input('btn-2', 'n_clicks'), Input('btn-3', 'n_clicks')]) def display(btn1, btn2, btn3): ctx = dash.callback_context if not ctx.triggered: button_id = 'No clicks yet' else: button_id = ctx.triggered[0]['prop_id'].split('.')[0] ctx_msg = json.dumps({ 'states': ctx.states, 'triggered': ctx.triggered, 'inputs': ctx.inputs }, indent=2) return html.Div([ html.Table([ html.Tr([html.Th('Button 1'), html.Th('Button 2'), html.Th('Button 3'), html.Th('Most Recent Click')]), html.Tr([html.Td(btn1 or 0), html.Td(btn2 or 0), html.Td(btn3 or 0), html.Td(button_id)]) ]), html.Pre(ctx_msg) ])
В какой момент выполняются обратные вызовы
Все обратные вызовы в Dash-приложении выполняются в следующие моменты:
- Как только запускается в браузере. Некоторые параметры инициализации callback, например, количество нажатий на кнопку, после запуска находятся в состояния None. Причём эти параметры перезаписывают то, что указно в layout;
- В момент прямого взаимодействия с пользователем. Нажатие на кнопку, выбор элемента в выпадающем списке или заполнение текста в блоке для ввода — все это вызывает callback;
- В момент косвенного взаимодействия с пользователем. Например, после ввода текста появляется график, а после него отображается ещё одно поле для ввода. Это похоже на цепную реакцию.
Предотвращаем начальное выполнение callback
В первом пункте мы указали, что после запуска Dash-приложения в браузере сразу же выполняется callback с перезаписыванием параметров layout. Такое поведение можно изменить, если передать в callback ещё один аргумент prevent_initial_call=True
. Ниже представлен пример на Python, где Dash-приложение ожидает нажатия кнопки, чтобы изменить значения, указанные в layout.
app.layout = html.Div([ html.Button('Нажми', id='inp-btn'), html.Div(id='out', children='Начальное значение'), ]) @app.callback( Output(component_id='out', component_property='children'), [Input(component_id='inp-btn', component_property='n_clicks')], prevent_initial_call=True ) def update_output(n_clicks): return f"Было произведено {n_clicks} кликов"
|
|
О способах визуализации данных в Dash для решения реальных задач Data Science, вы узнаете на специализированном курсе «VIP: Визуализация данных на языке Python» в лицензированном учебном центре обучения и повышения квалификации IT-специалистов в Москве.
Источники
- https://dash.plotly.com/advanced-callbacks
I am trying to create an interactive chart using Plotly Dash. The code reads the symbol name from the user and pullout historical data from yahoo finance and plots a candlestick chart with an slider. As I run the code I am getting this error in the browser:
Callback error updating output-graph.children
The source code is:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import pandas_datareader.data as web
import pandas as pd
from app import app
import datetime
app = dash.Dash()
app.layout = html.Div(children=[
html.H1('Interactive Chart'),
dcc.Input(id='input', value='', type='text'),
html.Div(id='output-graph')
])
@app.callback(
Output(component_id='output-graph', component_property = 'children'),
[Input(component_id='input', component_property = 'value')])
def update_graph(input_data):
start = datetime.datetime(2018, 6, 1)
end = datetime.datetime.now()
df = web.DataReader(input_data, 'yahoo', start, end)
df['year'] = pd.DatetimeIndex(df.index).year
df['date'] = pd.DatetimeIndex(df.index)
return dcc.Graph(id='example-graph',figure ={'data':[go.Candlestick(x=df['date'],open=df['Open'],high=df['High'],low=df['Low'],close=df['Close'],
increasing={'line': {'color': 'green'}},decreasing={'line': {'color': 'red'}})],
'layout':{'title': str.upper(input_data),
'height': 1000,
"spikedistance": 200,
"hoverdistance": 100,
"xaxis": {
"showspikes": 'true',
"spikemode": "across",
"spikedash": "dash",
"spikecolor": "#000000",
"spikethickness": 1},
"yaxis": {
"showspikes": 'true',
"spikemode": 'across',
"spikedash": "dash",
"spikecolor": "#000000",
"spikethickness": 1
}}})
if __name__ == '__main__':
app.run_server(debug=True)
I don’t know where in the callback I am making mistake.
Try this:
return html.Div(dcc.Graph(id='example-graph', figure=dict(data=traces,layout=layout)))
- Related Question
- Related Blog
- Related Tutorials
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.
I am trying to build an interactive dashboard using dash. I would like to show a scatterplot with each plot representing a fighter, the y axis the number of fights won and the x-axis the number of fights fought.
I want to allow users to select different divisions with a multi-dropdown arrow (to select one or multiple divisions).
With some online help, this is what I have come up with:
data['bouts_fought'] = data['w'].astype('float')+data['l'].astype('float')+data['d'].astype('float')
WEIGHT_CLASS = data['division'].unique()
app = dash.Dash()
app.css.append_css({
"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})
# layout
app.layout = html.Div(children=[
html.H1(children='Visualizing boxer stats', style={
'textAlign': 'center',
}),
dcc.Dropdown(
id='weight_class',
options=[{'label': i, 'value': i} for i in data['division'].unique()],
multi=True
),
dcc.Graph(
id='total-bouts-v-bouts-won',
)
])
@app.callback(
dash.dependencies.Output('total-bouts-v-bouts-won', 'figure'),
[dash.dependencies.Input('weight_class', 'value')])
def update_scatterplot(weight_class):
if weight_class is None or weight_class == []:
weight_class = WEIGHT_CLASS
weight_df = data[(data['division'].isin(weight_class))]
return {
'data': [
go.Scatter(
x=weight_df['bouts_fought'],
y=weight_df['w'],
text=weight_df['name'],
mode='markers',
opacity=0.5,
marker={
'size': 14,
'line': {'width': 0.5, 'color': 'blue'}
},
)
],
'layout': go.Layout(
xaxis={'title': 'Bouts fought'},
yaxis={'1': 40, 'b': '40', 't': 10, 'r': 10},
legend={'x': 0, 'y': 1},
hovermode='closest'
)
}
if __name__ == '__main__':
app.run_server(debug=True)
However, when I try and run this app, I get these warning messages:
options[14].label in Dropdown with ID «weight_class» is required but
it was not provided. Callback error updatingtotal-bouts-v-bouts-won.figure ValueError: Invalid properties
specified for object of type plotly.graph_objs.layout.YAxis: (‘1’,
‘b’, ‘t’, ‘r’)
Here is a sample of my data:
{'name': {0: 'Roberto Salas',
3: 'James Jackson',
6: 'Alex Love',
9: 'Juan Centeno',
12: 'Jordan Weeks'},
'division': {0: 'cruiser',
3: 'heavy',
6: 'bantam',
9: 'fly',
12: 'super middle'},
'w': {0: 5.0, 3: 4.0, 6: 3.0, 9: 4.0, 12: 2.0},
'l': {0: 0.0, 3: 0.0, 6: 0.0, 9: 3.0, 12: 0.0},
'd': {0: 0.0, 3: 1.0, 6: 0.0, 9: 1.0, 12: 0.0},
'location': {0: 'USA', 3: 'USA', 6: 'USA', 9: 'USA', 12: 'USA'},
'from': {0: 2016.0, 3: 2017.0, 6: 2018.0, 9: 2016.0, 12: 2019.0},
'sex': {0: 'male', 3: 'male', 6: 'female', 9: 'male', 12: 'male'}}
I updated my code based on the answer given, but still getting this error message:
Error: options[14].label in Dropdown with ID "weight_class" is required but it was not provided.
at propTypeErrorHandler (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/dash_renderer.v1_2_0m1574163797.dev.js:33569:9)
at CheckedComponent (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/dash_renderer.v1_2_0m1574163797.dev.js:30047:77)
at renderWithHooks (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/[email protected]_2_0m1574163797.8.6.js:13073:18)
at mountIndeterminateComponent (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/[email protected]_2_0m1574163797.8.6.js:15155:13)
at beginWork (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/[email protected]_2_0m1574163797.8.6.js:15760:16)
at performUnitOfWork (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/[email protected]_2_0m1574163797.8.6.js:19447:12)
at workLoop (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/[email protected]_2_0m1574163797.8.6.js:19487:24)
at renderRoot (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/[email protected]_2_0m1574163797.8.6.js:19570:7)
at performWorkOnRoot (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/[email protected]_2_0m1574163797.8.6.js:20477:7)
at performWork (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/[email protected]_2_0m1574163797.8.6.js:20389:7)
Issue
I’m quite new to dash but I’m trying to put together a data dashboard. Of the things I want to have is a drop down, that based on the input, renders 1 of two pie charts. The logic to structure the pie chart is included in my callback function. It is saying it is expecting 1 output but it had two. I’ve had a look online and tried different suggestions. I think I’m pretty close to getting this to work, there is just something dumb I’m not doing.
I know people here are wizards, so I was hoping someone might be able to help me. Also if anyone is Dash savvy, can you point me in the direction of good documentation to learn how to orient this, so I can change the layout to make these plots fit better together in a dashboard, rather than just a web page?
So much love
Thanks
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)
Solution
The first problem is that your callback has one output, but you return a tuple of two things. So you could add an Output
that targets the element which you want to have the value of content
, I’m guessing that element is the element with id output_container
. The other option is to remove content
from the return statement.
The second problem is that you have the Output
surrounded by a list, so dash expects the return value to be a list containing one value. You can remove the list surrounding your Ouput
so it expects a tuple
Output(component_id='pie_chart_reports', component_property='figure')
or you can surround your return values with a list.
The third problem is that you target the component_property
figure
, but you’re returning a Graph
component. So you should return fig1
instead of dcc.Graph(id='pie_chart_reports', figure=fig1)
for example.
Answered By — Bas van der Linden
The reason it is not working is because thread uvdos pandas you’re not handling the case in your thread uvdos pandas callback where the button has not been thread uvdos pandas clicked. Even if the button hasn’t been thread uvdos pandas clicked your callback still needs to thread uvdos pandas return a tuple (of your data and thread uvdos pandas columns).
That is what the error is saying here:
Expected the output type to be a list or thread uvdos pandas tuple but got: None.
You don’t return anything (None) when thread uvdos pandas n_clicks is 0 (false).
So what you need to do is return the thread uvdos pandas data and columns when n_clicks is 0. The thread uvdos pandas only difference in approach from what thread uvdos pandas you have is that you don’t apply any thread uvdos pandas filters to the data if n_clicks is 0.
Full example:
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_table as dt
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/solar.csv")
app = dash.Dash(__name__)
states = df.State.unique().tolist()
numSP = df["Number of Solar Plants"].unique().tolist()
app.layout = html.Div(
[
dcc.Dropdown(
id="filter_dropdown",
options=[{"label": st, "value": st} for st in states],
value=states[0],
),
html.Br(),
dcc.Dropdown(
id="filter2",
options=[{"label": np, "value": np} for np in numSP]
# value = numSP[0]
),
html.Br(),
html.Button("Submit", id="submit-button-state", n_clicks=0),
html.Br(),
html.Div(id="output"),
html.Div(
# id ='priceTable'
dt.DataTable(id="priceTable")
),
]
)
def get_table_data(data):
columns = [
{
"name": i,
"id": i,
}
for i in (data.columns)
]
data = data.to_dict("records")
return (data, columns)
@app.callback(
[Output("priceTable", "data"), Output("priceTable", "columns")],
[Input("submit-button-state", "n_clicks")],
[State("filter_dropdown", "value")],
[State("filter2", "value")],
[State("submit-button-state", "n_clicks")],
)
def update_table(n_clicks, filter_dropdown, filter2, table):
if n_clicks:
if filter_dropdown is None and filter2 is None:
raise PreventUpdate
if filter_dropdown is not None and filter2 is not None:
table = df[df.State == filter_dropdown]
table = table[table["Number of Solar Plants"] == filter2]
if filter_dropdown is None and filter2 is not None:
table = df[df["Number of Solar Plants"] == filter2]
if filter_dropdown is not None and filter2 is None:
table = df[df.State == filter_dropdown]
(data, columns) = get_table_data(table)
print("columns", columns)
print("data", columns)
return data, columns
return get_table_data(df)
if __name__ == "__main__":
app.run_server(debug=True)
In the example above I’ve also put your thread uvdos pandas code for retrieving data and columns thread uvdos pandas from a dataframe in its own function thread uvdos pandas get_table_data. For making sure a tuple thread uvdos pandas of your data is always returned I’ve thread uvdos pandas used a guard clause.