I'm stuck trying to implement a customized bar chart and as I'm not finding references about how to implement it;
The problem: I need to set a custom value to each of my x-axes, as shown in the image below:
But as shown below in my version of the chart, I'm not setting the x correctly.
Data:
data={'period': ['2019_1', '2019_1', '2020_1', '2020_1', '2019_2', '2019_2', '2020_2', '2020_2',
'2019_3', '2019_3', '2020_3', '2020_3', '2019_4', '2019_4', '2020_4', '2020_4'],
'indicator': ['metric1', 'metric0', 'metric1', 'metric0', 'metric1', 'metric0', 'metric1',
'metric0', 'metric1', 'metric0', 'metric1', 'metric0', 'metric1', 'metric0',
'metric1', 'metric0'],
'value_plot': [467.2, 1453.6, 468.13, 1521.29, 490.08, 1500.02, 518.69, 1599.33,
480.01, 1473.12, 510.53, 1556.38, 532.57, 1751.75, 563.62, 1877.21],
'qtr': ['Q1', 'Q1', 'Q1', 'Q1', 'Q2', 'Q2', 'Q2', 'Q2', 'Q3',
'Q3', 'Q3', 'Q3', 'Q4', 'Q4', 'Q4', 'Q4'],
'year': ['2019', '2019', '2020', '2020', '2019', '2019', '2020',
'2020', '2019', '2019', '2020', '2020', '2019',
'2019', '2020', '2020']}
Reproducible code:
import plotly.graph_objects as go
import pandas as pd
import plotly_express as px
import numpy as np
plot_df=pd.DataFrame.from_dict(data)
bargap=.3
past_rev_color="red"
current_rev_color="blue"
current_year_mask=np.where(plot_df.year==2020, True, False)
metric0_mask=plot_df.indicator.str.endswith("metric0")
metric0_table=plot_df[metric0_mask]
fig=px.bar(metric0_table,
x="qtr", y="value_plot",
color="year", barmode="group",
color_discrete_map={"2019": past_rev_color,
"2020": current_rev_color},
custom_data=[metric0_table["year"]])
fig.layout.xaxis2 = go.layout.XAxis(overlaying="x",
range=[0, 4], showticklabels=False)
fig.layout.yaxis2 = go.layout.YAxis(overlaying="y", side="right")
metric1_table=plot_df[np.logical_not(metric0_mask)]
metric1_curr_yr_mask=np.where(metric1_table["year"]=="2020", True, False)
fig.add_scatter(
x=[i + (bargap / 2 + (1 - bargap) / 4) for i in range(4)],
y=[metric1_table[metric1_curr_yr_mask].value_plot.iloc[i] for i in range(4)],
xaxis="x2",
yaxis="y2",
name="previous")
fig.add_scatter(
x=[i + (1 - bargap / 2 - (1 - bargap) / 4) for i in range(4)],
y=[metric1_table[np.logical_not(metric1_curr_yr_mask)].value_plot.iloc[i] for i in range(4)],
xaxis="x2",
yaxis="y2",
name="current")
fig.update_layout(showlegend=False)
fig
import plotly.graph_objects as go
import pandas as pd
data={'period': ['2019_1', '2019_1', '2020_1', '2020_1', '2019_2', '2019_2', '2020_2', '2020_2',
'2019_3', '2019_3', '2020_3', '2020_3', '2019_4', '2019_4', '2020_4', '2020_4'],
'indicator': ['metric1', 'metric0', 'metric1', 'metric0', 'metric1', 'metric0', 'metric1',
'metric0', 'metric1', 'metric0', 'metric1', 'metric0', 'metric1', 'metric0',
'metric1', 'metric0'],
'value_plot': [467.2, 1453.6, 468.13, 1521.29, 490.08, 1500.02, 518.69, 1599.33,
480.01, 1473.12, 510.53, 1556.38, 532.57, 1751.75, 563.62, 1877.21],
'qtr': ['Q1', 'Q1', 'Q1', 'Q1', 'Q2', 'Q2', 'Q2', 'Q2', 'Q3',
'Q3', 'Q3', 'Q3', 'Q4', 'Q4', 'Q4', 'Q4'],
'year': ['2019', '2019', '2020', '2020', '2019', '2019', '2020',
'2020', '2019', '2019', '2020', '2020', '2019',
'2019', '2020', '2020']}
plot_df=pd.DataFrame.from_dict(data)
metric0_mask=plot_df.indicator.str.endswith("metric0")
metric0_table=plot_df[metric0_mask]
df_line = plot_df[~metric0_mask]
past_rev_color="red"
current_rev_color="blue"
fig = go.Figure(
go.Bar(
x=[metric0_table["qtr"], metric0_table["year"]],
y=metric0_table["value_plot"],
marker={
"color": metric0_table["year"].map(
{"2019": past_rev_color, "2020": current_rev_color}
)
},
)
).add_traces(
[
go.Scatter(
x=[
df_line.loc[df_line["year"].eq(y), "qtr"],
df_line.loc[df_line["year"].eq(y), "year"],
],
y=df_line.loc[df_line["year"].eq(y), "value_plot"],
yaxis="y2"
)
for y in df_line["year"].unique()
]
).update_layout(yaxis2={"overlaying":"y","side":"right"}, showlegend=False)
fig