以特定角度在matplotlib中绘制饼图,并与楔块上的压裂痕迹相对应 [英] Plotting a pie-chart in matplotlib at a specific angle with the fracs on the wedges

查看:117
本文介绍了以特定角度在matplotlib中绘制饼图,并与楔块上的压裂痕迹相对应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码绘制带有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")

这将产生以下饼图.

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

这将产生以下饼图

但是,这不会像以前的饼图中那样在楔块上打印出压裂痕迹.我尝试了几种不同的方法,但是我无法保留这些碎片.如何在中午开始第一个楔形并在楔形上也显示裂缝?

解决方案

通常,我不建议更改工具的来源,但是要在外部轻松地解决此问题是不明智的.因此,如果您需要立即进行此操作,而有时又需要这样做,这就是我要做的事情.

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

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.

然后添加用#加法"括起来的五行.

    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)

产生

请注意,通常您应该避免这样做,修补我的意思是,但是过去有些时候我已经到了最后期限,只是想要Now(tm),所以就可以了..

I am plotting a piechart with matplotlib using the following code:

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")

This produces the following piechart.

However, I want to start the pie-chart with the first wedge on top, the only solution I could find for this was using this code

However on using this as below,

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")

This produces the following pie chart

However, this does not print the fracs on the wedges as in the earlier pie chart. I have tried a few different things, but I am not able to preserve the fracs. How can I start the first wedge at noon and display the fracs on the wedges as well??

解决方案

Ordinarily I wouldn't recommend changing the source of a tool, but it's hacky to fix this outside and easy inside. So here's what I'd do if you needed this to work Right Now(tm), and sometimes you do..

In the file matplotlib/axes.py, change the declaration of the pie function to

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

i.e. simply add start_angle=None to the end of the arguments.

Then add the five lines bracketed by "# 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)

Then if start_angle is None, nothing happens, but if start_angle has a value, then that's the location that the first slice (in this case the 20%) is centred on. For example,

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

produces

Note that in general you should avoid doing this, patching the source I mean, but there are times in the past when I've been on deadline and simply wanted something Now(tm), so there you go..

这篇关于以特定角度在matplotlib中绘制饼图,并与楔块上的压裂痕迹相对应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆