我使用pyplot.arrow
做一些直箭,例如,
import matplotlib.pyplot as plt
import numpy as np
v={}
for i in range (1,4):
v[i]=np.array([np.cos(-2*np.pi/3*i),np.sin(-2*np.pi/3*i)])
plt.arrow(.85*(.05*v[2]+.95*v[1])[0],.85*(.05*v[2]+.95*v[1])[1],.85*.9*(v[2]-v[1])[0],.85*.9*(v[2]-v[1])[1],width=0,head_width=.03,head_length=.045,length_includes_head=True,color="black")
plt.arrow(.85*(.05*v[3]+.95*v[2])[0],.85*(.05*v[3]+.95*v[2])[1],.85*.9*(v[3]-v[2])[0],.85*.9*(v[3]-v[2])[1],width=0,head_width=.03,head_length=.045,length_includes_head=True,color="black")
plt.arrow(.85*(.05*v[1]+.95*v[3])[0],.85*(.05*v[1]+.95*v[3])[1],.85*.9*(v[1]-v[3])[0],.85*.9*(v[1]-v[3])[1],width=0,head_width=.03,head_length=.045,length_includes_head=True,color="black")
plt.axes().set_xlim(-.5,1)
plt.axes().set_ylim(-np.sqrt(3)/2,np.sqrt(3)/2)
plt.axes().set_aspect(1)
plt.show()
现在我想绘制一些圆弧曲线而不是直线的箭头。我发现我可以使用pyplot.annotate()
或patches.FancyArrowPatch
并connectionstyle="arc3,rad=.5"
左右来实现此目的。
但是这些箭头看起来与pyplot.arrow
完全不同,并且不适合我的其他数字。而且我不知道如何将connectionstyle
传递给pyplot.arrow
。有没有办法绘制看起来与pyplot.arrow
完全相同的弯曲箭头?
答案 0 :(得分:11)
您无法使用pyplot.arrow
绘制弯曲箭头。但是,patches.FancyArrowPatch
应提供所有选项以获得您想要的任何箭头样式,因此我们的想法是使用FancyArrowPatch
作为直箭头,这样您就可以使用相同的样式箭头
import matplotlib.pyplot as plt
import matplotlib.patches as patches
plt.axes().set_xlim(-.5,0.5)
plt.axes().set_ylim(-0.9,0.7)
plt.axes().set_aspect(1)
style="Simple,tail_width=0.5,head_width=4,head_length=8"
kw = dict(arrowstyle=style, color="k")
a1 = patches.FancyArrowPatch((-0.4,-0.6), (0,0.6),**kw )
a2 = patches.FancyArrowPatch((0,0.6), (0.4,-0.6),**kw)
a3 = patches.FancyArrowPatch((-0.4,-0.6), (0.4,-0.6),connectionstyle="arc3,rad=.5", **kw)
for a in [a1,a2,a3]:
plt.gca().add_patch(a)
plt.show()
答案 1 :(得分:3)
这是我最终使用的内容;它有点像黑客,只是在arrow
的末尾画出Arc
个直头:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Arc
def circarrow(self,diameter,centX,centY,startangle,angle,**kwargs):
startarrow=kwargs.pop("startarrow",False)
endarrow=kwargs.pop("endarrow",False)
arc = Arc([centX,centY],diameter,diameter,angle=startangle,
theta1=np.rad2deg(kwargs.get("head_length",1.5*3*.001)) if startarrow else 0,theta2=angle-(np.rad2deg(kwargs.get("head_length",1.5*3*.001)) if endarrow else 0),linestyle="-",color=kwargs.get("color","black"))
self.axes().add_patch(arc)
if startarrow:
startX=diameter/2*np.cos(np.radians(startangle))
startY=diameter/2*np.sin(np.radians(startangle))
startDX=+.000001*diameter/2*np.sin(np.radians(startangle)+kwargs.get("head_length",1.5*3*.001))
startDY=-.000001*diameter/2*np.cos(np.radians(startangle)+kwargs.get("head_length",1.5*3*.001))
self.arrow(startX-startDX,startY-startDY,startDX,startDY,**kwargs)
if endarrow:
endX=diameter/2*np.cos(np.radians(startangle+angle))
endY=diameter/2*np.sin(np.radians(startangle+angle))
endDX=-.000001*diameter/2*np.sin(np.radians(startangle+angle)-kwargs.get("head_length",1.5*3*.001))
endDY=+.000001*diameter/2*np.cos(np.radians(startangle+angle)-kwargs.get("head_length",1.5*3*.001))
self.arrow(endX-endDX,endY-endDY,endDX,endDY,**kwargs)
import types
plt.circarrow = types.MethodType(circarrow,plt)
该函数被称为circarrow
,作为参数传递直径,中心的两个坐标,弧开始的角度和弧应该通过的总角度,以及任何参数传递给pyplot arrow
的。要在弧的开头绘制箭头,请指定startarrow=True
,而endarrow=True
将在弧的末尾启用箭头。
这是一个示例图像,您还可以看到箭头样式与直箭头一致:
plt.plot(0,0,"o",markersize=10,color="black",mfc="none")
plt.circarrow(.85,0,0,0.05*120,.9*120,startarrow=True,width=0,head_width=.03,head_length=.045,length_includes_head=True,color="black")
plt.circarrow(.85,0,0,1.05*120,.9*120,startarrow=True,endarrow=True,width=0,head_width=.03,head_length=.045,length_includes_head=True,color="black")
plt.arrow(-.2,-.33,.6,+.33,width=0,head_width=.03,head_length=.045,length_includes_head=True,color="black")
plt.axes().set_xlim(-.5,.5)
plt.axes().set_ylim(-.5,.5)
plt.axes().set_aspect(1)
plt.show()