matplotlib 画一个弯曲的箭头,看起来就像pyplot,

a0x5cqrl  于 2023-10-24  发布在  其他
关注(0)|答案(2)|浏览(133)

我用pyplot.arrow画了一些直箭头,例如,

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. v={}
  4. for i in range (1,4):
  5. v[i]=np.array([np.cos(-2*np.pi/3*i),np.sin(-2*np.pi/3*i)])
  6. 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")
  7. 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")
  8. 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")
  9. plt.axes().set_xlim(-.5,1)
  10. plt.axes().set_ylim(-np.sqrt(3)/2,np.sqrt(3)/2)
  11. plt.axes().set_aspect(1)
  12. plt.show()

现在我也想画一些有圆形曲率的箭头,而不是直的,我看到我可以用pyplot.annotate()patches.FancyArrowPatchconnectionstyle="arc3,rad=.5"左右来实现这一点。
但是这些箭头看起来与pyplot.arrow s完全不同,并且与我的其他图形不匹配。我不知道如何将connectionstyle传递给pyplot.arrow。有没有一种方法可以绘制出与pyplot.arrow完全相同的弯曲箭头?

0s7z1bwu

0s7z1bwu1#

你不能用pyplot.arrow绘制弯曲的箭头。但是,patches.FancyArrowPatch应该提供所有的选项来获得你想要的任何箭头样式,所以我们的想法是对直箭头也使用FancyArrowPatch,这样你就可以对所有箭头使用相同的样式。

  1. import matplotlib.pyplot as plt
  2. import matplotlib.patches as patches
  3. plt.axes().set_xlim(-.5,0.5)
  4. plt.axes().set_ylim(-0.9,0.7)
  5. plt.axes().set_aspect(1)
  6. style = "Simple, tail_width=0.5, head_width=4, head_length=8"
  7. kw = dict(arrowstyle=style, color="k")
  8. a1 = patches.FancyArrowPatch((-0.4, -0.6), (0, 0.6), **kw)
  9. a2 = patches.FancyArrowPatch((0, 0.6), (0.4, -0.6), **kw)
  10. a3 = patches.FancyArrowPatch((-0.4, -0.6), (0.4, -0.6),
  11. connectionstyle="arc3,rad=.5", **kw)
  12. for a in [a1, a2, a3]:
  13. plt.gca().add_patch(a)
  14. plt.show()

展开查看全部
ff29svar

ff29svar2#

这是我最终使用的;它有点黑客,只是在Arc的两端绘制直的arrow头:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from matplotlib.patches import Arc
  4. def circarrow(self,diameter,centX,centY,startangle,angle,**kwargs):
  5. startarrow=kwargs.pop("startarrow",False)
  6. endarrow=kwargs.pop("endarrow",False)
  7. arc = Arc([centX,centY],diameter,diameter,angle=startangle,
  8. 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"))
  9. self.axes().add_patch(arc)
  10. if startarrow:
  11. startX=diameter/2*np.cos(np.radians(startangle))
  12. startY=diameter/2*np.sin(np.radians(startangle))
  13. startDX=+.000001*diameter/2*np.sin(np.radians(startangle)+kwargs.get("head_length",1.5*3*.001))
  14. startDY=-.000001*diameter/2*np.cos(np.radians(startangle)+kwargs.get("head_length",1.5*3*.001))
  15. self.arrow(startX-startDX,startY-startDY,startDX,startDY,**kwargs)
  16. if endarrow:
  17. endX=diameter/2*np.cos(np.radians(startangle+angle))
  18. endY=diameter/2*np.sin(np.radians(startangle+angle))
  19. endDX=-.000001*diameter/2*np.sin(np.radians(startangle+angle)-kwargs.get("head_length",1.5*3*.001))
  20. endDY=+.000001*diameter/2*np.cos(np.radians(startangle+angle)-kwargs.get("head_length",1.5*3*.001))
  21. self.arrow(endX-endDX,endY-endDY,endDX,endDY,**kwargs)
  22. import types
  23. plt.circarrow = types.MethodType(circarrow,plt)

函数名为circarrow,作为参数,您可以传递直径、中心的两个坐标、圆弧起始的Angular 和圆弧应该经过的总Angular ,以及传递给pyplot arrow的任何参数。要在圆弧的起始处绘制箭头,您可以指定startarrow=True,而endarrow=True将在弧的末端启用箭头。
下面是一个示例图像,您还可以看到箭头样式与直箭头一致:

  1. plt.plot(0,0,"o",markersize=10,color="black",mfc="none")
  2. 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")
  3. 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")
  4. plt.arrow(-.2,-.33,.6,+.33,width=0,head_width=.03,head_length=.045,length_includes_head=True,color="black")
  5. plt.axes().set_xlim(-.5,.5)
  6. plt.axes().set_ylim(-.5,.5)
  7. plt.axes().set_aspect(1)
  8. plt.show()

example image

展开查看全部

相关问题