饼图标签已旋转后,如何旋转autopct百分比文本?
环形饼图百分比文本旋转问题解决
问题背景
我绘制了一个环形饼图并旋转了标签,原始代码如下:
import pandas as pd import matplotlib.pyplot as plt data = { 'T1': [1,1,1,1,1,2,2,2,2,2, 1,1,1,1,1, 2,2,2,2,2, 1,1,1,1,1, 2,2,2,2], 'T2':['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B','B', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C','C', 'C', 'C', 'D', 'D', 'D', 'D']} df = pd.DataFrame(data) df['T1']=df['T1'].astype(str) fig, ax=plt.subplots() values2=df['T2'].value_counts().sort_index() pie1=ax.pie(values2, radius=1.3, autopct='%1.1f%%', labeldistance=0.4, labels=['one', 'two', 'three', 'four'], rotatelabels=True, startangle=223.5, wedgeprops=dict(width=1, edgecolor='w')); for tx in pie1[1]: rot = tx.get_rotation() tx.set_rotation(rot+90+(1-rot//180)*180) hole = plt.Circle((0, 0), 0.5, facecolor='white') plt.gcf().gca().add_artist(hole) plt.show()
原始效果(标签已正确旋转):
尝试旋转百分比文本时,使用以下代码处理pie1[2](对应autopct文本),但旋转效果和标签不一致:
for tx in pie1[2]: rotate = tx.get_rotation() tx.set_rotation(rotate+90+(1-rotate//180)*180)
问题效果:
请问这是什么原因?如何实现正确旋转?
原因分析
- 标签(
pie1[1])和百分比文本(pie1[2])的初始旋转基准逻辑不同:- 开启
rotatelabels=True后,标签的初始旋转会结合startangle偏移,自动适配饼块角度调整; - 百分比文本(autopct)的初始旋转默认以饼块中心角度的水平方向为基准,不继承
rotatelabels的调整逻辑,也不直接跟随startangle的偏移规则,导致两者初始旋转的基准存在差异。
- 开启
- 你复用的标签旋转公式是针对标签的初始旋转设计的,直接套用在百分比文本上会因为基准错位,导致最终旋转效果不一致。
解决方法
要让百分比文本和标签旋转方向一致,需基于饼块的实际角度重新计算旋转值,对齐标签的旋转逻辑:
修改后的完整代码
import pandas as pd import matplotlib.pyplot as plt data = { 'T1': [1,1,1,1,1,2,2,2,2,2, 1,1,1,1,1, 2,2,2,2,2, 1,1,1,1,1, 2,2,2,2], 'T2':['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B','B', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C','C', 'C', 'C', 'D', 'D', 'D', 'D']} df = pd.DataFrame(data) df['T1']=df['T1'].astype(str) fig, ax=plt.subplots() values2=df['T2'].value_counts().sort_index() pie1=ax.pie(values2, radius=1.3, autopct='%1.1f%%', labeldistance=0.4, labels=['one', 'two', 'three', 'four'], rotatelabels=True, startangle=223.5, wedgeprops=dict(width=1, edgecolor='w')); # 旋转标签(保留原有逻辑) for tx in pie1[1]: rot = tx.get_rotation() tx.set_rotation(rot+90+(1-rot//180)*180) # 旋转百分比文本,对齐标签旋转逻辑 for tx, wedge in zip(pie1[2], pie1[0]): # 获取饼块的中心角度 center_angle = (wedge.theta2 - wedge.theta1) / 2 + wedge.theta1 # 根据中心角度所在半圆计算旋转角度,确保文本正向可读 if center_angle <= 180: tx.set_rotation(center_angle - 90) else: tx.set_rotation(center_angle + 90) hole = plt.Circle((0, 0), 0.5, facecolor='white') plt.gcf().gca().add_artist(hole) plt.show()
关键调整说明
- 遍历百分比文本时,同时关联对应的饼块(
pie1[0]),直接从饼块的theta1和theta2参数计算中心角度,避免依赖不一致的初始旋转值; - 根据中心角度所在的半圆(左半/右半),计算与标签逻辑一致的旋转角度,保证所有文本都保持正向可读的状态。
内容的提问来源于stack exchange,提问作者Kajette
相关产品推荐
相关产品推荐

