Hi all,
I wanted to created this chart:
and I got stuck with the overlay part.
In the end I used the Previous Year chart as a background-image for the Current chart (AC).
PY is generated when the image does not already exist, it took some experimenting.
I tried a lot to avoid this route, and still wonder, how can you accomplish an effect like this without using a background image and by creating two barcharts. Previous Year does not need tooltips. I tried stuff like a little shift for the previous year, to keep the current year exactly at the right spot on the x-axis.
code for this graph
def create_bar_ac_py(df_revenue_mom):
colors = {'AC': 'rgba(64,64,64,1)','PY':'rgba(166,166,166,1)' }
# Define a small shift using Timedelta
#shift = pd.Timedelta(days=3) # Adjust as needed
max_y = df_revenue_mom['revenue'].max()
current_year = df_revenue_mom['Last_dayofmonth_Date'].dt.year.max()
src_background = f"/assets/{current_year}_figPY.svg"
figPY = go.Figure()
# First bar trace (shift left)
figPY.add_trace(go.Bar(
x=df_revenue_mom['Last_dayofmonth_Date'],
y=df_revenue_mom['revenue_py'],
#width=0.5,
marker_color=colors.get('PY'),
name='PY'
))
#background needs to be transparent
figPY.update_layout({
'plot_bgcolor': 'rgba(0, 0, 0, 0)',
'paper_bgcolor': 'rgba(0, 0, 0, 0)',
})
# Change the bar mode
figPY.update_layout(bargap=0.2)
figPY.update_layout(yaxis_title=None)
figPY.update_yaxes(showticklabels=False)
figPY.update_layout(xaxis_title=None)
figPY.update_xaxes(showticklabels=False)
figPY.update_layout(yaxis_range=[0,max_y])
figPY.update_layout(
margin=dict(l=0, r=0, t=0, b=0),
width=800,
height=300,
)
#solution stuck kaleido 2 on win11 : https://github.com/plotly/Kaleido/issues/126
#writing an image dynamically triggers the callback function for a second time
#pio.write_image(figPY, "assets/figPY.svg")
figAC = go.Figure()
# Second bar trace (shift right)
figAC.add_trace(go.Bar(
x=df_revenue_mom['Last_dayofmonth_Date'],
y=df_revenue_mom['revenue'],
#width=0.5,
marker_color=colors.get('AC'),
name='AC',
text=df_revenue_mom['revenue'],
texttemplate = "%{y:,.3s}"
))
# Change the bar mode
#figAC.update_layout(bargap=0.2)
#background needs to be transparent fo a see through to PY
figAC.update_layout({
'plot_bgcolor': 'rgba(0, 0, 0, 0)',
'paper_bgcolor': 'rgba(0, 0, 0, 0)',
})
figAC.update_xaxes(showgrid=False, zeroline=False)
figAC.update_yaxes(showgrid=False, zeroline=False)
# Add images
figAC.add_layout_image(
dict(
source=src_background,
xref="paper", yref="paper",
#x=1, y=1,
x=-0.01, y=0,
sizex=1,
sizey=1,
xanchor="left",
yanchor="bottom",
opacity=1,
layer="below",
sizing="stretch")
)
figAC.update_layout(yaxis_title=None)
figAC.update_yaxes(showticklabels=False)
figAC.update_xaxes(
dtick="M1",
tickformat="%b")
#ticklabelmode="period")
figAC.update_layout(
margin=dict(l=0, r=0, t=0, b=0),
autosize=False,
width=800,
height=300,
hovermode=False
)
figAC.update_traces(textfont_size=12, textangle=0, textposition="outside", cliponaxis=False)
return dcc.Graph(figure = figAC)