我使用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楔的一角。正如你可以看到黑色箭头,那里没有问题。
有谁知道这里发生了什么?我怀疑可能存在骗子问题?
答案 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()