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)
Related
I want to update my DataFrame that feeds my graphs in realtime. In all the tutorials I have found, the DataFrame is created before creating the app layout. I want to take the input from the input component with the username_input ID and use that in the get_dataFrame function to create my initial DataFrame which will create the figure which will be used in the graph component.
app = Dash(__name__)
df = get_dataFrame(username_input)
fig = px.line(df, x='end', y="user",color="class")
app.layout = html.Div(children=[
dcc.Input(
id="username_input",
placeholder="username",
type='text'
),
dcc.Graph(
id='example-graph',
figure=fig
),
])
I don't fully understand how to structure the code so that this is possible. In essence I want a user input first and then after the user input all the dash data updates to reflect the new input. Any ideas?
Move your dataframe and figure creation into your callback, then return a new figure after the user's input comes in. Working example:
from dash import Dash, dcc, html, Input, Output, no_update
import pandas as pd
import plotly.express as px
import numpy as np
app = Dash(__name__)
def get_dataFrame(username_input):
data = np.random.rand(10) * len(username_input)
return pd.DataFrame({"end": [*range(10)], "user": data, "class": ["red"] * 10})
fig = px.line()
app.layout = html.Div(
children=[
dcc.Input(id="username_input", placeholder="username", type="text"),
dcc.Graph(id="example-graph", figure=fig),
]
)
#app.callback(
Output("example-graph", "figure"), Input("username_input", "value"),
)
def func(username_input: str):
if username_input:
df = get_dataFrame(username_input)
fig = px.line(df, x="end", y="user", color="class")
return fig
return no_update
if __name__ == "__main__":
app.run(debug=True)
I recently wrote a dash program
it is refreshing number of records and refreshes or redraws the fig
the problem is when I do filter over 1 or multiple legends it won't show any of the points
but when you hover over invisible points it shows the data of the point
my code:
from threading import Event
import dash
from dash import dcc, Input, Output
from dash import html
from dash.dcc.Interval import Interval
import plotly.express as px
import pandas as pd
import sqlalchemy
app = dash.Dash(__name__)
# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
connection = sqlalchemy.create_engine('mysql+pymysql://*:*#localhost:*')
df = pd.read_sql_table('rawdata_clean', connection)
fig = px.scatter(df, x="Size", y="Price", color="Neighbourhood_Per")
index = df.index
app.layout = html.Div(children=[
html.H1(id='Numberofrecords', children= len(index)),
dcc.Interval(id='up-Numberofrecords', interval=3000, n_intervals=0),
html.Div(children='''
Dash: A web application framework for Python.
'''),
dcc.Graph(
id='grph',
animate=True
),
dcc.Interval(id='up-graph', interval=3000, n_intervals=0)
])
#app.callback(Output('grph', 'figure'),
Input('up-graph', 'n_intervals'))
def update_graph (n):
df = pd.read_sql_table('rawdata_clean', connection)
fig = px.scatter(df, x="Size", y="Price", color="Neighbourhood_Per")
return fig
#app.callback(Output('Numberofrecords', 'children'),
Input('up-Numberofrecords', 'n_intervals'))
def up_Numberofrecords (n):
df = pd.read_sql_table('rawdata_clean', connection)
index = df.index
print('up_Numberofrecords')
return len(index)
if __name__ == '__main__':
app.run_server(debug=True, port=9876)
is there any problems with this code?
i'm new to dash and plotly :D
the problem was :
animate=True
IDK what this code does but by deleting it, it get to work
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
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()