Reputation: 109
I have tried to re-create the following example Towards Data Science Example shown on the web
I have written the following code which I modified to this:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.graph_objs as go
# Step 1. Launch the application
app = dash.Dash()
# Step 2. Import the dataset
filepath = 'https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv'
st = pd.read_csv(filepath)
# range slider options
st['Date'] = pd.to_datetime(st.Date)
dates = ['2015-02-17', '2015-05-17', '2015-08-17', '2015-11-17',
'2016-02-17', '2016-05-17', '2016-08-17', '2016-11-17', '2017-02-17']
features = st.columns[1:-1]
opts = [{'label' : i, 'value' : i} for i in features]
# Step 3. Create a plotly figure
trace_1 = go.Scatter(x = st.Date, y = st['AAPL.High'],
name = 'AAPL HIGH',
line = dict(width = 2,
color = 'rgb(229, 151, 50)'))
layout = go.Layout(title = 'Time Series Plot',
hovermode = 'closest')
fig = go.Figure(data = [trace_1], layout = layout)
# Step 4. Create a Dash layout
app.layout = html.Div([
# a header and a paragraph
html.Div([
html.H1("This is a Test Dashboard"),
html.P("Dash is great!!")
],
style = {'padding' : '50px' ,
'backgroundColor' : '#3aaab2'}),
# adding a plot
dcc.Graph(id = 'plot', figure = fig),
# dropdown
html.P([
html.Label("Choose a feature"),
dcc.Dropdown(
id='opt',
options=opts,
value=features[0],
multi=True
),
# range slider
html.P([
html.Label("Time Period"),
dcc.RangeSlider(id = 'slider',
marks = {i : dates[i] for i in range(0, 9)},
min = 0,
max = 8,
value = [1, 7])
], style = {'width' : '80%',
'fontSize' : '20px',
'padding-left' : '100px',
'display': 'inline-block'})
])
])
# Step 5. Add callback functions
@app.callback(Output('plot', 'figure'),
[Input('opt', 'value'),
Input('slider', 'value')])
def update_figure(input1, input2):
# filtering the data
st2 = st[(st.Date > dates[input2[0]]) & (st.Date < dates[input2[1]])]
# updating the plot
trace_1 = go.Scatter(x = st2.Date, y = st2['AAPL.High'],
name = 'AAPL HIGH',
line = dict(width = 2,
color = 'rgb(229, 151, 50)'))
trace_2 = go.Scatter(x = st2.Date, y = st2[input1],
name = input1,
line = dict(width = 2,
color = 'rgb(106, 181, 135)'))
fig = go.Figure(data = [trace_1, trace_2], layout = layout)
return fig
# Step 6. Add the server clause
if __name__ == '__main__':
app.run_server(debug = True)
It runs and initializes all fine, until I change an input in the dropdown menu. There is a callback error generated, and I can't figure out where it comes from.
The app runs locally and displays the drop down menu fine with all the column, changing the input for the dropdown gives the issue.
The error is as follows:
ValueError:
Invalid value of type 'builtins.list' received for the 'name' property of scatter
Received value: ['AAPL.Open', 'AAPL.Close']
The 'name' property is a string and must be specified as:
- A string
- A number that will be converted to a string
Traceback (most recent call last):
File "C:\test\Anaconda\lib\site-packages\flask\app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "C:\test\Anaconda\lib\site-packages\flask\app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "C:\test\Anaconda\lib\site-packages\flask\app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\test\Anaconda\lib\site-packages\flask\_compat.py", line 35, in reraise
raise value
File "C:\test\Anaconda\lib\site-packages\flask\app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "C:\test\Anaconda\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\test\Anaconda\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\test\Anaconda\lib\site-packages\flask\_compat.py", line 35, in reraise
raise value
File "C:\test\Anaconda\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "C:\test\Anaconda\lib\site-packages\flask\app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\test\Anaconda\lib\site-packages\dash\dash.py", line 1152, in dispatch
response.set_data(self.callback_map[output]['callback'](*args))
File "C:\test\Anaconda\lib\site-packages\dash\dash.py", line 1038, in add_context
output_value = func(*args, **kwargs)
File "C:\Users\Dash\Dash\test.py", line 87, in update_figure
color = 'rgb(106, 181, 135)'))
File "C:\test\Anaconda\lib\site-packages\plotly\graph_objs\__init__.py", line 37455, in __init__
self['name'] = name if name is not None else _v
File "C:\test\Anaconda\lib\site-packages\plotly\basedatatypes.py", line 3166, in __setitem__
self._set_prop(prop, value)
File "C:\test\Anaconda\lib\site-packages\plotly\basedatatypes.py", line 3407, in _set_prop
raise err
File "C:\test\Anaconda\lib\site-packages\plotly\basedatatypes.py", line 3402, in _set_prop
val = validator.validate_coerce(val)
File "C:\test\Anaconda\lib\site-packages\_plotly_utils\basevalidators.py", line 1005, in validate_coerce
self.raise_invalid_val(v)
File "C:\test\Anaconda\lib\site-packages\_plotly_utils\basevalidators.py", line 277, in raise_invalid_val
valid_clr_desc=self.description()))
ValueError:
Invalid value of type 'builtins.list' received for the 'name' property of scatter
Received value: ['AAPL.Open', 'AAPL.Close']
The 'name' property is a string and must be specified as:
- A string
- A number that will be converted to a string
Upvotes: 2
Views: 8966
Reputation: 1631
Callback error quick fix
Got similar error on callback
. Simple dash
update resolved it.
pip install dash --upgrade
Upvotes: 0
Reputation: 1455
Working Code
Your error was in line 85. You can only pass strings or numbers to the name
attribute. I just added pythons str()
function to transfer input1
to a string. :)
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.graph_objs as go
# Step 1. Launch the application
app = dash.Dash()
# Step 2. Import the dataset
filepath = 'https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv'
st = pd.read_csv(filepath)
# range slider options
st['Date'] = pd.to_datetime(st.Date)
dates = ['2015-02-17', '2015-05-17', '2015-08-17', '2015-11-17',
'2016-02-17', '2016-05-17', '2016-08-17', '2016-11-17', '2017-02-17']
features = st.columns[1:-1]
opts = [{'label' : i, 'value' : i} for i in features]
# Step 3. Create a plotly figure
trace_1 = go.Scatter(x = st.Date, y = st['AAPL.High'],
name = 'AAPL HIGH',
line = dict(width = 2,
color = 'rgb(229, 151, 50)'))
layout = go.Layout(title = 'Time Series Plot',
hovermode = 'closest')
fig = go.Figure(data = [trace_1], layout = layout)
# Step 4. Create a Dash layout
app.layout = html.Div([
# a header and a paragraph
html.Div([
html.H1("This is a Test Dashboard"),
html.P("Dash is great!!")
],
style = {'padding' : '50px' ,
'backgroundColor' : '#3aaab2'}),
# adding a plot
dcc.Graph(id = 'plot', figure = fig),
# dropdown
html.P([
html.Label("Choose a feature"),
dcc.Dropdown(
id='opt',
options=opts,
value=features[0],
multi=True
),
# range slider
html.P([
html.Label("Time Period"),
dcc.RangeSlider(id = 'slider',
marks = {i : dates[i] for i in range(0, 9)},
min = 0,
max = 8,
value = [1, 7])
], style = {'width' : '80%',
'fontSize' : '20px',
'padding-left' : '100px',
'display': 'inline-block'})
])
])
# Step 5. Add callback functions
@app.callback(Output('plot', 'figure'),
[Input('opt', 'value'),
Input('slider', 'value')])
def update_figure(input1, input2):
# filtering the data
st2 = st[(st.Date > dates[input2[0]]) & (st.Date < dates[input2[1]])]
# updating the plot
trace_1 = go.Scatter(x = st2.Date, y = st2['AAPL.High'],
name = 'AAPL HIGH',
line = dict(width = 2,
color = 'rgb(229, 151, 50)'))
trace_2 = go.Scatter(x = st2.Date, y = st2[input1],
name = str(input1),
line = dict(width = 2,
color = 'rgb(106, 181, 135)'))
fig = go.Figure(data = [trace_1, trace_2], layout = layout)
return fig
# Step 6. Add the server clause
if __name__ == '__main__':
app.run_server(debug = True)
Upvotes: 3