You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

饼图标签已旋转后,如何旋转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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 18:40:41