matplotlib 2D单侧方向箭头

weylhg0b  于 2023-02-23  发布在  其他
关注(0)|答案(1)|浏览(90)

I have the following code:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

N = 20
T = np.linspace(0, 1, N)
fig, ax = plt.subplots()

def lerp(p0, p1, t):
    return (1-t) * p0 + t * p1

def de_casteljaus(p0, p1, p2, p3, t):
    A = lerp(p0, p1, t)
    B = lerp(p1, p2, t)
    C = lerp(p2, p3, t)
    D = lerp(A, B, t)
    E = lerp(B, C, t)
    return lerp(D, E, t)

p0, p1, p2, p3 = np.array([[0, 0], [0.2, 0.4], [0.8, 0.2], [1, 1]])
ax.add_line(Line2D([p0[0], p1[0]], [p0[1], p1[1]], marker=">", linewidth=0.2))
ax.add_line(Line2D([p2[0], p3[0]], [p2[1], p3[1]], marker=">", linewidth=0.2))

X, Y = np.zeros(N), np.zeros(N)
for i, t in enumerate(T):
    [x, y] = de_casteljaus(p0, p1, p2, p3, t)
    X[i] = x
    Y[i] = y

ax.plot(X, Y)

ax.set_xlim(-0.1, 1.1)
ax.set_ylim(-0.1, 1.1)

The important part is these two lines

ax.add_line(Line2D([p0[0], p1[0]], [p0[1], p1[1]], marker=">", linewidth=0.2))
ax.add_line(Line2D([p2[0], p3[0]], [p2[1], p3[1]], marker=">", linewidth=0.2))

I have two problems with the lines however:

  • The arrow heads / markers are at both ends. I only want it at the leading end
  • The second line arrow heads are in the wrong direction (should be pointing down)
  • The arrow heads / markers are not exactly perpendicular with the line & aren't centred on the line

So something like

iovurdzv

iovurdzv1#

Not sure if you want to stick to ax.add_line() , but if not, a good alternative is plt.arrow() :

ax.arrow(x=p0[0], y=p0[1], dx=p1[0] - p0[0], dy=p1[1] - p0[0], 
         width=0.01, edgecolor='none')

which can be customised in many ways: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.arrow.html

相关问题