使用matplotlib在相空间中绘制箭头轨迹

14
我正在尝试为某个动力学系统绘制相空间图。实际上,我有一个二维平面,其中有一个起始点,接着是下一个点,以此类推。我想用线连接这些点,并在其上方绘制一些箭头,以便能够看到方向(从起始点到下一个点等)。我决定使用线型'->' 来实现这一点,但效果不佳,箭头经常指向错误的方向。而且它们非常紧密,因此我无法看到单独的线条。
我的代码如下:
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()

下图是得到的绘图结果: 相位图 可以看出,箭头没有正确对齐连接点之间的线条。此外,许多箭头是“向外”的,我希望它们是“向内”的,因为下一个点总是在中心闭环附近。此外,该绘图看起来太杂乱了,我想绘制更少的箭头,以使绘图更好看。有人知道如何做吗?谢谢。

例如,您可以使用plot(x,y,marker='o',markevery=5)来标记每个第五个数据点。不过要使它们指向正确的方向则更加困难。 - Tony Babarino
也可以看一下这个问题:https://dev59.com/ZGAg5IYBdhLWcg3wpMWz,或许能给您一些启示 :) - Tony Babarino
2
线条样式'->'不是箭头。它由两部分组成,'-'表示实线,'>'表示向右的三角形。如果你仔细看,所有你的“箭头”都只是指向右边的三角形。 - wflynny
@wflynny:没错!那我真的需要找到一个好答案来回答这个问题。 :) - Peaceful
或者 plt.streamplot - wflynny
显示剩余3条评论
1个回答

17

我认为解决方案应该是这样的:

enter image description here

使用该代码:
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)    

[编辑:关于索引的一些解释:

  • quiver的定义及其参数可以在此处找到:https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.quiver
  • 关于quiver的好例子可以在这里找到:https://www.getdatajoy.com/examples/python-plots/vector-fields
  • quiver需要向量作为输入,由起点和终点定义(起点和终点基本上是存储在sol中的线坐标中的点i和i+1)
  • 因此,向量数组的长度将比坐标数组的长度少一个
  • 为了弥补这一点,并为坐标和向量提供具有相同长度的数组,我们必须按以下方式处理索引:
  • sol[:-1, 0](第一个索引中的:-1删除最后一个坐标)
  • sol[1:, 0](第一个索引中的1:删除第一个坐标)
  • sol[1:, 0] - sol[:-1, 0] 因此是创建两个长度为n-1的向量并以使结果为sol[i+1] - sol[i]的方式将它们相减的方便方法

太好了!对我有用。但是,我想看一下您在 plt.quiver 中使用的 sol 索引的一些解释。 - Peaceful
1
抱歉,我已经包含了一些解释,希望有所帮助。 - tfv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接