Показать стрелки направления на диаграмме рассеяния - PullRequest
0 голосов
/ 11 октября 2019

Я строю данные в диаграмме рассеяния, и я хотел бы видеть направление гистерезиса. Кто-нибудь знает, как реализовать стрелки на каждой линии, которые указывают в направлении следующей точки?

В качестве альтернативы маркеры могут быть заменены стрелками, указывающими в направлении следующей точки.

Что я ищу:

enter image description here

Код для получения участка (без стрелок):

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)

Ответы [ 3 ]

2 голосов
/ 11 октября 2019

Как прокомментировано, можно использовать 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()

enter image description here

0 голосов
/ 11 октября 2019

Вы можете просто использовать стрелки-аннотации для представления фактических отрезков, например, так:

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)

output

можно поиграть с цветами / шириной, чтобысделать его красивее

0 голосов
/ 11 октября 2019

Спасибо за полезные советы! Вот мое решение:

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)

, которое дает это:

enter image description here

plt.quiver не помогает в этом случае, так какэто создает поле стрелок. plt.arrow масштабируется с осью, поэтому странно выглядящие стрелки, если единицы x и y не имеют одинаковый порядок величины. Таким образом, ax.annotate был моим выбором. Аргументы xytext & xy указывают соответственно начало и конец стрелки.

...