奇怪的饼图被切断

时间:2018-05-15 19:28:11

标签: python matplotlib visualization

我使用matplotlib饼作为基础来创建一个量表:

import matplotlib.pyplot as plt
import math    

theta = 0.2

group_size=[10,10,10,10,10,50]

mid = [18,54,90,126,162]

from textwrap import wrap
labels=['1','2','3','4','5','']
labels = [ '\n'.join(wrap(l, 9)) for l in labels ]

fig, ax = plt.subplots()

ax.axis('equal')
pie3 = ax.pie(group_size, radius=2.2, colors=['k'] ,startangle=180,counterclock=False)

my_circle=plt.Circle( (0,0), 0.4, color='white')
p=plt.gcf()
p.gca().add_artist(my_circle)

pie4 = ax.pie([10,10,10,10,10,50], radius=2,  labeldistance=0.9, labels=labels,
              startangle=180,rotatelabels =True,counterclock=False)

plt.setp(pie4[1], rotation_mode="anchor", ha="center", va="center")
for tx in pie4[1]:
    font = tx.get_fontsize()
    tx.set_fontsize(12)
    rot = tx.get_rotation()
    tx.set_rotation(rot+90+(1-rot//180)*180)

for pie_wedge in pie3[0]:
    pie_wedge.set_edgecolor('white')

for pie_wedge in pie4[0]:
    pie_wedge.set_edgecolor('white')
    pie_wedge.set_linewidth(4)

#arrow bottom circle
ax.add_patch(Circle((0, 0), radius=0.15, facecolor='k',zorder=12))
ax.add_patch(Circle((0, 0), radius=0.13, facecolor='w',zorder=13))

ax.arrow(0, 0, 1.7 * np.sin(math.radians(theta*180-90)), 1.7 * np.cos(math.radians(theta*180-90)), \
                 width=0.15, head_width=0.15, head_length=0.2, fc='k', ec='k')

theta2 = 0.45

ax.arrow(0, 0, 1.7 * np.sin(math.radians(theta2*180-90)), 1.7 * np.cos(math.radians(theta2*180-90)), \
                 width=0.15, head_width=0.15, head_length=0.2, fc='k', ec='k',zorder=20)

现在问题是我的仪表箭头(红色)似乎在顶部被切断,如果它位于2和4之间。几乎就像2楔形的左角和右边之间有一条想象线4楔的一角。正如你可以看到黑色箭头,那里没有问题。

enter image description here

有谁知道这里发生了什么?我怀疑可能存在骗子问题?

1 个答案:

答案 0 :(得分:1)

我认为你基本上认为它是一个骗子问题,或者至少是一个框架大小问题。正如你所拥有的那样,你正在绘制超出图形边界的饼图(这个边界是"假想线"你在你的问题中说的)。箭头不知道如何处理这个问题,只是在框架的位置被切断。解决这个问题的一种方法是绘制半径为1的饼图(而不是2,就像你所拥有的那样),以便它都在matplotlib框架的限制范围内,然后只划分箭头长度和其他箭头参数按2或左右,相应地缩放所有内容。这基本上是我修改你的代码所做的,让你去做(我在#### CAPS LOCK ####的评论里放了一些东西):

from matplotlib.patches import Circle
import matplotlib.pyplot as plt
import math    

theta = 0.2

group_size=[10,10,10,10,10,50]

mid = [18,54,90,126,162]

from textwrap import wrap
labels=['1','2','3','4','5','']
labels = [ '\n'.join(wrap(l, 9)) for l in labels ]

fig, ax = plt.subplots()

ax.axis('equal')
### CHANGED RADIUS HERE ###
pie3 = ax.pie(group_size,radius=1, colors=['k'] ,startangle=180,counterclock=False)

my_circle=plt.Circle( (0,0), 0.4, color='white')
p=plt.gcf()
p.gca().add_artist(my_circle)

### CHANGED RADIUS HERE ###
pie4 = ax.pie([10,10,10,10,10,50], radius=0.9,  labeldistance=0.85, labels=labels,
              startangle=180,rotatelabels =True,counterclock=False)

plt.setp(pie4[1], rotation_mode="anchor", ha="center", va="center")
for tx in pie4[1]:
    font = tx.get_fontsize()
    tx.set_fontsize(12)
    rot = tx.get_rotation()
    tx.set_rotation(rot+90+(1-rot//180)*180)

for pie_wedge in pie3[0]:
    pie_wedge.set_edgecolor('white')

### DIVIDED LINEWIDTH BY 2 FOR SCALING ###
for pie_wedge in pie4[0]:
    pie_wedge.set_edgecolor('white')
    pie_wedge.set_linewidth(2)

#arrow bottom circle
### DIVIDED RADIUS BY 2 FOR SCALING ###
ax.add_patch(Circle((0, 0), radius=0.15/2, facecolor='k',zorder=12))
ax.add_patch(Circle((0, 0), radius=0.13/2, facecolor='w',zorder=13))

### DIVIDED SOME PARAMETERS BY 2.2 FOR SCALING ####
ax.arrow(0, 0, 1.7/2.2 * np.sin(math.radians(theta*180-90)), 1.7/2.2 * np.cos(math.radians(theta*180-90)), \
                 width=0.15/2, head_width=0.15/2, head_length=0.2/2, fc='k', ec='k')

theta2 = 0.45

### DIVIDED SOME PARAMETERS BY 2.2 FOR SCALING ####
ax.arrow(0, 0, 1.7/2.2 * np.sin(math.radians(theta2*180-90)), 1.7/2.2 * np.cos(math.radians(theta2*180-90)), \
                 width=0.15/2, head_width=0.15/2, head_length=0.2/2, fc='k', ec='k')

#### TIGHT LAYOUT MAKES SENSE HERE ####
plt.tight_layout()

enter image description here