I would like to create a stopwatch using python plotly dash and the following is my code. Here I use the element dcc.Interval to update timing information every one second, but unfortunately, I found that it is not accurate when I used my iPhone built-in stopwatch to test its accuracy. Any suggestion on how how to correct my code? Thanks :)
# import modules
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
# define functions
def sec_transform(i):
m, s = divmod(i, 60)
msg = '%02i:%02i' % (m, s)
return msg
# dashboard layout
app = dash.Dash()
app.layout = html.Div([
# display time elapsed
html.H1(id='live-update-text'),
# for live updating
dcc.Interval(
id='interval-component',
interval=1000, # 1000 milliseconds
n_intervals=0
)
])
# call back function
#app.callback(Output('live-update-text', 'children'),
[Input('interval-component', 'n_intervals')])
def update_layout(n):
msg = sec_transform(n)
return msg
if __name__ == '__main__':
app.run_server()
Related
i have found a nice code on stackoverflow
( Dash app, plotly chart data outside the chart area)
I have change to "pie-figure"
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
#from datetime import datetime
import plotly.graph_objs as go
import random
labels = ['Mom','Max']
y_values = [] # finally: 1st value read c:\\test.txt ( only 1 value is inside,
# sec value = 6000 - 1st value )
# Initialize the dash app
app = dash.Dash()
app.layout = html.Div([
dcc.Graph(id='live-graph', animate=True,responsive=True),
dcc.Interval(
id='graph-update',
interval=1000,
n_intervals=0
),
])
# Define the callback function
#app.callback(Output('live-graph', 'figure'), [Input('graph-update', 'n_intervals')])
def update_graph(n):
current_value= random.randint(2000, 8000)
# Get the response value and append it to the y_values list
y = current_value
y_values.append(y)
# Create the line chart
trace = go.Pie(labels=labels, values=y_values)
data = [trace]
layout = go.Layout(title='Real-time Data')
return go.Figure(data=data)
if __name__ == '__main__':
app.run_server(host="192.168.178.26", port=8050, debug=True)
why does the current value didn´t change?
what must i do?
Many thanks!
I think there's two main problems you need to fix:
the way you have written your dash app, the labels will stay the same after every update, but the labels need to be the same length as the y_values (see the documentation for go.Pie). To fix this, I randomly selected a new label from ["Mom", "Max"] along with a new y-value for every update (but this can be changed if you intended for the dash app to do something different)
I believe the argument animate=True for dcc.Graph only applies to certain types of charts like bar charts and line charts where you can draw something smooth. for a pie chart, you don't need an animation (you can just redraw the chart) and I think this is what is causing the code to break. once I set animate=False, the pie chart updates
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
#from datetime import datetime
import plotly.graph_objs as go
import random
labels = []
y_values = [] # finally: 1st value read c:\\test.txt ( only 1 value is inside,
# sec value = 6000 - 1st value )
random.seed(42)
# Initialize the dash app
app = dash.Dash()
app.layout = html.Div([
dcc.Graph(id='live-graph', animate=False, responsive=True),
dcc.Interval(
id='graph-update',
interval=1000,
n_intervals=0
),
])
# Define the callback function
#app.callback(Output('live-graph', 'figure'), [Input('graph-update', 'n_intervals')])
def update_graph(n):
current_value= random.randint(2000, 8000)
current_label= random.choice(['Mom','Max'])
# Get the response value and append it to the y_values list
y = current_value
y_values.append(y)
labels.append(current_label)
# Create the pie chart
trace = go.Pie(labels=labels, values=y_values)
# trace = go.Bar(x=labels, y=y_values)
data = [trace]
layout = go.Layout(title='Real-time Data')
return go.Figure(data=data, layout=layout)
if __name__ == '__main__':
app.run_server(port=8050, debug=True)
I'm new in Dash. I'm trying to use a daq.BooleanSwitch() like an input to callback a graph. I can display a message but I have troubles with the graph.
Does anyone have any advice that can help me?
import dash
from dash.dependencies import Input, Output
import dash_daq as daq
import dash_html_components as html
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("Here we go"),
daq.BooleanSwitch(id='my_pb', on=False,color="red"),
html.Div(id='power-button-result-1'),
dcc.Graph(id="plot")
])
#app.callback(
Output('power-button-result-1', 'children'),
Input('my_pb', 'on')
)
def update_output(on):
x = '{}'.format(on)
if x == "True":
return "Hi Iḿ using DASH"
#app.callback(
Output('plot', 'figure'),
Input('my_pb', 'on')
)
def figura(on):
x = '{}'.format(on)
if x == "True":
# fig1 = Code to do a nice plot
return fig1
if __name__ == "__main__":
app.run_server(port = 1895)
My DASH output look like this:
I took a look at your code, and a couple changes were necessary:
import dash
import dash_daq as daq
from dash import dcc
from dash import html
from dash.dependencies import Input
from dash.dependencies import Output
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.H1("Here we go"),
daq.BooleanSwitch(id="my_pb", on=False, color="red"),
html.Div(id="power-button-result-1"),
]
)
#app.callback(
Output("power-button-result-1", "children"),
Input("my_pb", "on"),
)
def update_output(on):
x = "{}".format(on)
if x == "True":
return [dcc.Graph(id="plot")]
if __name__ == "__main__":
app.run_server(debug=True)
You were super close - I think you only need one callback. Here, you can see the boolean switch now toggles the display (or not) of the dcc.Graph object. Is this what you were looking for?
↓ (toggle the switch)
If you want the graph to already be displayed, and then updated upon toggling, here's a slightly modified expanded version of same code above to do that:
import dash
import dash_daq as daq
from dash import dcc
from dash import html
from dash import no_update
from dash.dependencies import Input
from dash.dependencies import Output
import plotly.express as px
import pandas as pd
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.H1("Here we go"),
daq.BooleanSwitch(id="my_pb", on=False, color="red"),
html.Div(
[dcc.Graph(id="plot")], id="power-button-result-1"
),
]
)
#app.callback(
Output("power-button-result-1", "children"),
Input("my_pb", "on"),
)
def update_output(on):
df = px.data.iris()
if on:
fig = px.scatter(df, x="sepal_width", y="sepal_length")
dcc.Graph(figure=fig)
return [dcc.Graph(figure=fig)]
else:
fig = px.scatter()
return [dcc.Graph(figure=fig)]
if __name__ == "__main__":
app.run_server(debug=True)
There - that's much better, hopefully helpful?
New to Dash so bear with.
I have a websocket connection that streams forex data to my console; price, high, low, symbol etc.
I'd like to have that information displayed on a dashboard that is easily viewable, instead of everything being printed to my console.
The issue i face is the data only updates on page refresh, when i'd like it to update as it is received, on the dashboard.
This is my code to connect to the websocket and create the dashboard:
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly
from dash.dependencies import Input, Output, State
import fxcmpy
import pandas as pd
import datetime as dt
import time
con = fxcmpy.fxcmpy(access_token = "1111111111111111111111111111111111111111111111212", log_level = 'error')
currenc = ["AUD/CAD", "AUD/CHF", "AUD/JPY", "AUD/NZD", "AUD/USD", "CAD/CHF", "CAD/JPY", "CHF/JPY", "EUR/AUD", "EUR/CAD", "EUR/CHF", "EUR/GBP", "EUR/JPY", "EUR/NZD", "EUR/TRY", "EUR/USD", "GBP/AUD", "GBP/CAD", "GBP/CHF", "GBP/JPY", "GBP/NZD", "GBP/USD", "NZD/CAD", "NZD/CHF", "NZD/JPY", "NZD/USD", "USD/CAD", "USD/JPY"]
app = dash.Dash(__name__)
def print_data(data, dataframe):
t = pd.to_datetime(int(data['Updated']), unit='ms')
price = data['Rates'][0]
symbol = data['Symbol']
app.layout = html.Div([
dcc.Textarea(
id='textprice',
value=(str(price)),
style={'width': '100%', 'height': 300},
),
dcc.Textarea(
id='textsymbol',
value=(str(symbol)),
style={'width': '100%', 'height': 300},
),
html.Div(id='textarea-example-output', style={'whiteSpace': 'pre-line'})
])
if __name__ == '__main__':
for i in currenc:
con.subscribe_market_data(i, (print_data,))
app.run_server(debug=True)
The dashboard contains two text boxes, one for price, the other for symbol. I'd like to be able to have the dashboard open and those values update automatically.
Any help will be appreciated,
What you need is the Interval component. Set up the dcc.Interval for whatever time period you want, and use it as the input to a callback function. The output from that function will be the text boxes with the data you want to refresh each time the interval updates. Very basically:
app.layout = html.Div([
...
dcc.Interval(id='my-interval', interval=5000), # one tick each 5 seconds
html.Div(id='my-output', children=[]),
...
])
#app.callback(Output('my-output', 'children'),
[Input('my-interval', 'n_intervals')])
def callback_func(interval):
# make your calls to get the data
return [html.Div([
# the data content in here
])
Is it possible to have a text field at the bottom of a graph in dash that displays the text for the point they are on (showing hover data as plain text). So the text box will be able to make changes when users hover over a certain point. I have defined a dcc.Graph component and the app layout but am not sure how to define the callback function for the hoverdata.
I have used the below code to define dcc.Graph and app.layout
fig = go.Figure(data=plot_data, layout=plot_layout)
app.layout = html.Div([
dcc.Graph(figure=fig),
html.Div([
dcc.Markdown(id='mpg-metrics')
],style={'width':'20%','display':'inline-block'})
])
Any help with the callback will be great. thanks in advance
Yes, that's very possible! Since you haven't provided a complete description of your setup, I've put together a minimal example that draws on elements from dash.plotly.com/interactive-graphing and https://community.plotly.com/: Use Hover Trace As Input for Callback that among other things describes the use of hover data in callbacks. The code snippet below will produce the following app for JupyterDash. If you'd like to run a standard dash app, just rewrite it following these steps.
The solution I've put together should do exactly what you're aiming for. Every time you hover over a point on one of the lines in the figure in the dcc.Graph component, a set of details about the trace is displayed in the html.Pre component under it, such as x and y values. Try it out and let me know how it works out for you!
App 1:
If you'd like to retrieve only certain elements of the output, you can subset the output like this:
json.dumps({'Date:':hoverData['points'][0]['x'],
'Value:':hoverData['points'][0]['y']}, indent = 2)
App 2:
Complete code for JupyterDash, App1
import json
from textwrap import dedent as d
import pandas as pd
import plotly.graph_objects as go
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
from dash.dependencies import Input, Output
from jupyter_dash import JupyterDash
# app info
app = JupyterDash(__name__)
styles = {
'pre': {
'border': 'thin lightgrey solid',
'overflowX': 'scroll'
}
}
# data and basic figure
x = np.arange(20)+10
fig = go.Figure(data=go.Scatter(x=x, y=x**2, mode = 'lines+markers'))
fig.add_traces(go.Scatter(x=x, y=x**2.2, mode = 'lines+markers'))
app.layout = html.Div([
dcc.Graph(
id='basic-interactions',
figure=fig,
),
html.Div(className='row', children=[
html.Div([
dcc.Markdown(d("""
Click on points in the graph.
""")),
html.Pre(id='hover-data', style=styles['pre']),
], className='three columns'),
])
])
#app.callback(
Output('hover-data', 'children'),
[Input('basic-interactions', 'hoverData')])
def display_hover_data(hoverData):
return json.dumps(hoverData, indent=2)
app.run_server(mode='external', port = 8070, dev_tools_ui=True,
dev_tools_hot_reload =True, threaded=True)
Complete code for JupyterDash, App2
import json
from textwrap import dedent as d
import pandas as pd
import plotly.graph_objects as go
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
from dash.dependencies import Input, Output
from jupyter_dash import JupyterDash
# app info
app = JupyterDash(__name__)
styles = {
'pre': {
'border': 'thin lightgrey solid',
'overflowX': 'scroll'
}
}
# data and basic figure
y = np.arange(100)+10
x = pd.date_range(start='1/1/2021', periods=len(y))
fig = go.Figure(data=go.Scatter(x=x, y=y**2, mode = 'lines+markers'))
fig.add_traces(go.Scatter(x=x, y=y**2.2, mode = 'lines+markers'))
app.layout = html.Div([
dcc.Graph(
id='basic-interactions',
figure=fig,
),
html.Div(className='row', children=[
html.Div([
dcc.Markdown(d("""
Click on points in the graph.
""")),
html.Pre(id='hover-data', style=styles['pre']),
], className='three columns'),
])
])
#app.callback(
Output('hover-data', 'children'),
[Input('basic-interactions', 'hoverData')])
def display_hover_data(hoverData):
try:
return json.dumps({'Date:':hoverData['points'][0]['x'],
'Value:':hoverData['points'][0]['y']}, indent = 2)
except:
return None
app.run_server(mode='external', port = 8070, dev_tools_ui=True,
dev_tools_hot_reload =True, threaded=True)
When I run the code i get the graph but the graph is not getting updated i am calling the data from my sql laptop sql management studio.
Kindly let me know what needs to be done the X axis contains date and time and Y axis contains data in numeric form which is getting updated automatically
Code:
import pandas as pd
import pyodbc
import numpy as np
server ='LAPTOP-OO3V36UA\SQLEXPRESS'
db='addy'
conn=pyodbc.connect('DRIVER={SQL Server}; SERVER=' +server + ';DATABASE=' + db +
';Trusted_connection=yes')
sql="""
SELECT * FROM Summry
"""
df=pd.read_sql(sql ,conn)
import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
from random import random
import plotly
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(id='live-update-graph-scatter', animate=True),
dcc.Interval(
id='interval-component',
interval=1*1000
)
])
#app.callback(Output('live-update-graph-scatter', 'figure'),
[Input('interval-component', 'interval')])
def update_graph_scatter():
df=pd.read_sql(sql ,conn)
trace1=go.Scatter(
y=df['ACL'],
x = df['DateandnTime'],
mode='lines',
name='ACL'
)
layout = go.Layout(
title='Daily Monitoring'
)
return {'data': trace1, 'layout': layout}
if __name__ == '__main__':
app.run_server()
You've set your callback's input to
Input('interval-component', 'interval')
But you want
Input('interval-component', 'n_intervals')
The interval property sets how frequently n_intervals gets updated. The change in n_intervals is what can be used to trigger the callback.
Here's the documentation: https://dash.plotly.com/dash-core-components/interval