Сложная процентная барная карта

import pandas as pd
import matplotlib.pyplot as plt

# create the dataframe
data = {'Range':['<10','>10', '>= 20', '<10','>10', '>= 20', '<10','>10', '>= 20'],
        'Price':[50,25,25,70,20,10,80,10,10],
        'Value':[100,50,50,140,40,20,160,20,20]}    

df1 = pd.DataFrame(data)

# pivot the price data
df_price = df1.assign(idx=df1.groupby('Range').cumcount()).pivot(index='idx', columns='Range', values='Price')

Range  <10  >10  >= 20
idx                   
0       50   25     25
1       70   20     10
2       80   10     10

# pivot the value data
df_value = df1.assign(idx=df1.groupby('Range').cumcount()).pivot(index='idx', columns='Range', values='Value')

Range  <10  >10  >= 20
idx                   
0      100   50     50
1      140   40     20
2      160   20     20

# set colors
colors = ['#b5ffb9', '#f9bc86', '#a3acff']

# plot the price
ax = df_price.plot.bar(stacked=True, figsize=(8, 6), color=colors, ec='w')

# label the x-axis
plt.xticks(ticks=range(3), labels=['low', 'med', 'high'], rotation=0)

# x-axis title
plt.xlabel('group')

# position the legend
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

# annotate the bar segments
# col and row iloc indices for df_value
col_idx = 0
row_idx = 0

# iterate through each bar patch from ax
for i, p in enumerate(ax.patches, 1):

    left, bottom, width, height = p.get_bbox().bounds
    v = df_value.iloc[row_idx, col_idx]
    if width > 0:
        ax.annotate(f'{v:0.0f}', xy=(left+width/2, bottom+height/2), ha='center', va='center')

        # use this line to add commas for thousands
#        ax.annotate(f'{v:,}', xy=(left+width/2, bottom+height/2), ha='center', va='center')
    
    row_idx += 1
    if i%3 == 0:  # there are three bars, so update the indices 
        col_idx += 1
        row_idx = 0
Chunxiao Wang