Matplotlib 2.1.0+饼图标签对齐问题:labeldistance与ha/va兼容求助
Yes, this is a known quirk in Matplotlib versions 2.1.0 and newer when using rotatelabels=True with pie charts. The ha and va parameters you pass via textprops get overwritten by the internal logic that handles rotating labels to align with each wedge's radial direction—that's why your first attempt didn't work. And when you manually reset those alignment properties afterward, you're changing the label's anchor point, which shifts the label's position inward (since the original placement was calculated for an edge-aligned anchor), leading to overlap with the pie.
Solution 1: Manually Position & Rotate Labels (Full Control)
Instead of relying on rotatelabels=True, calculate each label's position and rotation angle yourself. This lets you preserve the labeldistance positioning while ensuring labels are perfectly centered on their radial lines.
import matplotlib.pyplot as plt import numpy as np figure = plt.figure() axes = figure.add_subplot(111) axes.set_aspect(1) # Ensure circular pie y = [1,2,3, 4,8,16,18] labels = ['car','domino', 'romancical','testing1', 'thisisthelonglabel', 'fffffffffffffffffffffffffffffffffffffffffff', 'as'] radius = 1.2 labeldistance = 1.0 # Draw pie without auto-labels or rotation wedges, _ = plt.pie(y, radius=radius, startangle=10, wedgeprops={"linewidth": 0.7, "edgecolor": "white"}) # Calculate and place each label manually for wedge, label in zip(wedges, labels): # Get the mid-angle of the wedge (in degrees) wedge_mid_angle = (wedge.theta1 + wedge.theta2) / 2 # Convert to radians for trigonometric calculations angle_rad = np.deg2rad(wedge_mid_angle) # Calculate label position based on labeldistance label_x = radius * labeldistance * np.cos(angle_rad) label_y = radius * labeldistance * np.sin(angle_rad) # Add centered, rotated label axes.text(label_x, label_y, label, ha='center', va='center', rotation=wedge_mid_angle, # Align label with wedge direction fontsize=10) plt.show()
Solution 2: Fix Alignment Without Repositioning
If you prefer to keep using rotatelabels=True, you can adjust the alignment while compensating for the anchor point shift. Reset the label's position to its original coordinates after setting center alignment to maintain the labeldistance placement:
import matplotlib.pyplot as plt figure = plt.figure() axes = figure.add_subplot(111) axes.set_aspect(1) y = [1,2,3, 4,8,16,18] labels = ['car','domino', 'romancical','testing1', 'thisisthelonglabel', 'fffffffffffffffffffffffffffffffffffffffffff', 'as'] # Draw pie with auto-rotation enabled wedges, texts = plt.pie(y, radius=1.2, labels=labels, labeldistance=1.0, rotatelabels=True, startangle=10, wedgeprops={"linewidth": 0.7, "edgecolor": "white"}) for t in texts: # Save original position before changing alignment orig_x, orig_y = t.get_position() # Set center alignment t.set_horizontalalignment("center") t.set_verticalalignment("center") # Reset to original position to keep labeldistance intact t.set_position((orig_x, orig_y)) plt.show()
内容的提问来源于stack exchange,提问作者K.Ivi

