Forewarning, I have three strikes against me: new-ish to python
, very newt to dash
and just wrapping my head around classes.
I have a process at work and I want to create a gui for it. The user will input some key process variables, click “Go”, and the process will start, outputting some data of interest via a table and plot live. My dash
code got a bit long so I started looking into putting it into a class. This is likely wrong, but the gist of my structure:
class Gui:
def __init__(self):
self.params = {'dur': 5, 'freq': 10}
self.app = dash.Dash()
self.app.layout = self.build_layout
def generate_inputs(self, params):
dur = [html.Label(html.Strong('duration to sample, sec')),
dcc.Input(type='number', value=params['dur'], id='dur')]
freq = [html.Label(html.Strong('sample frequency, n/sec')),
dcc.Input(type='number', value=params['freq'], id='freq')]
run_test = [html.Label(html.Strong('ready?')),
html.Button('run test!', id='run', n_clicks=0)]
input_list = [dur, freq, run_test]
widgets = list()
for sublist in input_list:
sublist.append(html.H1(''))
for item in sublist:
widgets.append(item)
return widgets
def build_layout(self):
layout = html.Div([
html.H2('a dashboard'),
html.Div(self.generate_inputs(self.params),
style={'width' : '15%', 'float' : 'left' }),
html.Div(id='plot'),
]) # app.layout
return layout
def generate_plot(data):
plot = dcc.Graph(
id='live-data',
figure={
'data': [go.Scatter(name='plot',
x=data['i'],
y=data['mean'])],
'layout': go.Layout(title= 'Live test data')#,
},
style={'width' : '80%', 'float' : 'right' }
) # dcc.Graph
return plot
if __name__ == '__main__':
gui = Gui()
gui.app.run_server(debug=False)
This works, but I get stumped when it comes to integrating any sort of reactivity. For example, let’s say I add this to build_layout()
:
html.Div(dcc.Interval(id='refresh', interval=5000))
This would call my plot function, but I don’t know how to put it in the class. I get NameError: name 'app' is not defined
as shown, and Dash.app.callback
, dash.app.callback
, and self.app.callback
don’t work either (total guesses).
@app.callback(
dash.dependencies.Output('plot', 'children'),
events=[dash.dependencies.Event('refresh', 'interval')])
def updates(self):
return generate_plot(self.data)
I’m open to any feedback on this approach. What is the recommended way to integrate dash
with more complicated things? My sense in the examples I see is that dash
is sort of in the spotlight, with other things somehow worked into it. What if dash
is only a component of what you’re doing (the gui/visualization side) and you have a lot of other complicated stuff to do elsewhere?
If it’s helpful here’s a flattened (no class) version of the above that works. In parallel with dash
I’d be using a library to talk to some equipment, send a command, get back some data, and plot it. In my real example, the code just gets so darn long and ugly I was trying to simplify it a bit and ran into issues.
Many thanks!