0
votes

I'm trying to create a basic interactive plot for a timeseries dataframe I have. I have read the data into a data frame df. It has datetime as index and two other colums category (has 3 unique values), count. Now, I'm trying to plot an interactive graph using plotly-dash with following features

  1. It will have a input box where the user should enter the category value for which they want to see the plot for
  2. If the value they entered is in df['category'].unique() it will return the timeseries plot corresponding to that particular category. Else It will throw an error

This is the code I have written for it

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.express as px

app = dash.Dash()
app.layout = html.Div(children = [
    html.H1(children='Dash trail'),
    html.Br(),
    html.Br(),
    dcc.Input(id='input_id',value='',type='text'),
    dcc.Graph(id='inflow_graph')
])

@app.callback(
[Output(component_id='inflow_graph',component_property='figure')],
    [Input(component_id='input_id',component_property='value')])
def update_graph(input_text):
    if input_text in df['category'].unique():
        dff = df[df['category']==input_text]
        fig = px.line(dff, x=dff.index, y=dff['count'],title='count for selected category')
        return fig
    else:
        return 'Enter the correct category value'
if __name__=='__main__':
    app.run_server(debug=True,use_reloader=False)

It is throwing the following error

dash.exceptions.InvalidCallbackReturnValue: The callback ..inflow_graph.figure.. is a multi-output.
Expected the output type to be a list or tuple but got:
Figure({
    'data': [{'hovertemplate': 'ds=%{x}<br>ticket_count=%{y}<extra></extra>',
              'legendgroup': '',
              'line': {'color': '#636efa', 'dash': 'solid'},
              'mode': 'lines',
              'name': '',
              'showlegend': False,
              'type': 'scattergl',
              'x': array([datetime.datetime(2020, 1, 3, 0, 0), ....(and so on my full dataframe)

I didn't understand where I'm calling back multiple outputs. How do I resolve this error?

Edit: Adding sample data here

            Category Count
date(index) 
2020-01-03    A       30
2020-01-03    B       50
2020-01-04    C       14
2020-01-04    A       16
2020-01-04    B       40
1
Please share a sample of your data in order to make your code reproducible. - vestland
Added the sample data in the edit - MonkeyDLuffy

1 Answers

2
votes

In @app.callback() you put a list of Outputs, containing a single element. If you do so, you'll need to return a list as well, so return [fig] instead of return fig.

However, you don't need to have the lists at all, so your callback decorator can simply look like this:

@app.callback(
    Output('inflow_graph', 'figure'),
    Input('input_id', 'value'))
def update_graph(input_text):

Note how I also dropped the component_id and component_property keys for brevity, since they are also not needed in current versions of Dash (they are not wrong however).

There is another problem in your callback though: You return a string in the else case, but inflow_graph.figure will expect a Figure object or dictionary. You can fix this by returning an empty dictionary (return {}).