Очень хороший ответ от Yann , но при использовании стрелки на получающиеся стрелки могут влиять соотношение сторон и пределы осей.Я сделал версию, которая использует axes.annotate () вместо axes.arrow ().Я включил это здесь для других, чтобы использовать.
Короче говоря, это используется для построения стрелок вдоль ваших линий в matplotlib.Код показан ниже.Это все еще можно улучшить, добавив возможность иметь разные стрелки.Здесь я включил только контроль ширины и длины стрелки.
import numpy as np
import matplotlib.pyplot as plt
def arrowplot(axes, x, y, narrs=30, dspace=0.5, direc='pos', \
hl=0.3, hw=6, c='black'):
''' narrs : Number of arrows that will be drawn along the curve
dspace : Shift the position of the arrows along the curve.
Should be between 0. and 1.
direc : can be 'pos' or 'neg' to select direction of the arrows
hl : length of the arrow head
hw : width of the arrow head
c : color of the edge and face of the arrow head
'''
# r is the distance spanned between pairs of points
r = [0]
for i in range(1,len(x)):
dx = x[i]-x[i-1]
dy = y[i]-y[i-1]
r.append(np.sqrt(dx*dx+dy*dy))
r = np.array(r)
# rtot is a cumulative sum of r, it's used to save time
rtot = []
for i in range(len(r)):
rtot.append(r[0:i].sum())
rtot.append(r.sum())
# based on narrs set the arrow spacing
aspace = r.sum() / narrs
if direc is 'neg':
dspace = -1.*abs(dspace)
else:
dspace = abs(dspace)
arrowData = [] # will hold tuples of x,y,theta for each arrow
arrowPos = aspace*(dspace) # current point on walk along data
# could set arrowPos to 0 if you want
# an arrow at the beginning of the curve
ndrawn = 0
rcount = 1
while arrowPos < r.sum() and ndrawn < narrs:
x1,x2 = x[rcount-1],x[rcount]
y1,y2 = y[rcount-1],y[rcount]
da = arrowPos-rtot[rcount]
theta = np.arctan2((x2-x1),(y2-y1))
ax = np.sin(theta)*da+x1
ay = np.cos(theta)*da+y1
arrowData.append((ax,ay,theta))
ndrawn += 1
arrowPos+=aspace
while arrowPos > rtot[rcount+1]:
rcount+=1
if arrowPos > rtot[-1]:
break
# could be done in above block if you want
for ax,ay,theta in arrowData:
# use aspace as a guide for size and length of things
# scaling factors were chosen by experimenting a bit
dx0 = np.sin(theta)*hl/2. + ax
dy0 = np.cos(theta)*hl/2. + ay
dx1 = -1.*np.sin(theta)*hl/2. + ax
dy1 = -1.*np.cos(theta)*hl/2. + ay
if direc is 'neg' :
ax0 = dx0
ay0 = dy0
ax1 = dx1
ay1 = dy1
else:
ax0 = dx1
ay0 = dy1
ax1 = dx0
ay1 = dy0
axes.annotate('', xy=(ax0, ay0), xycoords='data',
xytext=(ax1, ay1), textcoords='data',
arrowprops=dict( headwidth=hw, frac=1., ec=c, fc=c))
axes.plot(x,y, color = c)
axes.set_xlim(x.min()*.9,x.max()*1.1)
axes.set_ylim(y.min()*.9,y.max()*1.1)
if __name__ == '__main__':
fig = plt.figure()
axes = fig.add_subplot(111)
# my random data
scale = 10
np.random.seed(101)
x = np.random.random(10)*scale
y = np.random.random(10)*scale
arrowplot(axes, x, y )
plt.show()
Полученную цифру можно увидеть здесь: