I’m not sure if it will help to show the code that I’ve written, but here goes…
All I want is to have the range selector that makes changes in the primary graph (fixed interest rates) cause the same effect on the second graph (fixed interest spreads).
There’s more going on in the code. There’s a datatable that’s editable and an app.callback that will recalculate some of the calculated numbers. In addition, if any of the calculated numbers in the data table change, both of the time series graphs will change.
I’m a python programmer at heart. I don’t know any javascript or CSS. I just thought that using dash would be a lot cooler than matplotlib or using libraries such as openpyxl.
Anyone that can give me some sample code is appreciated. For some reason the relayoutData information that I’ve found doesn’t seem to be helping me. I’ve hit some type of mental block.
Thanks everyone in advance.
app.layout = html.Div([ #html.Div 1
html.Div([ # html.Div 2
# Header(),
dash_table.DataTable(
id='datatable-int-rates',
# columns = [{"name": i, "id": i} for i in df_mortgage.columns],
columns = [
{'name': ['', 'Date'],
'id' : 'Date',
'editable' : False
},
{'name': ['Interest Rate Type','Freddie Mac'],
'id' : 'Freddie Mac',
'type' : 'numeric',
'format' : Format(
precision=3,
scheme=Scheme.fixed,
symbol=Symbol.yes,
symbol_suffix= '%'),
},
{'name': ['Interest Rate Type','Conforming Rates'],
'id' : 'WFC Conf Int Rate',
'type' : 'numeric',
'format' : Format(
precision=3,
scheme=Scheme.fixed,
symbol=Symbol.yes,
symbol_suffix= '%'),
},
{'name': ['Interest Rate Type','Jumbo Rates'],
'id' : 'WFC Jumbo Int Rate',
'type' : 'numeric',
'format' : Format(
precision=3,
scheme=Scheme.fixed,
symbol=Symbol.yes,
symbol_suffix= '%'),
},
{'name': ['Spreads','Conf minus Freddie'],
'id' : 'Conf minus Freddie',
'editable' : False,
'type' : 'numeric',
'format' : Format(
precision = 3,
scheme = Scheme.fixed,
sign = Sign.parantheses)
},
{'name': ['Spreads','Jumbo minus Freddie'],
'id' : 'Jumbo minus Freddie',
'editable' : False,
'type' : 'numeric',
'format' : Format(
precision = 3,
scheme = Scheme.fixed,
sign = Sign.parantheses)
}
], # close columns
merge_duplicate_headers = True,
data = df_mortgage.to_dict('rows'),
editable=True,
n_fixed_rows = 2,
style_cell = {'textAlign' : 'center'},
style_header = {'fontWeight' : 'bold'},
style_table = {'maxHeight': '300px', 'overflowY' : 'scroll'},
pagination_mode = False,
style_cell_conditional=[{'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(248, 248, 248)'}],
style_data_conditional = [{'if': {'column_id' : 'Conf minus Freddie',
'filter' : '"Conf minus Freddie" < num(0)'}, 'color': 'red'},
{'if': {'column_id' : 'Jumbo minus Freddie',
'filter' : '"Jumbo minus Freddie" < num(0)'}, 'color': 'red'},
] # style_data_conditional
), # dash_table.DataTable
html.Div(id = 'mortgage-graph-container'),
]), # html.Div 2
]) #html.Div 1
# Recalculate spread values if one of the underlying interest rates change.
@app.callback(
Output('datatable-int-rates', 'data'),
[Input('datatable-int-rates', 'data_timestamp')],
[State('datatable-int-rates', 'data')])
def update_spreads(data_timestamp, rows):
# Recalculate the value in Conf minus Freddie and Jumbo minus Freddie
for row in rows:
row['Conf minus Freddie'] = round(float(row['WFC Conf Int Rate']) - float(row['Freddie Mac']),3)
row['Jumbo minus Freddie'] = round(float(row['WFC Jumbo Int Rate']) - float(row['Freddie Mac']),3)
return rows
# change graphs if value in data table changes.
@app.callback(
Output('mortgage-graph-container', 'children'),
[Input('datatable-int-rates', 'derived_virtual_data'),
Input('datatable-int-rates', 'derived_virtual_selected_rows')])
def update_graph(rows, derived_virtual_selected_rows):
if derived_virtual_selected_rows is None:
derived_virtual_selected_rows = []
dff = df_mortgage if rows is None else pd.DataFrame(rows)
# This is the return statement for the update_graph function.
return html.Div([ #html.Div 1
html.Div([ #html.Div 2
html.Div([ #html.Div 3
dcc.Graph(
id='fixed interest rates',
figure={
'data': [
{'x': dff['Date'],
'y': dff['Freddie Mac'],
'type': 'line',
'name': 'Freddie Mac'
},
{'x': dff['Date'],
'y': dff['WFC Conf Int Rate'],
'type': 'line',
'name': 'Conforming Rates'
},
{'x': dff['Date'],
'y': dff['WFC Jumbo Int Rate'],
'type': 'line',
'name': 'Jumbo Rates'
},
], # data
'layout' : {
'title' : '<b>Freddie, Jumbo and Conforming Interest Rates<b>',
'xaxis' : {'title' : '<b>Date<b>',
'rangeselector' : {'buttons' : [
{
'count' : 3,
'label' : '3M',
'step' : 'month',
'stepmode' : 'backward'
},
{
'count' : 6,
'label' : '6M',
'step' : 'month',
'stepmode' : 'backward'
},
{
'count' : 12,
'label' : '12M',
'step' : 'month',
'stepmode' : 'backward'
},
{
'count' : 24,
'label' : '24M',
'step' : 'month',
'stepmode' : 'backward'
}
]}, # button rangeselctor
}, # xaxis
'yaxis' : {'title' : '<b>Interest Rate<b>'},
'height' : 600,
'automargin' : True,
'hovermode': 'closest',
'width' : 950,
},
} # layout
) # figure
# for column in ['WFC Conf Int Rate', 'WFC Jumbo Int Rate']
for column in ['Conf minus Freddie', 'Jumbo minus Freddie']
]), # html.Div 3
html.Div([ #html.Div 4
dcc.Graph(
id='fixed interest spreads',
figure={
'data': [
{'x': dff['Date'],
'y': dff['Conf minus Freddie'],
'type': 'line',
'name': 'Conf minus Freddie'
},
{'x': dff['Date'],
'y': dff['Jumbo minus Freddie'],
'type': 'line',
'name': 'Jumbo minus Freddie'
},
], # data
'layout' : {
'title' : '<b>Spreads From Freddie Mac<b>',
'xaxis' : {'title' : '<b>Date<b>',
'rangeselector' : {'buttons' : [
{
'count' : 3,
'label' : '3M',
'step' : 'month',
'stepmode' : 'backward'
},
{
'count' : 6,
'label' : '6M',
'step' : 'month',
'stepmode' : 'backward'
},
{
'count' : 12,
'label' : '12M',
'step' : 'month',
'stepmode' : 'backward'
},
{
'count' : 24,
'label' : '24M',
'step' : 'month',
'stepmode' : 'backward'
}
]}, # button rangeselctor
},
'yaxis' : {'title' : '<b>Interest Differential<b>'},
'height' : 600,
'automargin' : True,
'hovermode': 'closest',
'width' : 950,
} #layout
} # figure
) # dcc.graph
]) #html.Div 4
], className = 'row') #html.Div
]) # html.Div 1
app.css.append_css({
'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css'
})