问题
I am building a simple python dashboard using dash and plotly. I am also new to python (as is probably evident!) and I'm happy for any/all corrections. I would like to plot a time series of data from a pre-determined CSV file. I have added a dropdown selection box with which I would like to allow multiple different columns to be plotted.
Sample data:
"TOA5","HE605_RV50_GAF","CR6","7225","CR6.Std.07","CPU:BiSP5_GAF_v2d.CR6","51755","SensorStats"
"TIMESTAMP","RECORD","BattV_Min","BattV_Avg","PTemp_C_Avg","SensorRel_Min(1)","SensorRel_Min(2)","SensorRel_Min(3)","SensorRel_Min(4)","SensorRel_Min(5)","SensorRel_Max(1)","SensorRel_Max(2)","SensorRel_Max(3)","SensorRel_Max(4)","SensorRel_Max(5)"
"TS","RN","Volts","Volts","Deg C","","","","","","","","","",""
"","","Min","Avg","Avg","Min","Min","Min","Min","Min","Max","Max","Max","Max","Max"
"2019-09-30 11:15:00",0,12.68219,12.74209,"NAN","NAN","NAN","NAN","NAN","NAN","NAN","NAN","NAN","NAN","NAN"
"2019-09-30 11:30:00",1,12.68466,12.73777,31.26331,-2.498894,-2.38887,-8.497528,-2.963989,-20.42339,41.51585,28.41309,88.98283,27.27819,17.98986
"2019-09-30 11:45:00",2,12.69364,12.74584,31.43891,-3.490456,-2.856804,-8.770081,-3.879868,-22.69171,42.27676,30.53723,89.47752,34.25191,23.92586
"2019-09-30 12:00:00",3,12.69078,12.74522,31.38461,-3.290047,-2.973389,-8.69928,-3.295074,-21.88254,42.72508,29.91062,83.36012,27.9931,22.6571
"2019-09-30 12:15:00",4,12.6914,12.74376,31.2449,-2.899231,-2.392128,-10.01413,-2.996033,-23.22171,42.97162,29.20943,106.1204,35.93995,41.74426
My python(3.7) code for this is:
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_objects as go
# Load external stylesheets
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
# Load external datasets
df = pd.read_csv('../SampleData/test_data.dat', skiprows=3, na_values='NAN')
df.columns=["TIMESTAMP","RECORD","BattV_Min","BattV_Avg","PTemp_C_Avg","SensorRel_Min(1)","SensorRel_Min(2)","SensorRel_Min(3)","SensorRel_Min(4)","SensorRel_Min(5)","SensorRel_Max(1)","SensorRel_Max(2)","SensorRel_Max(3)","SensorRel_Max(4)","SensorRel_Max(5)"]
# define dropdown options
opts=[{'label': k, 'value': k} for k in list(df.columns.values)[1:]]
# create plotly figures
fig2=go.Figure()
# Create a Dash layout
app.layout = html.Div(children=[
html.H1(children='Testing dashboard v01'),
html.Div(children='''
Select variable to plot below.
'''),
html.Div(children='''
Select variables to add to plot below.
'''),
dcc.Dropdown(
id='multiVariableDropdown',
options=opts,
value='RECORD',
multi=True
),
dcc.Graph(
id='plot2'
)
])
# Add callback functions
## For plot 2
@app.callback(Output('plot2', 'figure'),
[Input('multiVariableDropdown', 'value')])
def update_graph(selectedVariable2):
trace_finalPlot2 = go.Scatter(
x=df['TIMESTAMP'],
y=df[selectedVariable2],
name=str(selectedVariable2))
fig2 = go.Figure(data=trace_finalPlot2)
return fig2
if __name__ == '__main__':
app.run_server(debug=True)
The initial rendering of the plot looks good, as this is what appear after running python3 app.py
:
But once I add another column to be plotted from the multi-selection dropdown, the original data disappears and it only plots a single point:
Unfortunately, it's not returning any error data so I'm having trouble debugging. Any tips/hints appreciated.
回答1:
The issue is that the dropdown returns a list of multiple variables (as you set multi=True
), while your callback is designed to plot only one variable.
In order to plot multiple variables, you need to iterate through the selected list of variables (i.e. through selectedVariable2
in your code) and add the respective traces to the figure.
You should also make sure that the dropdown is initialized with a list rather than a string (i.e. you should replace value="RECORD"
with value=["RECORD"]
.
I included an example below.
import pandas as pd
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
# Load external stylesheets
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
# Create a sample dataset
df = pd.DataFrame({"TIMESTAMP": ["2019-09-30 11:15:00", "2019-09-30 11:30:00", "2019-09-30 11:45:00", "2019-09-30 12:00:00", "2019-09-30 12:15:00"],
"RECORD": [0, 1, 2, 3, 4],
"SensorRel_Min(2)": [12.68219, 12.68466, 12.69364, 12.69078, 12.6914],
"SensorRel_Min(3)": [14.74209, 13.73777, 10.74584, 9.74522, 16.74376]})
# Define dropdown options
opts = [{'label': k, 'value': k} for k in list(df.columns.values)[1:]]
# Create a Dash layout
app.layout = html.Div(children=[
html.H1(children='Testing dashboard v01'),
html.Div(children='''
Select variable to plot below.
'''),
html.Div(children='''
Select variables to add to plot below.
'''),
dcc.Dropdown(
id='multiVariableDropdown',
options=opts,
value=['RECORD'],
multi=True
),
dcc.Graph(
id='plot2'
)
])
# Add callback functions
## For plot 2
@app.callback(Output('plot2', 'figure'),
[Input('multiVariableDropdown', 'value')])
def update_graph(selectedVariable2):
traces = []
for var in selectedVariable2:
traces.append(go.Scatter(x=df['TIMESTAMP'],
y=df[var],
name=var))
fig2 = go.Figure(data=traces)
return fig2
if __name__ == '__main__':
app.run_server(debug=True)
回答2:
Try to debug it by using print(). Something like below, this way you can see what`s getting sent to the Output component every time you add/remove something from dropdown. Hope it helps!
def update_graph(selectedVariable2):
trace_finalPlot2 = go.Scatter(
x=df['TIMESTAMP'],
y=df[selectedVariable2],
name=str(selectedVariable2))
fig2 = go.Figure(data=trace_finalPlot2)
print(df[selectedVariable2])
return fig2
来源:https://stackoverflow.com/questions/62015493/plotly-dash-why-is-my-figure-failing-to-show-with-a-multi-dropdown-selection