Трассировка фазового пространства рисования со стрелками в matplotlib

Я пытаюсь провести график фазового пространства для некоторой динамической системы. По сути, у меня есть 2d-плоскость, в которой есть начальная точка, за которой следует следующая точка и так далее. Я хочу связать эти точки с линиями, и, кроме того, я хочу нарисовать несколько стрелок, чтобы я мог видеть направление (отправная точка к следующей точке и т.д.). Я решил использовать linetype '->' для достижения этого, но он не дает никакого хорошего результата, и стрелки на самом деле, кажется, указывают в неправильном направлении много раз. Также они довольно близко расположены, и поэтому я не вижу отдельных линий.

Мой код приведен ниже:

import numpy as np
import matplotlib.pylab as plt
from scipy.integrate import odeint

def system(vect, t):
    x, y = vect
    return [x - y - x * (x**2 + 5 * y**2), x + y - y * (x**2 + y**2)]

vect0 = [(-2 + 4*np.random.random(), -2 + 4*np.random.random()) for i in range(5)]
t = np.linspace(0, 100, 1000)

for v in vect0:
    sol = odeint(system, v, t)
    plt.plot(sol[:, 0], sol[:, 1], '->')

plt.show()

Полученный график показан ниже: Фазовый график

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

Ответ 1

Я думаю, что решение будет выглядеть следующим образом:

введите описание изображения здесь

Используя этот код:

import numpy as np
import matplotlib.pylab as plt
from scipy.integrate import odeint
from scipy.misc import derivative

def system(vect, t):
    x, y = vect
    return [x - y - x * (x**2 + 5 * y**2), x + y - y * (x**2 + y**2)]

vect0 = [(-2 + 4*np.random.random(), -2 + 4*np.random.random()) for i in range(5)]
t = np.linspace(0, 100, 1000)

color=['red','green','blue','yellow', 'magenta']

plot = plt.figure()

for i, v in enumerate(vect0):
    sol = odeint(system, v, t)
    plt.quiver(sol[:-1, 0], sol[:-1, 1], sol[1:, 0]-sol[:-1, 0], sol[1:, 1]-sol[:-1, 1], scale_units='xy', angles='xy', scale=1, color=color[i])    

plt.show(plot)    

[EDIT: Некоторое объяснение по индексам:

  • Определение колчана и его аргументов можно найти здесь: http://matplotlib.org/api/pyplot_api.html
  • Хорошие примеры для колчана можно найти здесь: https://www.getdatajoy.com/examples/python-plots/vector-fields
  • колчану требуются векторы в качестве входов, которые отбрасываются начальной и конечной точками (start и и точки в основном являются точками я и я + 1 из координат линии, хранящихся в sol)
  • Как следствие, длина векторного массива будет меньше длины массива координат
  • Чтобы свести к минимуму и предоставить массивы с одинаковой длиной для координат и vecotors, чтобы дрожать, мы должны играть с индексами следующим образом:
  • sol[:-1, 0] (: -1 в первом индексе сбрасывает последнюю координату)
  • sol[1:, 0] (1: в первом индексе начинается сбрасывание первой координаты)
  • sol[1:, 0] - sol[:-1, 0], следовательно, является удобным способом создания двух векторов длины n-1 и вычитания их таким образом, что результат sol[i+1] - sol[i]