如何基于给定DataFrame绘制100%堆叠柱状图并显示百分比?
100% Stacked Bar Chart with Percentage Labels
Got it, let's turn your regular stacked bar chart into a 100% stacked version that shows percentage values directly on the bars. Here's a step-by-step solution tailored to your data:
Step 1: Calculate Grouped Sums & Normalize to Percentages
First, we'll compute the total counts per name like you did initially, then normalize each value to its percentage of the group's total. This normalization is what creates the 100% stacked effect.
import pandas as pd import matplotlib.pyplot as plt # Your original DataFrame df = pd.DataFrame({ "name": ["Foo", "Foo", "Baar", "Foo", "Baar", "Foo", "Baar", "Baar"], "count_1": [5,10,12,15,20,25,30,35], "count_2": [100,150,100,25,250,300,400,500] }) # 1. Group by name and sum the count columns sum_df = df.groupby(['name'])[['count_1', 'count_2']].sum() # 2. Convert sums to percentages (divide each row by its total, multiply by 100) pct_df = sum_df.div(sum_df.sum(axis=1), axis=0) * 100
Step 2: Plot the 100% Stacked Bar Chart
Use the percentage-based DataFrame to generate the stacked chart, and add basic styling for readability:
# Create the 100% stacked bar chart ax = pct_df.plot(kind='bar', stacked=True, figsize=(8, 6), colormap='coolwarm') # Add axis labels and title ax.set_xlabel('Name') ax.set_ylabel('Percentage (%)') ax.set_title('100% Stacked Bar Chart: Count 1 vs Count 2 by Name') ax.legend(title='Count Category')
Step 3: Add Percentage Labels to Each Bar Segment
Loop through every segment of the stacked bars to place the percentage value dead-center on each section:
# Iterate over each bar segment to add labels for p in ax.patches: # Grab the dimensions and position of the segment width, height = p.get_width(), p.get_height() x_pos, y_pos = p.get_xy() # Add formatted percentage text ax.text( x_pos + width/2, # Center horizontally y_pos + height/2, # Center vertically f'{height:.1f}%', # Show 1 decimal place for clarity ha='center', va='center' ) # Adjust layout to prevent label cutoff plt.tight_layout() plt.show()
Quick Explanation
- Normalization:
sum_df.sum(axis=1)calculates the total count pername, anddiv(..., axis=0)ensures each value is scaled relative to its group's total. - Label Placement: Using
ax.patcheslets us target every individual segment of the stacked bars, so each percentage is placed exactly where it belongs.
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

