Bar graph with editable dash table - python

I'm trying to make a bar graph with editable dash table but graph changes for just once time. After changing data in table, graph be updated but not like my expectation.
Below is my sample code:
from dash_table import DataTable
from dash.dependencies import Input, Output
import dash
import dash_html_components as html
import dash_core_components as dcc
import pandas as pd
import plotly.graph_objs as go
raw_data = {'Type': ["Cash", "Credit Card"],
'Rate': [50,50]}
test_df = pd.DataFrame(raw_data)
test_df['id'] = test_df['Type']
test_df.set_index('id', inplace=True, drop=False)
app = dash.Dash(__name__)
app.layout = html.Div(children=[
dash_table.DataTable(
id='table',
data=test_df.to_dict('records'),editable=True,
columns=[
{"name": i, "id": i, "deletable": True, "selectable": True, "hideable": True}
if i == "Type" or i == "Rate"
else {"name": i, "id": i, "deletable": True, "selectable": True}
for i in test_df.columns
],
style_cell={
'minWidth': '0px',
'maxWidth': '180px',
'whiteSpace': 'no-wrap',
'overflow': 'hidden',
'textOverflow': 'ellipsis'},
style_table={'overflowX': 'scroll'},
row_deletable=True
),
dcc.Graph(
id='plot',
style={"max-width": "600px",
"margin": "auto",
"display": "inline-block"})
])
#app.callback(Output('plot', 'figure'),
[Input('table', 'data'),
Input('table', 'columns')])
def update_graph(data, cols):
df = pd.DataFrame(data, columns=[c['name'] for c in cols])
figure_2 = go.Figure(data=[
go.Bar(x=df['Type'],
y=df['Rate'],
width=0.45,
text = df['Rate'],
textposition='inside',
marker_color='indianred')])
return figure_2
if __name__ == '__main__':
app.run_server(port=1211, debug=False)
My first time change, graph looking like this:
But from the second time, graph looking like this:
What should I do to fix this problem.
Actually I read editable docs but I still not get it. The Graph in docs is generated like this:
def display_output(rows, columns):
return {
'data': [{
'type': 'heatmap',
'z': [[row.get(c['id'], None) for c in columns] for row in rows],
'x': [c['name'] for c in columns]
}]
}
I don't know how to apply it for bar graph.
Thank you.

If you put a print statement inside your callback of data you will see on initial load the data is as expected
[{'Type': 'Cash', 'Rate': 50, 'id': 'Cash'}, {'Type': 'Credit Card', 'Rate': 50, 'id': 'Credit Card'}]
Rate holds a numeric value.
But when editing values in the datatable the value could be anything so dash table treats your input as a string and not a number.
So after editing a value in the Rate column data could now look like this
[{'Type': 'Cash', 'Rate': 50, 'id': 'Cash'}, {'Type': 'Credit Card', 'Rate': '200', 'id': 'Credit Card'}]
The value I filled in 200 is now a string in data.
It seems that when both Rate values are string values plotly doesn't know how it should draw the bars anymore.
What you could do is to convert the Rate column of df to numeric.
df['Rate'] = pd.to_numeric(df['Rate'])

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()

Create dcc.Dropdown values Dynamically with Python Function

I am creating a search application with Dash by Plotly. I have a main search function for that creates a dataframe for the whole application that is defined as:
def search(term):
with index.searcher() as searcher:
parser = QueryParser("content", index.schema)
myquery = parser.parse(term)
results = searcher.search(myquery, limit=None)
print("Documents Containing ", term, ": ", len(results), "\n")
df = pd.DataFrame([i['date'], i['site'], i['system'], i['ticket'], i.score, i['level'], i['first'], i['last'], i['department'], \
i['detect'], i['code'],i['content'], i['description'], i['owner'], i['ownerGroup'], i['docId']] for i in results)
df.columns=['Reported Date', 'Site', 'System','Ticket ID', 'Score', 'Level', 'First', 'Last', 'Department', \
'Detection', 'Code', 'Content', 'Description', 'Owner', 'Owner Group', 'Document ID']
return df
I want users to be able to filter down search results with filters built into dcc.Dropdown. A couple of them can be hard-coded like so:
dcc.Dropdown(
id='siteFilter',
options=[
{'label': 'ABC', 'value': 'ABC'},
{'label': 'DEF', 'value': 'DEF'},
{'label': 'HIJ', 'value': 'HIJ'},
{'label': 'LMO', 'value': 'LMO'}
],
value=['ABC', 'DEF', 'HIJ', 'LMO'],
multi=True
However, some of the fields I want to filter on contain many options for a search and cannot be hard-coded. I can get the options to work. However, my application will not apply the filter changing when a user changes values. So, I have in my app.layout:
html.Div(dbc.Row([dbc.Col([
html.Label(["System Filter",
dcc.Dropdown(
id='systemFilter',
options='options',
value='All',
multi=True,
)
])
], width = 5)
]))
In my callback, I have tried several different options/combos of Outputs and States to achieve this with no luck. Callback:
#app.callback(
[Output(component_id='outTable', component_property='data'),
Output(component_id='outTable', component_property='columns'),
Output(component_id='commonWords', component_property='children'),
Output(component_id='systemFilter', component_property='options'),
#Output(component_id='systemFilter', component_property='value')
],
[Input(component_id='button', component_property='n_clicks')],
[State('searchId', 'value'),
State('siteFilter', 'value'),
State('detectFilter', 'value'),
State('levelFilter', 'value'),
State('codeFilter', 'value'),
#State(component_id='systemFilter', component_property='value')
])
def tableCreate(n_clicks, searchId, siteFilter, detectFilter, levelFilter, codeFilter):
if n_clicks > 0:
searchFrame = search(searchId)
###################### System Filter #######################################
#print('HERE DLKFSJSLDFKJSLDKJFJLKFDSJLDSKF')
#print(searchFrame['System'].unique())
#global optionsArray
optionsArray = searchFrame['System'].unique()
optionsArray = optionsArray.tolist()
print('Test')
print(optionsArray)
print('Test')
system_filter_options = [{'label': i, 'value': i} for i in optionsArray]
systemFilter = optionsArray
searchFrame = searchFrame[searchFrame['System'].isin(systemFilter)]
# Bunch of other code
searchFrame = searchFrame.drop(columns=['ContentNoStop'])
columns = [{'name': col, 'id': col} for col in searchFrame.columns]
data = searchFrame.to_dict(orient='records')
return data, columns, wordComponent, system_filter_options #, systemFilter
else:
return dash.no_update, dash.no_update, dash.no_update, dash.no_update
Essentially, one of 2 things happens. 1) The values return blank because they are not defined or 2) the options continually override the updated value parameter which I know is caused by the line systemFilter = optionsArray but I cannot seem to figure out a work around for this.
Here is an example image. I would like the results to populate all, but when a user filters by system and only selects a few, all my graphs and tables should update. But everytime, it does not seem to catch that. What am I missing here? How can the dcc.Dropdown selections be applied as a filter dynamically? I cannot and do not want to hard-code all the options
Easier reproduceable example:
I would like the dropdowns options to filter the table. If dog is selected, the table only shows dog.
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table
import pandas as pd
from dash.dependencies import Input, Output, State
external_stylesheets = [dbc.themes.BOOTSTRAP]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server
def createTable():
df = pd.DataFrame({'num_legs': [2, 4, 8, 0],
'num_wings': [2, 0, 0, 0],
'system': ['falcon', 'dog', 'spider', 'fish']},
index=[1, 2, 3, 4])
return df
app.layout = html.Div([
html.Button('Submit and Refresh', id='button', n_clicks=0, className='btn btn-primary'),
dbc.Row([dbc.Col([
html.Label(["System Filter",
dcc.Dropdown(
id='systemFilter',
options='options',
value='All',
multi=True,
)
])
], width = 5)
]),
html.Div([dash_table.DataTable(style_cell={
'whiteSpace': 'normal',
'height': 'auto',
'textAlign': 'left'
},
fill_width=False,
id='outTable',
sort_action="native",
sort_mode="multi",
column_selectable="single",
row_deletable=True,
)
],
) ])
#app.callback(
[Output(component_id='outTable', component_property='data'),
Output(component_id='outTable', component_property='columns'),
Output(component_id='systemFilter', component_property='options'),
#Output(component_id='systemFilter', component_property='value')
],
[Input(component_id='button', component_property='n_clicks')],
[
State(component_id='systemFilter', component_property='value')
])
def tableCreate(n_clicks, systemFilter):
if n_clicks > 0:
searchFrame = createTable()
optionsArray = searchFrame['system'].unique()
optionsArray = optionsArray.tolist()
print('Test')
print(optionsArray)
print('Test')
system_filter_options = [{'label': i, 'value': i} for i in optionsArray]
systemFilter = optionsArray
searchFrame = searchFrame[searchFrame['system'].isin(systemFilter)]
columns = [{'name': col, 'id': col} for col in searchFrame.columns]
data = searchFrame.to_dict(orient='records')
return data, columns, system_filter_options#, systemFilter
if __name__ == '__main__':
app.run_server(debug=False)

Plotly/Dash -- range filter resets on hoverData

I am trying capture mouse hover events using Dash. I capture the position of the mouse using hoverData.
The problem appears when I filter the time series using the range selector or the range slider. The plot correctly reduces to the selected time, but when I hover it with the mouse it resets to the main view (whole main series).
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
app.layout = html.Div([
dcc.Graph(
id='stock-plot'
),
], className="container")
#app.callback(
Output('stock-plot', 'figure'),
[Input('stock-plot', 'hoverData')])
def drawStockPrice(hoverData):
traces = [go.Scatter(
x=df.Date,
y=df['AAPL.High'],
mode='lines',
opacity=0.7,
connectgaps=True),
]
return {'data': traces,
'layout': go.Layout(colorway=["#5E0DAC", '#FF4F00', '#375CB1', '#FF7400', '#FFF400', '#FF0056'],
height=600,
title=f"Closing prices",
xaxis={"title": "Date",
'rangeselector': {'buttons': list([{'count': 1, 'label': '1M',
'step': 'month',
'stepmode': 'backward'},
{'count': 6, 'label': '6M',
'step': 'month',
'stepmode': 'backward'},
{'step': 'all'}])},
'rangeslider': {'visible': True}, 'type': 'date'},
yaxis={"title": "Price (USD)"},
)}
if __name__ == '__main__':
app.run_server(debug=True)
I am sure there should be a better solution but this is what I got (Dash v1.6.0):
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output, State
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
layout = go.Layout( colorway=["#5E0DAC", '#FF4F00', '#375CB1', '#FF7400', '#FFF400', '#FF0056'],
height=600,
title=f"Closing prices",
xaxis={"title": "Date",
'rangeselector': {'buttons': list([{'count': 1, 'label': '1M',
'step': 'month',
'stepmode': 'backward'},
{'count': 6, 'label': '6M',
'step': 'month',
'stepmode': 'backward'},
{'step': 'all'}]
),
},
'rangeslider': {'visible': True},
'type': 'date',
},
yaxis={"title": "Price (USD)"},
)
traces = [go.Scatter( x=df.Date,
y=df['AAPL.High'],
mode='lines',
opacity=0.7,
connectgaps=True
)]
app.layout = html.Div([
dcc.Graph(
id='stock-plot',
figure={
'data': traces,
'layout': layout
}
),
], className="container")
#app.callback(
Output('stock-plot', 'figure'),
[Input('stock-plot', 'hoverData'),
Input('stock-plot', 'relayoutData')],
[State('stock-plot', 'figure')]
)
def drawStockPrice(hoverData, selected, figure):
data = figure['data']
layout = figure['layout']
if selected is not None and 'xaxis.range' in selected:
layout['xaxis']['range'] = selected['xaxis.range']
return {'data': data,
'layout': layout
}
if __name__ == '__main__':
app.run_server(debug=True)

How to use Callback to update Bar Graph in Dash

Since Dash is a fairly new framework for making interactive web-based graphs, there is not too many information that are specific or detailed for beginners. In my case I need to update a simple bar graph using a callback function.
The data does not render on the browser even though the server runs fine without prompting any errors.
Need help sorting out and understanding why data does not render.
import dash
from dash.dependencies import Output, Event
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go
app = dash.Dash(__name__)
colors = {
'background': '#111111',
'background2': '#FF0',
'text': '#7FDBFF'
}
app.layout = html.Div( children = [
html.Div([
html.H5('ANNx'),
dcc.Graph(
id='cx1'
)
])
]
)
#app.callback(Output('cx1', 'figure'))
def update_figure( ):
return {
'data': [
{'x': ['APC'], 'y': [9], 'type': 'bar', 'name': 'APC'},
{'x': ['PDP'], 'y': [8], 'type': 'bar', 'name': 'PDP'},
],
'layout': {
'title': 'Basic Dash Example',
'plot_bgcolor': colors['background'],
'paper_bgcolor': colors['background']
}
}
if __name__ == '__main__':
app.run_server(debug=True)
You can use callback in a such way (I create dropdown menu for this):
import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go
import pandas as pd
app = dash.Dash(__name__)
df = pd.DataFrame({'x': ['APC', 'PDP'], 'y': [9, 8]})
colors = {
'background': '#111111',
'background2': '#FF0',
'text': '#7FDBFF'
}
app.layout = html.Div(children=[
html.Div([
html.H5('ANNx'),
html.Div(
id='cx1'
),
dcc.Dropdown(id='cx2',
options=[{'label': 'APC', 'value': 'APC'},
{'label': 'PDP', 'value': 'PDP'},
{'label': 'Clear', 'value': None}
]
)
])])
#app.callback(Output('cx1', 'children'),
[Input('cx2', 'value')])
def update_figure(value):
if value is None:
dff = df
else:
dff = df.loc[df["x"] == value]
return html.Div(
dcc.Graph(
id='bar chart',
figure={
"data": [
{
"x": dff["x"],
"y": dff["y"],
"type": "bar",
"marker": {"color": "#0074D9"},
}
],
"layout": {
'title': 'Basic Dash Example',
"xaxis": {"title": "Authors"},
"yaxis": {"title": "Counts"},
'plot_bgcolor': colors['background'],
'paper_bgcolor': colors['background']
},
},
)
)
if __name__ == '__main__':
app.run_server(debug=True)
If you write output in your calback function then you need to provide input as well, it can be, slider, date picker or dropdown menu and etc. but in your case you dont need any input and output as your graph is not dynamic in this case. check here https://dash.plot.ly/getting-started-part-2
so in your case it is enough just to put id and figure into dcc.Graph component:
import dash
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(__name__)
colors = {
'background': '#111111',
'background2': '#FF0',
'text': '#7FDBFF'
}
app.layout = html.Div( children = [
html.Div([
html.H5('ANNx'),
dcc.Graph(
id='cx1', figure={
'data': [
{'x': ['APC'], 'y': [9], 'type': 'bar', 'name': 'APC'},
{'x': ['PDP'], 'y': [8], 'type': 'bar', 'name': 'PDP'},
],
'layout': {
'title': 'Basic Dash Example',
'plot_bgcolor': colors['background'],
'paper_bgcolor': colors['background']
}}
)
])
]
)
if __name__ == '__main__':
app.run_server(debug=True)

Graphs not updating with dropdown (Dash Plotly)

I am trying to build a dashboard where the graph updates depending on the value passed in the dropdown menu.
For some reason, the graph does not adapt to any changes in the dropdown. Peculiarities about this are:
The input is for sure received: I created a second function which has the same structure but updates a different field. It works fine.
The problem seems to be with the graph display: I created a different version of the function where the update function would return "none" for the default value of 1. The area of the graph was empty at first but would change to one of the graphs when a new value was selected in the dropdown. Once a graph was shown, the field would not react to any further changes in the dropdown menu: Neither for values prompting a new graph nor for the return to the default value returning none.
This is the code:
import dash
from dash.dependencies import Output, Event
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go
from dash.dependencies import Input, Output
import collections
app = dash.Dash()
df = dm.return_all_pd_data(token = API_TOKEN)
app.layout = html.Div(children=[
html.H1(children='''
Month for graph:
'''),
dcc.Dropdown(
id = "input",
options=[
{'label': 'Jan', 'value': 1},
{'label': 'Feb', 'value': 2},
{'label': 'Mar', 'value': 3}
], value = 1
),
html.Div(id='output-graph'),
])
#app.callback(
Output(component_id='output-graph', component_property='children'),
[Input(component_id='input', component_property='value')])
def update_value(value):
start = datetime.datetime(2018, value, 1, 0, 0, 0, 1)
end = datetime.datetime(2018, value + 1, 1, 0, 0, 0, 1)
subset_df = df[ (df["lost_time"] > start) & (df["lost_time"] < end) ]
x = pd.value_counts(subset_df.deal_source).index
y = pd.value_counts(subset_df.deal_source).values
return(dcc.Graph(
id='output-graph',
figure={
'data': [
{'x': x, 'y': y, 'type': 'bar', 'name': value},
],
'layout': {
'title': "You selected month: {}".format(value)
}
}
))
if __name__ == "__main__":
app.run_server(debug = True)
I was able to find the solution myself eventually. Answering here in case somebody else might have the same problem.
The problem was that I was trying to update the children element in the div tag. Instead it proved much easier to create an empty chart and write the function to update the figure element of the chart.
Below is the code which turned out to work:
app = dash.Dash()
app.layout = html.Div(children=[
html.H1(children='''
Interactive Chart:
'''),
dcc.Dropdown(
id = "input",
options=[
{'label': 'January', 'value': 1},
{'label': 'Febuary', 'value': 2},
{'label': 'March', 'value': 3}
], value = 1
),
dcc.Graph( id="output-graph")
])
#app.callback(
Output(component_id='output-graph', component_property='figure'),
[Input(component_id='input', component_property='value')])
def update_value(value):
start = datetime.datetime(2018, value, 1, 0, 0, 0, 1)
end = datetime.datetime(2018, value + 1, 1, 0, 0, 0, 1)
subset_df = df[ (df["lost_time"] > start) & (df["lost_time"] < end) ]
x = pd.value_counts(subset_df.deal_source).index
y = pd.value_counts(subset_df.deal_source).values
return({'data': [
{'x': x, 'y': y, 'type': 'bar', 'name': value},
],
'layout': {
'title': "Deal Flow source for {} 2018".format(months[value-1])
}
}
)
if __name__ == "__main__":
app.run_server(debug = True)

Categories

Resources