柱状图数值错位问题:如何将数值置于对应柱状内部?
Fixing Bar Chart Label Placement (Inside Bars)
Hey there! I see you're struggling with misaligned labels on your bar chart and want to move them inside the bars instead—let's get that sorted out.
The main issue with your current code is the coordinates you're using for ax.text(): you're mixing up x and y positions, which causes the labels to be off. For categorical x-axis values (like your years), we need to target the center of each bar, and adjust the y-position based on whether the value is positive or negative to keep the label inside the bar.
Here's the revised code with explanations:
import pandas as pd import matplotlib.pyplot as plt import matplotlib # Your original data df = pd.DataFrame({'Years': ['2015', '2016', '2017', '2018'], 'Value': [-495982.0, 405549.0, -351541.0, 283790.0]}) # Optional: Convert values to thousands for readability (matches your commented-out line) df['Value_k'] = df['Value'] / 1000 fig, ax = plt.subplots() ax.set_title('Plotting Financials') ax.set_xlabel('Years') ax.set_ylabel('Value (in thousands)') # Plot bars with conditional colors bars = ax.bar(df['Years'], df['Value_k'], color=['r' if v < 0 else 'g' for v in df['Value_k']]) # Format y-axis with commas ax.get_yaxis().set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ','))) # Add labels inside each bar for bar, value in zip(bars, df['Value_k']): # Get the bar's x position (center) and height x = bar.get_x() + bar.get_width() / 2 y = value # Adjust y-position to keep label inside the bar if value > 0: # Place label near the top of the positive bar (subtract a small offset) y_pos = y - abs(y) * 0.1 text_color = 'white' # Contrast with green bars else: # Place label near the bottom of the negative bar (add a small offset) y_pos = y + abs(y) * 0.1 text_color = 'white' # Contrast with red bars # Add the formatted label (rounded to 1 decimal place for clarity) ax.text(x, y_pos, f'{value:,.1f}', ha='center', va='center', fontweight='bold', color=text_color) plt.tight_layout() plt.show()
Key Changes:
- Target Bar Centers: We use
bar.get_x() + bar.get_width() / 2to get the exact center of each bar, so labels are perfectly aligned horizontally. - Conditional Y-Position: Depending on whether the value is positive or negative, we shift the label slightly inward so it stays inside the bar instead of floating outside.
- Contrast Text Color: Using white text on colored bars makes the labels easy to read.
- Readable Formatting: The
f'{value:,.1f}'format string adds commas and rounds to 1 decimal place, making large numbers easier to parse.
This should fix the alignment issue and put all labels neatly inside their corresponding bars!
内容的提问来源于stack exchange,提问作者AndrewRoj
相关产品推荐
相关产品推荐

