I manged to create the following chart in plotly using python. It's pretty much all I need, but the final thing is to make the whole chart a 100% stacked, so instead o 0.35, the max value in the Y axis would be 1 and all the bars would be evenly aligned. Is there any way to do that in plotly?
Here is the code I used to generate the chart:
fig = go.Figure()
categories = grouped_values2['portfolio_category'].unique()
category_colors = ["#0070C0", "#FFC000", "#AD1457", "#00A651", "#DB4437", "#6E3159", "#F4A000", "#00788C", "#5FB3C3"]
for i, category in enumerate(categories):
num1 = random.randint(0, 30)
category_data = grouped_values2[grouped_values['portfolio_category'] == category]
fig.add_trace(
go.Bar(
x=category_data['month'],
y=category_data['importancia_realizado'],
name=f'R - {category}',
marker_color=category_colors[i],
offsetgroup=0
)
)
fig.add_trace(
go.Bar(
x=category_data['month'],
y=category_data['importancia_referencia'],
name=f'P - {category}',
marker_color=category_colors[i],
offsetgroup=1
)
)
fig.update_layout(
barmode='group',
title='IMPORTÂNCIA PROJETADA (P) vs IMPORTANCIA REALIZADA',
plot_bgcolor="rgba(0, 0, 0, 0)",
xaxis_title='Mês',
yaxis_title='Importância'
)
fig.show()
Here is the data:
month,month_number,portfolio_category,gmv_mtd,importancia_referencia,importancia_realizado,
0,Apr,4,CAT1,3242989.05,0.230,0.188
1,Apr,4,CAT2,3490670.33,0.190,0.202
2,Apr,4,CAT3,2970437.35,0.170,0.172
3,Apr,4,CAT4,6310704.34,0.160,0.365
4,Apr,4,CAT5,1046692.36,0.120,0.610
5,Apr,4,CAT6,216612.53,0.130,0.130
6,Jun,6,CAT1,4449799.95,0.210,0.274
7,Jun,6,CAT2,5209480.79,0.240,0.321
8,Jun,6,CAT3,2478664.66,0.160,0.153
9,Jun,6,CAT4,1318476.99,0.130,0.810
10,Jun,6,CAT5,2349817.17,0.0,130,0.145
11,Jun,6,CAT6,425692.50,0.130,0.260
12,May,5,CAT1,4057372.58,0.210,0.284
13,May,5,CAT2,3504235.05,0.250,0.245
14,May,5,CAT3,2863510.23,0.170,0.201
15,May,5,CAT4,900040.46,0.130,0.630
16,May,5,CAT5,2564349.59,0.130,0.180
17,May,5,CAT6,385128.35,0.120,0.270
This is tricky but you need to first normalize everything by the totals over each month (basically divide each row by the sum of its month group).
Then you need to keep track of the base so that we are plotting each bar from the right place. For example, if you want to plot the values [0.1,0.2,0.3,0.4]
that add to 1, you want to plot 0.1 with base = 0, then plot 0.2 starting from 0.1, then 0.3 from 0.1+0.2, and 0.4 from 0.1+0.2+0.3
.
from io import StringIO
import pandas as pd
import plotly.graph_objects as go
sample_data = StringIO("""
index,month,month_number,portfolio_category,gmv_mtd,importancia_referencia,importancia_realizado,
0,Apr,4,CAT1,3242989.05,0.230,0.188
1,Apr,4,CAT2,3490670.33,0.190,0.202
2,Apr,4,CAT3,2970437.35,0.170,0.172
3,Apr,4,CAT4,6310704.34,0.160,0.365
4,Apr,4,CAT5,1046692.36,0.120,0.610
5,Apr,4,CAT6,216612.53,0.130,0.130
6,Jun,6,CAT1,4449799.95,0.210,0.274
7,Jun,6,CAT2,5209480.79,0.240,0.321
8,Jun,6,CAT3,2478664.66,0.160,0.153
9,Jun,6,CAT4,1318476.99,0.130,0.810
10,Jun,6,CAT5,2349817.17,0.0,130,0.145
11,Jun,6,CAT6,425692.50,0.130,0.260
12,May,5,CAT1,4057372.58,0.210,0.284
13,May,5,CAT2,3504235.05,0.250,0.245
14,May,5,CAT3,2863510.23,0.170,0.201
15,May,5,CAT4,900040.46,0.130,0.630
16,May,5,CAT5,2564349.59,0.130,0.180
17,May,5,CAT6,385128.35,0.120,0.270
""")
grouped_values2 = pd.read_csv(sample_data, sep=",")
grouped_values2 = grouped_values2.assign(importancia_referencia=grouped_values2.importancia_referencia/grouped_values2.groupby('month').importancia_referencia.transform('sum'))
grouped_values2 = grouped_values2.assign(importancia_realizado=grouped_values2.importancia_realizado/grouped_values2.groupby('month').importancia_realizado.transform('sum'))
fig = go.Figure()
categories = grouped_values2['portfolio_category'].unique()
category_colors = ["#0070C0", "#FFC000", "#AD1457", "#00A651", "#DB4437", "#6E3159", "#F4A000", "#00788C", "#5FB3C3"]
## calculate base bars for each month
months = grouped_values2['month'].unique()
month_base_values = {
'importancia_realizado': {k:0 for k in months},
'importancia_referencia': {k:0 for k in months}
}
for i, category in enumerate(categories):
# num1 = random.randint(0, 30)
category_data = grouped_values2[grouped_values2['portfolio_category'] == category]
fig.add_trace(
go.Bar(
x=category_data['month'],
y=category_data['importancia_realizado'],
base=list(month_base_values['importancia_realizado'].values()),
name=f'R - {category}',
marker_color=category_colors[i],
offsetgroup=0
)
)
fig.add_trace(
go.Bar(
x=category_data['month'],
y=category_data['importancia_referencia'],
base=list(month_base_values['importancia_referencia'].values()),
name=f'P - {category}',
marker_color=category_colors[i],
offsetgroup=1
)
)
## update the base for each group by month
for k,v in month_base_values['importancia_realizado'].items():
month_base_values['importancia_realizado'][k] += category_data.loc[category_data['month'] == k,['importancia_realizado']].values[0][0]
month_base_values['importancia_referencia'][k] += category_data.loc[category_data['month'] == k,['importancia_referencia']].values[0][0]
fig.update_layout(
barmode='group',
title='IMPORTÂNCIA PROJETADA (P) vs IMPORTANCIA REALIZADA',
plot_bgcolor="rgba(0, 0, 0, 0)",
xaxis_title='Mês',
yaxis_title='Importância'
)
fig.show()