Callback error updating dash

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 imp...

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)

Содержимое появится только после нажатия Dash

Использование PreventUpdate

В этом примере можно возвращать 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

Отображение на веб-странице dash.callback_context

В какой момент выполняются обратные вызовы

Все обратные вызовы в Dash-приложении выполняются в следующие моменты:

  1. Как только запускается в браузере. Некоторые параметры инициализации callback, например, количество нажатий на кнопку, после запуска находятся в состояния None. Причём эти параметры перезаписывают то, что указно в layout;
  2. В момент прямого взаимодействия с пользователем. Нажатие на кнопку, выбор элемента в выпадающем списке или заполнение текста в блоке для ввода — все это вызывает callback;
  3. В момент косвенного взаимодействия с пользователем. Например, после ввода текста появляется график, а после него отображается ещё одно поле для ввода. Это похоже на цепную реакцию.

Предотвращаем начальное выполнение 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} кликов"
Мгновенное обновление callback Dash
Результат при prevent_initial_call=False (по умолчанию)
Обновление callback после нажатия Dash
Результат при prevent_initial_call=True

О способах визуализации данных в Dash для решения реальных задач Data Science, вы узнаете на специализированном курсе «VIP: Визуализация данных на языке Python» в лицензированном учебном центре обучения и повышения квалификации IT-специалистов в Москве.

Источники

  1. 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

enter image description here

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 updating

total-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.

Понравилась статья? Поделить с друзьями:
  • Callable not found or import error
  • Call to httpclient begin declared with attribute error obsolete api use begin wificlient url
  • Call to arms ошибка при запуске приложения 0xc0000142
  • Call to arms gates of hell ostfront ошибка program will be terminated
  • Call to arms gates of hell ostfront ошибка failed to allocate memory