I am working on a school project. I have created the following callback to update a graph. The graph simply plots 1) a line showing the values of the variable Wealth, 2) a horizontal line at the starting value of Wealth, 3) fills the area between the first and the second line. I would like to modify the code to add ticks on the vertical axis on the left, showing the difference between the value of Wealth and the starting its value. Therefore, I donβt want to add a 3rd line, I just want to add the ticks that essentially show the profit. I will show my attempt below this code snippet.
# Callbacks to update graphs based on the original code
@app.callback(
Output('wealth-over-time', 'figure'),
Input('wealth-time-range-slider', 'value'))
def update_wealth_over_time(selected_range):
filtered_df = df[df['Day'].between(selected_range[0], selected_range[1])]
# Create a new DataFrame for the fill area
fill_area_df = pd.DataFrame({
'Day': filtered_df['Day'],
'Starting Wealth': starting_wealth,
'Wealth ($)': filtered_df['Wealth ($)']
})
fig = go.Figure()
# Add fill area between starting wealth and Wealth ($)
fig.add_trace(go.Scatter(
x=pd.concat([fill_area_df['Day'], fill_area_df['Day'][::-1]]), # X-values concatenated with reverse for seamless fill
y=pd.concat([fill_area_df['Starting Wealth'], fill_area_df['Wealth ($)'][::-1]]), # Y-values for starting wealth and Wealth ($) with reverse for fill
fill='toself',
fillcolor='rgba(135, 206, 250, 0.5)', # Light blue fill with transparency
line=dict(color='rgba(255,255,255,0)'), # Invisible line around the fill area
showlegend=False,
name='Fill Area',
))
# Add Wealth ($) line on top of the fill area
fig.add_trace(go.Scatter(
x=filtered_df['Day'],
y=filtered_df['Wealth ($)'],
mode='lines+markers',
showlegend=False,
name='Wealth ($)',
line=dict(color='DeepSkyBlue'),
))
# Add dashed horizontal line for starting wealth
fig.add_shape(
type='line',
x0=filtered_df['Day'].min(),
x1=filtered_df['Day'].max(),
y0=starting_wealth,
y1=starting_wealth,
line=dict(color='Gray', dash='dash', width=2),
)
fig.update_layout(
title={'text': "Wealth", 'font': {'color': 'black'}},
plot_bgcolor='white',
xaxis=dict(
title='Day',
color='black',
showgrid=True,
gridcolor='lightgrey',
gridwidth=1,
showline=True,
linewidth=2,
linecolor='black',
mirror=True
),
yaxis=dict(
title='Wealth ($)',
color='black',
showgrid=True,
gridcolor='lightgrey',
gridwidth=1,
showline=True,
linewidth=2,
linecolor='black',
mirror=True
),
xaxis_range=[filtered_df['Day'].min(), filtered_df['Day'].max()]
)
fig.add_shape(
go.layout.Shape(
type="line",
x0=min(filtered_df['Day']),
y0=starting_wealth,
x1=max(filtered_df['Day']),
y1=starting_wealth,
line=dict(
color="black",
width=2,
dash="dash",
),
)
)
return fig
This generates the following image:
I have attempted to do this modification following the steps illustrated here. In particular, I made the following changes:
-
from plotly.subplots import make_subplots
-
Changed fig = go.Figure()
tofig = make_subplots(specs=[[{"secondary_y": True}]])
-
Added
secondary_y=True
as follows:
# Add Wealth ($) line on top of the fill area
fig.add_trace(go.Scatter(
x=filtered_df['Day'],
y=filtered_df['Wealth ($)'],
mode='lines+markers',
showlegend=False,
name='Wealth ($)',
line=dict(color='DeepSkyBlue'),
), secondary_y=True,)
However, when I run the code, 1) the blue area is no longer aligned properly:
Moreover, 2) I do not know how to show the correct ticks (the difference of the ticks on the left and the starting value of Wealth).
I would really appreciate some help with this.