问题
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??
回答1:
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..
来源:https://stackoverflow.com/questions/9220933/plotting-a-pie-chart-in-matplotlib-at-a-specific-angle-with-the-fracs-on-the-wed