Python 在散点图中显示方向箭头

Python 在散点图中显示方向箭头,python,matplotlib,scatter-plot,Python,Matplotlib,Scatter Plot,我在散点图中绘制数据,我想看看滞后的方向。有人知道如何在指向下一个点的方向的每一条线上实现箭头吗 或者,标记可以替换为指向下一点方向的箭头 我要找的是: 获取不带箭头的绘图的代码: df = pd.DataFrame.from_dict({'x' : [0,3,8,7,5,3,2,1], 'y' : [0,1,3,5,9,8,7,5]}) x = df['x'] y = df['y'] fig, ax = plt.subplots() a

我在散点图中绘制数据,我想看看滞后的方向。有人知道如何在指向下一个点的方向的每一条线上实现箭头吗

或者,标记可以替换为指向下一点方向的箭头

我要找的是:

获取不带箭头的绘图的代码:

df = pd.DataFrame.from_dict({'x' : [0,3,8,7,5,3,2,1],
                             'y' : [0,1,3,5,9,8,7,5]})
x = df['x']
y = df['y']
fig, ax = plt.subplots()
ax.scatter(x,y)
ax.plot(x,y)

谢谢你的有用提示!以下是我的解决方案:

df = pd.DataFrame.from_dict({'x' : [0,3,8,7,5,3,2,1],
                             'y' : [0,1,3,5,9,8,7,5]})
x = df['x']
y = df['y']
# calculate position and direction vectors:
x0 = x.iloc[range(len(x)-1)].values
x1 = x.iloc[range(1,len(x))].values
y0 = y.iloc[range(len(y)-1)].values
y1 = y.iloc[range(1,len(y))].values
xpos = (x0+x1)/2
ypos = (y0+y1)/2
xdir = x1-x0
ydir = y1-y0
fig, ax = plt.subplots()
ax.scatter(x,y)
ax.plot(x,y)
# plot arrow on each line:
for X,Y,dX,dY in zip(xpos, ypos, xdir, ydir):
    ax.annotate("", xytext=(X,Y),xy=(X+0.001*dX,Y+0.001*dY), 
    arrowprops=dict(arrowstyle="->", color='k'), size = 20)
因此:

在这种情况下,plt.quiver没有帮助,因为它创建了一个箭头区域。plt.arrow随轴缩放,因此,如果x和y单位的数量级不相同,则会出现奇怪的箭头。因此,ax.annotate是我的选择。参数是文本 &xy分别表示箭头的开始和结束。

如注释所示,可以使用plt.quiver沿直线生成箭头,例如

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame.from_dict({'x' : [0,3,8,7,5,3,2,1],
                             'y' : [0,1,3,5,9,8,7,5]})
x = df['x'].values
y = df['y'].values

u = np.diff(x)
v = np.diff(y)
pos_x = x[:-1] + u/2
pos_y = y[:-1] + v/2
norm = np.sqrt(u**2+v**2) 

fig, ax = plt.subplots()
ax.plot(x,y, marker="o")
ax.quiver(pos_x, pos_y, u/norm, v/norm, angles="xy", zorder=5, pivot="mid")
plt.show()

可以使用箭头注释表示实际线段,如下所示:

df = pd.DataFrame.from_dict({'x' : [0,3,8,7,5,3,2,1],
                             'y' : [0,1,3,5,9,8,7,5]})

for i,row in df.iterrows():
    if i==0:
        pass
    else:
        plt.annotate('',xy=(row['x'],row['y']),xytext=(df.iloc[i-1]['x'],df.iloc[i-1]['y']),
        arrowprops=dict(facecolor='black',width=1,headwidth=5))

plt.xlim(0 ,10)
plt.ylim(0,10)

由于@NicoH,您可以使用颜色/宽度使其更漂亮。这段代码很棒。我用它来解决TSP问题

nyc_map_zoom = plt.imread('https://aiblog.nl/download/nyc_-74.3_-73.7_40.5_40.9.png')

def plot_on_map(df, BB, nyc_map, s=40, alpha=0.2):
    x = df['Longitude']
    y = df['Latitude']
    # calculate position and direction vectors:
    x0 = x.iloc[range(len(x)-1)].values
    x1 = x.iloc[range(1,len(x))].values
    y0 = y.iloc[range(len(y)-1)].values
    y1 = y.iloc[range(1,len(y))].values
    xpos = (x0+x1)/2
    ypos = (y0+y1)/2
    xdir = x1-x0
    ydir = y1-y0
    # plot map
    fig, ax = plt.subplots(figsize=(20,20))
    ax.scatter(x,y, marker='H',c='fuchsia',s=80,label=df["Name"])
    ax.set_xlim((BB[0], BB[1]))
    ax.set_ylim((BB[2], BB[3]))
    ax.set_title('Pizza Locations and Route Directions', fontsize=15)
    ax.imshow(nyc_map, zorder=0, extent=BB)
    ax.plot(x,y,linewidth=3)
    plt.legend(title='Pizza Joints', facecolor='white', framealpha=1,fontsize=15,title_fontsize=18, fancybox=True,edgecolor = 'k')
    # plot arrow on each line:
    for X,Y,dX,dY in zip(xpos, ypos, xdir, ydir):
        ax.annotate("", xytext=(X,Y),xy=(X+0.001*dX,Y+0.001*dY), 
        arrowprops=dict(arrowstyle="->", linewidth=3,color='k'), size = 40)
    plt.savefig('Pizza_Route.png',bbox_inches='tight');



BB_zoom = (-74.3, -73.7, 40.5, 40.9)
plot_on_map(TSP, BB_zoom, nyc_map_loc, s=20, alpha=0.3)
如果有两个点x0,y0和x1,y1,它们之间的中间是x0+y0/2,y0+y1/2。这将是箭头的位置。角度是arctanx1-x0,y1-y0`使用numpy.arctan2。箭头可以用PLT.Quiver绘制。