Python Plotly Dash Live Streaming - python

I’m new to Dash. But I really loved the way it works.
I’m trying to implement a certain live streaming code for stocks which plots the graph by reading it from an external dictionary variable.
I’m sure that I get data continuously. However, this live streaming works perfectly only for 15 minutes and then it stops working. I have to restart the app which I’m not interested in doing so.
Please guide me to solve this.
Also, if I zoom during streaming, it resets my scale because of interval time. How can I fix this ?
Here is my code:
# Import statements
# Importing external python script which is useful in handling the stock data
from StockData import StockData
# dash is an open source graph and dashboard building framework using PlotLy and Flask
import dash
# dcc contains the core graph components
import dash_core_components as dcc
# for javascript and css especially for html components such as id and div
import dash_html_components as html
# for live events
from dash.dependencies import Event
# working with data-frames and datetime series
import pandas as pd
class ChartPlot:
"""
Everything related to plotting chart should be inside this class
Once I initiate the class from the Main.py file, it should start plotting
StockData.data_dictionary has the data
"""
def __init__(self, title="STOCK CHARTS"):
"""
Initialising the dash app
:param title: title of the graph
"""
# Name of the app - stock-tickers
app = dash.Dash('stock-tickers')
# TITLE OF THE APP - THAT WILL BE REFLECTED ON THE TAB
app.title = title
external_css = ["https://fonts.googleapis.com/css?family=Product+Sans:400,400i,700,700i",
"https://cdn.rawgit.com/plotly/dash-app-stylesheets/2cc54b8c03f4126569a3440aae611bbef1d7a5dd/stylesheet.css"]
for css in external_css:
app.css.append_css({"external_url": css,
'modeBarButtonsToRemove': ['sendDataToCloud'], 'displaylogo': False})
def plot_live(self, stock_symbols=StockData.symbol_list, hostname='127.0.0.1', port=5000):
app = self.app
# LAYOUT OF OUR APPLICATION
app.layout = html.Div([
# THE FIRST LINE DESIGN
html.Div([
html.H2('STOCK CHARTS',
# styling can be customised here for title
style={'display': 'inline',
'float': 'left',
'font-size': '2.65em',
'margin-left': '7px',
'font-weight': 'bolder',
'font-family': 'Product Sans',
'color': "rgba(117, 117, 117, 0.95)",
'margin-top': '20px',
'margin-bottom': '0'
})
]),
# DROP DOWN FROM THE AVAILABLE TICKERS
# we are using the stock_symbols from the stock_symbols StockData.symbol_list
dcc.Dropdown(
id='stock-ticker-input',
options=[{'label': s, 'value': s}
for s in stock_symbols],
# DEFAULT VALUE - CAN BE EMPTY AS WELL
value=[stock_symbols[0]],
# INDICATES MULTIPLE SELECTION IS POSSIBLE
multi=True
),
dcc.Checklist(
id='check-list-input',
options=[
{'label': 'High', 'value': 'High'},
{'label': 'Low', 'value': 'Low'}
],
values=['High', 'Low'],
labelStyle={'display': 'inline-block'}
),
# WHERE THE GRAPHS ARE APPEARED
html.Div(id='graphs'),
# INTERVAL FOR UPDATING
dcc.Interval(
id='graph-update',
# 1000 MILLI-SECONDS
interval=1 * 1000
),
], className="container")
# BOOTSTRAP CONTAINER CLASS
# CALL BACK FUNCTION DECORATOR - DEFAULT
#app.callback(
# WHERE THE OUTPUT IS EXPECTED
dash.dependencies.Output('graphs', 'children'),
# WHAT IS THE INPUT FOR THE OUTPUT
[dash.dependencies.Input('stock-ticker-input', 'value'),
dash.dependencies.Input('check-list-input', 'values')],
# ANY SPECIFIC EVENTS - HERE UPDATING BASED ON INTERVAL
events=[Event('graph-update', 'interval')])
def update_graph(symbols, checkers):
"""
This plots the graphs based on the symbol selected
:param symbols: list of available symbols
:return: graphs with high and low values
"""
# Total graphs
graphs = list()
# where all the data is present
data = list()
# running through the selected tickers
for i, symbol in enumerate(symbols):
# StockData has data_dictionary with symbols as keys containing time stamp, high and low data for particular key
data_dictionary = StockData.data_dictionary[symbol]
# Extracting data out of selected data frame
if len(checkers) == 2:
graph_data = [{'x': pd.to_datetime(data_dictionary['Time Stamp']), 'y': data_dictionary['High'],
'type': 'line', 'name': str(symbol) + " High"},
{'x': pd.to_datetime(data_dictionary['Time Stamp']), 'y': data_dictionary['Low'],
'type': 'line', 'name': str(symbol) + ' Low'}]
elif 'High' in checkers:
graph_data = [{'x': pd.to_datetime(data_dictionary['Time Stamp']),
'y': data_dictionary['High'],
'type': 'line', 'name': str(symbol) + " High"}]
elif 'Low' in checkers:
graph_data = [{'x': pd.to_datetime(data_dictionary['Time Stamp']),
'y': data_dictionary['Low'],
'type': 'line', 'name': str(symbol) + ' Low'}]
else:
graph_data = None
# adding to total data
data.extend(graph_data)
# DRAWING THE GRAPH
graphs = [dcc.Graph(
figure={
'data': data,
'layout': {"hovermode": "closest", "spikesnap": "cursor",
"xaxis": {"showspikes": True, "spikemode": "across"},
"yaxis": {"showspikes": True, "spikemode": "across"}}
},
config={'modeBarButtonsToRemove': ['sendDataToCloud'], 'displaylogo': False}
)]
return graphs
app.run_server(debug=True, host=hostname, port=port)
Kindly let me know if I’m doing it wrong anywhere

Based on the Dash documentation snippet
events=[Event('graph-update', 'interval')])
should be:
events=[Event('graph-update', 'n_intervals')])
This seems to be a common hiccup in live streaming dash code... Hope this helps!

Related

What can I do to avoid race conditions for multiple callbacks in plotly?

I have a dashboard very similar to this one-
import datetime
import dash
from dash import dcc, html
import plotly
from dash.dependencies import Input, Output
# pip install pyorbital
from pyorbital.orbital import Orbital
satellite = Orbital('TERRA')
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div(
html.Div([
html.H4('TERRA Satellite Live Feed'),
html.Div(id='live-update-text'),
dcc.Graph(id='live-update-graph'),
dcc.Interval(
id='interval-component',
interval=1*1000, # in milliseconds
n_intervals=0
)
])
)
# Multiple components can update everytime interval gets fired.
#app.callback(Output('live-update-graph', 'figure'),
Input('live-update-graph', 'relayout'),
Input('interval-component', 'n_intervals'))
def update_graph_live(relayout, n):
if ctx.triggered_id == 'relayout':
* code that affects the y axis *
return fig
else:
satellite = Orbital('TERRA')
data = {
'time': [],
'Latitude': [],
'Longitude': [],
'Altitude': []
}
# Collect some data
for i in range(180):
time = datetime.datetime.now() - datetime.timedelta(seconds=i*20)
lon, lat, alt = satellite.get_lonlatalt(
time
)
data['Longitude'].append(lon)
data['Latitude'].append(lat)
data['Altitude'].append(alt)
data['time'].append(time)
# Create the graph with subplots
fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2)
fig['layout']['margin'] = {
'l': 30, 'r': 10, 'b': 30, 't': 10
}
fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}
fig.append_trace({
'x': data['time'],
'y': data['Altitude'],
'name': 'Altitude',
'mode': 'lines+markers',
'type': 'scatter'
}, 1, 1)
fig.append_trace({
'x': data['Longitude'],
'y': data['Latitude'],
'text': data['time'],
'name': 'Longitude vs Latitude',
'mode': 'lines+markers',
'type': 'scatter'
}, 2, 1)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
In my case, I have three different intputs. One input gets triggered by an dcc.interval timer, like in the example. Another input gets triggered when a user zooms in on the dashboard using the Input('live-update-graph', 'relayoutData' input and the last triggeres when a button gets pressed.
All three inputs are totally independent. One updates the data stored in fig['data'], another updates the data stored in fig['layout']['xaxis'] and the last updates the stuff in fig['layout']['yaxis'].
I am concerned about the this situation:
The dcc interval input gets triggered and the function starts to update the data
The user zooms in on the dashboard and triggers the relayout data
The dcc.interval returns a figure
Now, because the relayout input got triggered second, it has stale data. There is a race condition and it is possible that the dcc interval gets undone as a result.
What can I do to avoid the race condition? I wonder if it's possible to update only a part of the figure with a callback rather than editing the whole object.
I think this code does what you want. Update data, while keeping layout. You can adapt to exactly what you would like, your example is copied anyhow and not really working (ex: you have a ctx there that is not defined)
The idea of the code below is: rather than update the complete object server side (in the callback) have different "parts" of the object (data-patch1, data-patch2, etc) and "merge" them in the browser (see deep_merge).
Depending on what you want to keep/adjust you can adjust that function and fill accordingly the data-patch.
For the code below you can just zoom in/zoom out, but you could also patch colors, sizes, etc.
# From https://github.com/plotly/dash-core-components/issues/881
import dash
import datetime
import random
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
import plotly.express as px
import plotly.graph_objects as go
import plotly
figure = go.Figure()
app = dash.Dash(__name__)
app.layout = html.Div(children = [
html.Div(id="patchstore",
**{'data-figure':figure, 'data-patch1':{}, 'data-patch2':{}, 'data-patch3':{}}),
dcc.Graph(id="graph"),
dcc.Interval(
id='interval-component',
interval=2*1000, # in milliseconds
n_intervals=0)
])
deep_merge = """
function batchAssign(patches) {
function recursiveAssign(input, patch){
var outputR = Object(input);
for (var key in patch) {
if(outputR[key] && typeof patch[key] == "object" && key!="data") {
outputR[key] = recursiveAssign(outputR[key], patch[key])
}
else {
outputR[key] = patch[key];
}
}
return outputR;
}
return Array.prototype.reduce.call(arguments, recursiveAssign, {});
}
"""
app.clientside_callback(
deep_merge,
Output('graph', 'figure'),
[Input('patchstore', 'data-figure'),
Input('patchstore', 'data-patch1'),
Input('patchstore', 'data-patch2'),
Input('patchstore', 'data-patch3')]
)
#app.callback(Output('patchstore', 'data-patch1'),[Input('interval-component', 'n_intervals')])
def callback_data_generation(n_intervals):
data = {
'time': [],
'Latitude': [],
'Longitude': [],
'Altitude': []
}
# Collect some data
for i in range(30):
time = datetime.datetime.now() - datetime.timedelta(seconds=i*20)
data['Longitude'].append(random.randint(1,10))
data['Latitude'].append(random.randint(1,10))
data['Altitude'].append(random.randint(1,10))
data['time'].append(time)
# Create the graph with subplots
fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2)
fig['layout']['margin'] = {
'l': 30, 'r': 10, 'b': 30, 't': 10
}
fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}
fig.append_trace({
'x': data['time'],
'y': data['Altitude'],
'name': 'Altitude',
'mode': 'lines+markers',
'type': 'scatter'
}, 1, 1)
fig.append_trace({
'x': data['Longitude'],
'y': data['Latitude'],
'text': data['time'],
'name': 'Longitude vs Latitude',
'mode': 'lines+markers',
'type': 'scatter'
}, 2, 1)
if n_intervals==0:
fig.layout = None
return fig
app.run_server()

How can I use multiple datasets in the dash app to visualize a graph?

I am building a dash app. I want to viz a graph for crypto data (being extracted from APIs). The dash dropdowns contain different crypto ticker symbols & on that basis, I want to showcase different graphs. For e.g, if a user selects ETH in the dropdown, the API will extract the eth market price data & feeds it to the dash app so the user can see the graph, but I am struggling with using multiple datasets with the dropdowns.
So far, I think a dropdown is used to change the property of 1 dataset via changing rows, limits, etc. but unable to choose between multiple datasets.
I am looking for a method to show market price graphs for different cryptocurrencies through the dash app.
########################### Importing Libraries #############################################
import numpy as np
import pandas as pd
from dash import dcc,html,Dash
import plotly.express as px
import warnings
warnings.filterwarnings("ignore")
from api_to_df import open_df,high_df,low_df,close_df,volume_df,mkt_cap_df
###########################################################################################
# Defining app name
app = Dash(__name__)
colors = {
'background': '#231F20',
'text': '#ADD8E6'
}
############### Defining elements for dropdowns ####################################################
ticker_list = ['ETH', 'XRP','BTC','LTC','LRC','DOT','MANA','EGLD','SHIB','SOL','TFUEL','ICP','SAND','MATIC']
type_list = ['Open', 'High','Low','Close','Volume','Mkt cap']
currency_list = ['USD']
############################################################################################################
markdown_text = '''
Koin is a webapp focussed at providing crypto coin data to crypto newbies in a simple yet elegant fashion.
'''
def generate_table(dataframe, max_rows=15):
'''
generate_table function is used to parse pandas dataframes into html tables.
'''
return html.Table([
html.Thead(
html.Tr([html.Th(col) for col in dataframe.columns])
),
html.Tbody([
html.Tr([
html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
]) for i in range(min(len(dataframe), max_rows))
])
])
#fig = px.bar(open_df, x="date", y="open",barmode = "group")
fig = px.line(open_df, x="date", y="open",markers = 1)
# Updating the layout of the figure
fig.update_layout(
plot_bgcolor=colors['background'],
paper_bgcolor=colors['background'],
font_color=colors['text']
)
#fig.update_traces(marker=dict(size=12,
# line=dict(width=2,
# color='Red')),
# selector=dict(mode='markers'))
# Div is used to create divisions in an html block
# children is a subbranch of an Division tree
app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
# H1 is header 1 i.e Heading of the webapp
html.H1(
children='KOIN',
style={
'textAlign': 'center',
'color': colors['text']
}
),
# style is used to style a particular dash/html component
html.Div(children='Your Koin, Our Data', style={
'textAlign': 'center',
'color': colors['text']
}),
#dcc.markdown is used to add markdown/text info to the frontend
html.Div(children =[dcc.Markdown(children=markdown_text,style={
'textAlign': 'center',
'color': colors['text'] } )]),
#Inside children branch, a dcc dropdown component is created to add filters
html.Div(children =[html.Label('Ticker symbol'),
dcc.Dropdown(ticker_list,style={'color':'#000000'})
],
style={'color': colors['text'],'padding': 10, 'flex': 1}
),
html.Div(children =[html.Label('Data type'),
dcc.Dropdown(type_list,style={'color':'#000000'})
],
style={'color': colors['text'],'padding': 10, 'flex': 1}
),
html.Div(children = [html.Label('Currency'),
dcc.Dropdown(currency_list,style={'color':'#000000'})
],
style={'color': colors['text'],'padding': 10, 'flex': 1}
),
html.H2(children='ETH opening price',style={'color':colors['text']}),
# Adding generate_table function to html division
html.Div(generate_table(open_df),style={'color':colors['text']}),
#dcc.graph is used to parse plotly graphs to html
dcc.Graph(
id='open graph',
figure=fig
)
]
)
if __name__ =="__main__":
app.run_server(debug=True)enter code here
You need a callback that listens to the dropdown and builds a graph for each value selected. It should loop over the selected values, and append a graph to the output value for each one.

Dash python dynamic

I try to do a dashboard on python dash.
I succeeded the front-end. Indeed, I made appear a "year selector" but I do not understand how to change the graph depending on this year selector. Is anyone has idea or an explaination ? Thanks a lot.
#
# Imports
#
import plotly_express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
#
# Data
if __name__ == '__main__':
app = dash.Dash(__name__) # (3)
fig = px.bar(df2, x="dpe", y="Percentage", color="signature") # (4)
app.layout = html.Div(children=[
html.H1(children=f'Répartition des Leads DEC',
style={'textAlign': 'center', 'color': '#7FDBFF'}), # (5)
html.Label('Year'),
dcc.Dropdown(
id="year-dropdown",
options=[
{'label': '2019', 'value': 2019},
{'label': '2020', 'value': 2020},
{'label': '2021', 'value': 2021},
{'label': '2022', 'value': 2022},
],
value=2022,
),
dcc.Graph(
id='graph1',
figure=fig
), # (6)
html.Div(children=f'''
This a graph which show the repartition of the DPE
'''), # (7)
]
)
#
# RUN APP
#
app.run_server(debug=False, port =4056) # (8)```
You need to use callbacks for the selection of dropdowns to appear. Check out the official documentation
You need to use callback to make you fig be interactive:
Change your dcc.Graph to: dcc.Graph(id='graph1',figure={})
Call back
#app.callback(Output('graph1', 'figure'),[Input('year-dropdown', 'value')]) def update_graph_1(year_dropdown): df2 = df2[(df2['Year'] == year_dropdown)] (# I dont see your dataframe so you will need to change this code) fig = px.bar(df2, x="dpe", y="Percentage", color="signature") return fig

MongoDb, Dash and Python

I can't get this code to run and I am supposed to get a couple of things to work. First, a data table which I managed to get up and get to work. Then I created a few buttons so I can filter the data table. The buttons don't do anything to change the data table, I need to get them to work. Second, I am trying to get a pie chart to work and have it be interactive with the data table. The pie chart does not render. Lastly, I need a geolocation chart that interacts with the data table as well. The data table has a lateral location and a longitude location. geolocation doesn't render either*
from jupyter_plotly_dash import JupyterDash
import dash
import dash_leaflet as dl
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import dash_table as dt
from dash.dependencies import Input, Output, State
import os
import numpy as np
import pandas as pd
from pymongo import MongoClient
from bson.json_util import dumps
# change animal_shelter and AnimalShelter to match your CRUD Python module file name and class name
from AnimalShelter import AnimalShelter
import base64
###########################
# Data Manipulation / Model
###########################
# FIX ME change for your username and password and CRUD Python module name
username = "aacuser"
password = "42213"
shelter = AnimalShelter(username, password)
# class read method must support return of cursor object
df = pd.DataFrame.from_records(shelter.read())
#########################
# Dashboard Layout / View
#########################
app = JupyterDash('SimpleExample')
#FIX ME Add in Grazioso Salvare’s logo
image_filename = 'Grazioso Salvare Logo.png' # replace with your own image
encoded_image = base64.b64encode(open(image_filename, 'rb').read())
#FIX ME Place the HTML image tag in the line below into the app.layout code according to your design
#FIX ME Also remember to include a unique identifier such as your name or date
#html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode()))
app.layout = html.Div([
html.Div(id='hidden-div', style={'display':'none'}),
html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode())),
html.Center(html.B(html.H1('Willi Blanco CS-340 Dashboard'))),
html.Hr(),
html.Div(
#FIXME Add in code for the interactive filtering options. For example, Radio buttons, drop down, checkboxes, etc.
className='row',
style={'display': 'flex'},
children=[
html.Button(id='submit-button-one',n_clicks=0, children= 'Water Rescue'),
html.Button(id='submit-button-two',n_clicks=0, children= 'Mountain or Wilderness Rescue'),
html.Button(id='submit-button-three',n_clicks=0, children='Disaster Rescue or Individual Tracking'),
html.Button(id='submit-button-four', n_clicks=0, children='reset')
]
),
html.Hr(),
dt.DataTable(
id='datatable-id',
columns=[
{"name": i, "id": i, "deletable": False, "selectable": True} for i in df.columns
],
data=df.to_dict('records'),
#FIXME: Set up the features for your interactive data table to make it user-friendly for your client
#If you completed the Module Six Assignment, you can copy in the code you created here
page_size=100,
style_table={'height':'300px','overflowY':'auto','overflowX':'auto'},
style_header={
'backgroundColor':'rgb(230,230,230)',
'fontWeight':'bold'
},
style_data={
'whiteSpace':'normal',
'height':'auto'
},
#tooltips that we are going to use on the table so that we know what information we are looking at
tooltip ={i: {
'value': i,
'use_with': 'both' # both refers to header & data cell
} for i in df.columns},
tooltip_delay=0,
tooltip_duration = None,
#sorting features that we are going to use
sort_action='native',
sort_mode='multi',
filter_action='native',
editable=False,
column_selectable=False,
row_selectable='single',
row_deletable=False,
selected_rows=[],
),
html.Br(),
html.Hr(),
#This sets up the dashboard so that your chart and your geolocation chart are side-by-side
html.Div(className='row',
style={'display' : 'flex'},
children=[
html.Div(
id='graph-id',
className='col s12 m6',
),
html.Div(
id='map-id',
className='col s12 m6',
)
])
])
#############################################
# Interaction Between Components / Controller
#############################################
#app.callback([Output('datatable-id','data')],
[Input('submit-button-one', 'n_clicks'),Input('submit-button-two','n_clicks'),
Input('submit-button-three','n_clicks'),Input('submit-button-four','n_clicks')])
def update_dashboard(bt1,bt2,bt3,bt4):
### FIX ME Add code to filter interactive data table with MongoDB queries
if (int(bt1) >= 1):
df = pd.Dataframe.from_records(shelter.read({'$and': [
{'$or': [ {'breed':'Labrador Retriever Mix'}, {'breed':'Chesapeake Bay Retriever'},
{'breed':'Newfoundland'}]},
{'sex_upon_outcome':'Intact Female'}, {'age_upon_outcome_in_weeks':{'$lte':26, 'gte':156}}]}))
bt2, bt3, bt4 = 0
elif (int(bt2)>= 1):
df = pd.Dataframe.from_records(shelter.read({'$and': [
{'$or': [ {'breed':'German Shepherd'}, {'breed':'Alaskan Malamute'},
{'breed':'Old English Sheepdog'},{'breed':'Siberian Husky'},{'breed':'Rottweiler'}]},
{'sex_upon_outcome':'Intact Male'}, {'age_upon_outcome_in_weeks':{'$lte':26, 'gte':156}}]}))
bt1, bt3 ,bt4 = 0
elif (int(bt3)>=1):
df = pd.Dataframe.from_records(shelter.read({'$and': [
{'$or': [ {'breed':'Doberman Pinscher'}, {'breed':'German Sheperd'},
{'breed':'Golden Retriever'},{'breed':'Bloodhound'},{'breed':'Rottweiler'}]},
{'sex_upon_outcome':'Intact Male'}, {'age_upon_outcome_in_weeks':{'$lte':20, 'gte':300}}]}))
bt1, bt2, bt4 = 0
elif(int(bt4)>=1):
df = pd.Dataframe.from_records(shelter.read())
bt1, bt2, bt3 = 0
columns=[{"name": i, "id": i, "deletable": False, "selectable": True} for i in df.columns]
data=df.to_dict('records')
return data
#app.callback(
Output('datatable-id', 'style_data_conditional'),
[Input('datatable-id', 'selected_columns')]
)
def update_styles(selected_columns):
return [{
'if': { 'column_id': i },
'background_color': '#D2F3FF'
} for i in selected_columns]
#app.callback(
Output('graph-id', "children"),
[Input('datatable-id', "derived_viewport_data")])
def update_graphs(viewData):
###FIX ME ####
# add code for chart of your choice (e.g. pie chart)
df = pd.DataFrame.from_dict(viewData)
return [
dcc.Graph(
figure = px.pie(df, values=values, names=names, title='Percentage of breeds available')
)
]
#app.callback(
Output('map-id', "children"),
[Input('datatable-id', "derived_viewport_data"),
Input('datatable-id',"derived_viewport_selected_rows")])
def update_map(viewData):
#FIXME: Add in the code for your geolocation chart
#If you completed the Module Six Assignment, you can copy in the code you created here.
viewDF = pd.DataFrame.from_dict(viewData)
dff = viewDF.loc[rows]
return [ dl.Map(style={'width': '1000px', 'height': '500px'}, center=[dff.loc[0,'location_lat'],dff.loc[0,'location_long']], zoom=15, children=[
dl.TileLayer(id="base-layer-id"),
# Marker with tool tip and pop up
dl.Marker(position=[dff.loc[0,'location_lat'],dff.loc[0,'location_long']], children=[
dl.Tooltip(dff['breed']),
dl.Popup([
html.H1("Animal Name"),
html.P(dff.loc[0,'name'])
])
])
])]
app
In the #app.callback([Output('datatable-id','data')], add [Input('filter-type', 'value')]).
Also, in the callback before update_map, remove Input('datatable-id',"derived_viewport_selected_rows")]). Try: #app.callback(Output('map-id', "children"), [Input('datatable-id', "derived_viewport_data")])

Create Dropdown with label and values using panda library and Dash Plotly in python

I am using panda library in Python to read from a csv file and fill a Dropdown. My application uses Dash Plotly to create a HTML web interface. I am filling with only the values of the Dropdown, the labels of the Dropdown are the same of the values. How do I change the labels to be the text from the csv file?
available_rpi.csv
ip,name
192.168.1.6,"Virtual I²C (192.168.1.6)"
192.168.1.102,"GPS UART (192.168.1.102)"
192.168.1.106,"Ultrasonic I²C (192.168.1.103)"
python script:
import dash,requests,pandas as pd
df = pd.read_csv('available_rpi.csv', usecols = ['ip','name'])
available_rpi = df['ip'].unique()
app.layout = html.Div( [
html.H1(children='RESENSE'),
html.Div(children='''RESENSE: Transparent Record and Replay in the Internet of Things (IoT).'''),
# html.Div(['Name : ', dcc.Input(id='input',value='ACC',type='text') ]),
# dcc.Markdown(''' '''),
html.Label('Raspberry Pi'),
dcc.Dropdown(
id = "input",
options=[{'label': i, 'value': i} for i in available_rpi],
value=''
),
html.Div(id='output'),
# Graph for arriving data (static)
dcc.Graph(id='data', animate=True),
dcc.Interval(id='graph-update',interval=2*1000)
])
How about reading the CSV data in a bit different way with pandas and storing it in a dictionary?
import dash
import pandas as pd
import dash_core_components as dcc
import dash_html_components as html
df = pd.read_csv('available_rpi.csv', usecols = ['ip','name'])
available_rpi = df.to_dict('records')
app = dash.Dash(__name__)
app.layout = html.Div( [
html.H1(children='RESENSE'),
html.Div(children='''RESENSE: Transparent Record and Replay in the Internet of Things (IoT).'''),
# html.Div(['Name : ', dcc.Input(id='input',value='ACC',type='text') ]),
# dcc.Markdown(''' '''),
html.Label('Raspberry Pi'),
dcc.Dropdown(
id = "input",
options=[{'label': i['name'], 'value': i['ip']} for i in available_rpi],
value=''
),
html.Div(id='output'),
# Graph for arriving data (static)
dcc.Graph(id='data', animate=True),
dcc.Interval(id='graph-update',interval=2*1000)
])
if __name__ == '__main__':
app.run_server()
You should store your .csv file as a list of dictionaries using orient='records' and then use a list comprehension to set your options for your Dropdown component:
import dash
import pandas as pd
import dash_core_components as dcc
import dash_html_components as html
available_rpi = pd.read_csv('available_rpi.csv').to_dict(orient='records')
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1(children='RESENSE'),
html.Div(children='''RESENSE: Transparent Record and Replay in the Internet of Things (IoT).'''),
html.Label('Raspberry Pi'),
dcc.Dropdown(
id = "input",
options=[{'label': i['name'], 'value': i['ip']} for i in available_rpi],
value=''
),
html.Div(id='output'),
#Graph for arriving data (static)
dcc.Graph(id='data', animate=True),
dcc.Interval(id='graph-update',interval=2*1000)
])
if __name__ == '__main__':
app.run_server()
I have to use a dictionary....
available_rpi = pd.read_csv('available_rpi.csv', header=None, dtype={0: str}).set_index(0).squeeze().to_dict()
#print("Raspberry Pi's available:")
#for key, car in available_rpi.items():
# print('{} : {}'.format(key, car))
app.layout = html.Div( [
html.H1(children='RESENSE'),
html.Div(children='''RESENSE: Transparent Record and Replay in the Internet of Things (IoT).'''),
# html.Div(['Name : ', dcc.Input(id='input',value='ACC',type='text') ]),
# dcc.Markdown(''' '''),
html.Label('Raspberry Pi'),
dcc.Dropdown(
id = "input",
options=[{'label': v, 'value': k} for k, v in available_rpi.items()],
value=''
),
html.Div(id='output'),
# Graph for arriving data (static)
dcc.Graph(id='data', animate=True),
dcc.Interval(id='graph-update',interval=2*1000)
])

Categories

Resources