0
votes

I am trying to generate a stacked bar chart with plotly, specifically one that is "100%-stacked," like this:-

https://www.python-graph-gallery.com/13-percent-stacked-barplot

I am using the following code:-

import plotly
import plotly.graph_objects as go
import numpy as np
binnum_attr=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
tnl_attr=[164549.654, 278570.473, 201857.2155, 146326.9935, 116167.091, 98121.201, 384025.989, 786854.992, 502627.797, 306844.9995, 452795.6745, 271533.2325, 143591.5138]
pop_attr=[296699, 195322, 82853, 42382, 26001, 17926, 47187, 46586, 15508, 6500, 6412, 2339, 785]
verbose_customdata = np.stack((binnum_attr, tnl_attr, pop_attr), axis=-1)

fig = go.Figure(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['3.618', '1.526', '0.899', '0.674', '0.587', '0.566', '0.632', '0.411', '0.139', '0.081', '0.046', '0.024', '0.060'], customdata=verbose_customdata, legendgroup="M0", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M0 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M0', marker_color='rgb(128,128,128)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['36.797', '21.312', '12.348', '9.136', '8.275', '8.028', '9.105', '5.944', '2.473', '1.225', '0.725', '0.394', '0.377'], customdata=verbose_customdata, legendgroup="M1", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M1 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M1', marker_color='rgb(230,25,75)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['45.265', '40.620', '30.699', '23.548', '20.190', '18.252', '18.068', '13.085', '6.579', '3.656', '1.950', '1.343', '2.040'], customdata=verbose_customdata, legendgroup="M2", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M2 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M2', marker_color='rgb(60,180,75)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['12.552', '28.142', '34.866', '33.760', '30.362', '27.477', '22.317', '16.624', '10.221', '6.285', '3.853', '2.342', '3.101'], customdata=verbose_customdata, legendgroup="M3", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M3 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M3', marker_color='rgb(0,130,200)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['1.572', '7.198', '17.117', '24.482', '27.654', '28.867', '27.013', '22.357', '16.369', '13.342', '9.081', '6.584', '7.308'], customdata=verbose_customdata, legendgroup="M4", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M4 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M4', marker_color='rgb(245,130,48)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['0.177', '1.028', '3.369', '7.020', '10.741', '13.425', '16.108', '16.946', '13.654', '11.075', '7.060', '3.919', '3.424'], customdata=verbose_customdata, legendgroup="M5", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M5 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M5', marker_color='rgb(145,30,180)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['0.014', '0.147', '0.539', '0.898', '1.445', '2.123', '3.598', '7.842', '8.837', '7.916', '6.015', '4.466', '4.884'], customdata=verbose_customdata, legendgroup="M6", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M6 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M6', marker_color='rgb(70,240,240)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['0.003', '0.012', '0.120', '0.309', '0.460', '0.801', '2.013', '7.288', '10.854', '10.506', '6.766', '3.984', '2.921'], customdata=verbose_customdata, legendgroup="M7", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M7 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M7', marker_color='rgb(0,0,128)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['0.000', '0.001', '0.018', '0.075', '0.142', '0.279', '0.579', '4.052', '9.357', '10.690', '11.111', '9.456', '8.756'], customdata=verbose_customdata, legendgroup="M8", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M8 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M8', marker_color='rgb(210,245,80)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['0.003', '0.010', '0.019', '0.043', '0.086', '0.103', '0.300', '2.427', '7.132', '9.093', '8.937', '7.208', '4.578'], customdata=verbose_customdata, legendgroup="M9", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M9 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M9', marker_color='rgb(0,128,128)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['0.000', '0.000', '0.002', '0.017', '0.033', '0.051', '0.149', '1.564', '5.752', '9.613', '12.453', '15.218', '13.762'], customdata=verbose_customdata, legendgroup="M10", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M10 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M10', marker_color='rgb(220,190,255)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['0.000', '0.003', '0.004', '0.028', '0.019', '0.022', '0.068', '0.558', '3.286', '5.387', '9.235', '9.583', '6.008'], customdata=verbose_customdata, legendgroup="M11", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M11 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M11', marker_color='rgb(170,255,195)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['0.000', '0.000', '0.000', '0.002', '0.001', '0.001', '0.036', '0.732', '4.020', '8.839', '15.911', '25.388', '20.153'], customdata=verbose_customdata, legendgroup="M12", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M12 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M12', marker_color='rgb(255,215,180)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['0.000', '0.000', '0.000', '0.003', '0.003', '0.005', '0.014', '0.119', '0.810', '1.324', '3.969', '5.143', '7.068'], customdata=verbose_customdata, legendgroup="M13", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M13 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M13', marker_color='rgb(0,0,0)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~11', '11~26', '26~41', '41~55', '55~94', '94~158', '158~1644'], y=['0.000', '0.000', '0.000', '0.004', '0.000', '0.000', '0.000', '0.050', '0.517', '0.967', '2.888', '4.948', '15.559'], customdata=verbose_customdata, legendgroup="M14", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M14 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M14', marker_color='rgb(128,0,0)', marker_opacity=1.0))
fig.update_layout(barmode='stack')
fig.update_layout(title_text='<b>Metal Layer Usage by Length: euunit n3</b>', title_font_size=28, yaxis=dict(title='<b>Metal Layer Usage (%)</b>', titlefont_size=20, showticklabels=False), xaxis=dict(title='<b>Net Length Range (um)</b>', titlefont_size=20, tickfont_size=16))
fig.update_layout(legend=dict(font=dict(size=14),borderwidth=1))
fig.show()

...however, the outcome looks like this:-

not 100 percent stacked bar

...I am not quite sure why the bars do not fully occupy the vertical height of the plot area. Does the sum total of numbers in each bin (e.g. 0~1, 1~2, etc.) have to add up to exactly 100? I am asking because due to rounding some add up to 100.001 and others 99.999, etc. Or am I supposed to declare some kind of special format (e.g. %) for the numbers in each column?

The plotly options are all relatively new to me, so I could very well be missing something simple. Does anyone have any suggestions? Note that barmode='relative' did not change the outcome.

Thanks!

1
The data for the y-axis is a string, so change it to a number, and then change mode to relative.r-beginners
@r-beginners yup, that was indeed the problem. I removed the ' characters around the y values and now it looks as expected. Thanks!Chris

1 Answers

1
votes

Removing the ' characters around the y values and adding 'relative' for barmode produced the correct outcome...

import plotly
import plotly.graph_objects as go
import numpy as np
binnum_attr=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
tnl_attr=[164549.654, 278570.473, 201857.2155, 146326.9935, 116167.091, 98121.201, 86260.078, 79611.275, 346547.786, 573329.789, 345360.231, 513364.5035, 287341.8995, 472867.1225, 143591.5138]
pop_attr=[296699, 195322, 82853, 42382, 26001, 17926, 13310, 10637, 33974, 32444, 12302, 12449, 4635, 4781, 785]
verbose_customdata = np.stack((binnum_attr, tnl_attr, pop_attr), axis=-1)

fig = go.Figure(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[3.618, 1.526, 0.899, 0.674, 0.587, 0.566, 0.566, 0.622, 0.644, 0.392, 0.185, 0.094, 0.056, 0.029, 0.060], customdata=verbose_customdata, legendgroup="M0", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M0 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M0', marker_color='rgb(128,128,128)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[36.797, 21.312, 12.348, 9.136, 8.275, 8.028, 8.307, 8.749, 9.195, 5.667, 3.191, 1.561, 0.890, 0.466, 0.377], customdata=verbose_customdata, legendgroup="M1", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M1 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M1', marker_color='rgb(230,25,75)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[45.265, 40.620, 30.699, 23.548, 20.190, 18.252, 17.691, 18.222, 17.714, 12.791, 7.958, 4.590, 2.436, 1.391, 2.040], customdata=verbose_customdata, legendgroup="M2", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M2 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M2', marker_color='rgb(60,180,75)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[12.552, 28.142, 34.866, 33.760, 30.362, 27.477, 24.941, 23.311, 20.421, 16.449, 11.854, 7.587, 4.617, 2.679, 3.101], customdata=verbose_customdata, legendgroup="M3", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M3 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M3', marker_color='rgb(0,130,200)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[1.572, 7.198, 17.117, 24.482, 27.654, 28.867, 28.483, 27.705, 25.384, 22.417, 17.922, 14.306, 10.080, 7.284, 7.308], customdata=verbose_customdata, legendgroup="M4", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M4 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M4', marker_color='rgb(245,130,48)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[0.177, 1.028, 3.369, 7.020, 10.741, 13.425, 15.438, 16.022, 16.681, 17.102, 14.868, 11.920, 8.350, 4.642, 3.424], customdata=verbose_customdata, legendgroup="M5", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M5 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M5', marker_color='rgb(145,30,180)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[0.014, 0.147, 0.539, 0.898, 1.445, 2.123, 2.673, 2.974, 4.886, 7.980, 9.202, 8.248, 6.609, 4.891, 4.884], customdata=verbose_customdata, legendgroup="M6", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M6 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M6', marker_color='rgb(70,240,240)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[0.003, 0.012, 0.120, 0.309, 0.460, 0.801, 1.243, 1.570, 3.151, 7.628, 10.602, 10.732, 7.845, 4.673, 2.921], customdata=verbose_customdata, legendgroup="M7", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M7 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M7', marker_color='rgb(0,0,128)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[0.000, 0.001, 0.018, 0.075, 0.142, 0.279, 0.341, 0.416, 1.054, 4.200, 7.894, 10.699, 11.194, 9.985, 8.756], customdata=verbose_customdata, legendgroup="M8", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M8 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M8', marker_color='rgb(210,245,80)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[0.003, 0.010, 0.019, 0.043, 0.086, 0.103, 0.191, 0.265, 0.409, 2.451, 5.941, 8.565, 9.452, 7.728, 4.578], customdata=verbose_customdata, legendgroup="M9", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M9 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M9', marker_color='rgb(0,128,128)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[0.000, 0.000, 0.002, 0.017, 0.033, 0.051, 0.050, 0.085, 0.274, 1.564, 4.395, 8.221, 11.563, 14.457, 13.762], customdata=verbose_customdata, legendgroup="M10", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M10 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M10', marker_color='rgb(220,190,255)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[0.000, 0.003, 0.004, 0.028, 0.019, 0.022, 0.049, 0.030, 0.095, 0.514, 2.237, 4.737, 8.285, 9.802, 6.008], customdata=verbose_customdata, legendgroup="M11", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M11 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M11', marker_color='rgb(170,255,195)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[0.000, 0.000, 0.000, 0.002, 0.001, 0.001, 0.005, 0.025, 0.083, 0.695, 2.848, 6.794, 13.261, 22.648, 20.153], customdata=verbose_customdata, legendgroup="M12", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M12 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M12', marker_color='rgb(255,215,180)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[0.000, 0.000, 0.000, 0.003, 0.003, 0.005, 0.024, 0.004, 0.008, 0.093, 0.582, 1.165, 3.187, 4.934, 7.068], customdata=verbose_customdata, legendgroup="M13", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M13 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M13', marker_color='rgb(0,0,0)', marker_opacity=1.0))
fig.add_trace(go.Bar(x=['0~1', '1~2', '2~3', '3~4', '4~5', '5~6', '6~7', '7~8', '8~13', '13~24', '24~33', '33~53', '53~73', '73~158', '158~1644'], y=[0.000, 0.000, 0.000, 0.004, 0.000, 0.000, 0.000, 0.000, 0.000, 0.056, 0.321, 0.781, 2.176, 4.394, 15.559], customdata=verbose_customdata, legendgroup="M14", hovertemplate='<b>Bin: %{customdata[0]: .0f}</b><br>'+'<b>M14 portion: %{y:.2f}%</b><br>'+'<b>Total length (all layers): %{customdata[1]:.2f}</b><br>'+'<b>Nets: %{customdata[2]: .0f}</b><br>', name='M14', marker_color='rgb(128,0,0)', marker_opacity=1.0))
fig.update_layout(barmode='relative')
fig.update_layout(title_text='<b>Metal Layer Usage by Length: block node</b>', title_font_size=28, yaxis=dict(title='<b>Metal Layer Usage (%)</b>', titlefont_size=20, tickfont_size=16), xaxis=dict(title='<b>Net Length Range (um)</b>', titlefont_size=20, tickfont_size=16))
fig.update_layout(legend=dict(font=dict(size=14),borderwidth=1))
fig.show()

...results in...

correct 100% stacked bar chart