在matplotlib中以特定角度绘制饼图,并在楔块上绘制压裂图

时间:2012-02-10 00:12:30

标签: python matplotlib pie-chart wedge

我正在使用以下代码绘制带有matplotlib的饼图:

ax = axes([0.1, 0.1, 0.6, 0.6])
labels = 'Twice Daily', 'Daily', '3-4 times per week', 'Once per week','Occasionally'
fracs = [20,50,10,10,10]

explode=(0, 0, 0, 0,0.1)
patches, texts, autotexts = ax.pie(fracs, labels=labels, explode = explode,         
                             autopct='%1.1f%%', shadow =True)
proptease = fm.FontProperties()
proptease.set_size('xx-small')
setp(autotexts, fontproperties=proptease)
setp(texts, fontproperties=proptease)
rcParams['legend.fontsize'] = 7.0
savefig("pie1")

这会生成以下饼图。 PieChart 1

但是,我想在第一个楔形顶部开始饼图,我能找到的唯一解决方案就是使用this code

但是如下所示使用它,

from pylab import *
from matplotlib import font_manager as fm
from matplotlib.transforms import Affine2D
from matplotlib.patches import Circle, Wedge, Polygon
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111)

labels = 'Twice Daily', 'Daily', '3-4 times per week', 'Once per week','Occasionally'
fracs = [20,50,10,10,10]

 wedges, plt_labels = ax.pie(fracs, labels=labels)
 ax.axis('equal')

 starting_angle = 90
 rotation = Affine2D().rotate(np.radians(starting_angle))

for wedge, label in zip(wedges, plt_labels):
  label.set_position(rotation.transform(label.get_position()))
  if label._x > 0:
    label.set_horizontalalignment('left')
  else:
    label.set_horizontalalignment('right')

  wedge._path = wedge._path.transformed(rotation)

plt.savefig("pie2")

这会生成以下饼图

enter image description here

然而,这并不像早期的饼图那样打印楔形物上的压裂物。我尝试了一些不同的东西,但我无法保留压裂。我怎样才能在中午开始第一个楔子并在楔子上显示压裂?

1 个答案:

答案 0 :(得分:2)

通常我不建议更改工具的来源,但是将它固定在外面并且容易在里面是很麻烦的。所以这就是我要做的事情,如果你现在需要这个工作(tm),有时你会这样做..

在文件matplotlib/axes.py中,将饼图函数的声明更改为

def pie(self, x, explode=None, labels=None, colors=None,
        autopct=None, pctdistance=0.6, shadow=False,
        labeldistance=1.1, start_angle=None):

即。只需将start_angle=None添加到参数的末尾。

然后添加“#addition”括起来的五行。

    for frac, label, expl in cbook.safezip(x,labels, explode):
        x, y = center
        theta2 = theta1 + frac
        thetam = 2*math.pi*0.5*(theta1+theta2)

        # addition begins here
        if start_angle is not None and i == 0:
            dtheta = (thetam - start_angle)/(2*math.pi)
            theta1 -= dtheta
            theta2 -= dtheta
            thetam = start_angle
        # addition ends here

        x += expl*math.cos(thetam)
        y += expl*math.sin(thetam)

然后,如果start_angle为None,则没有任何反应,但如果start_angle有一个值,那么这就是第一个切片(在本例中是20%)居中的位置。例如,

patches, texts, autotexts = ax.pie(fracs, labels=labels, explode = explode,         
                             autopct='%1.1f%%', shadow =True, start_angle=0.75*pi)

产生

enter image description here

请注意,一般情况下你应该避免这样做,修补我的意思是来源,但过去有些时候我已经在截止日期并且只是想要一些现在(tm),所以你去..