在matplotlib中用箭头绘制相空间轨迹 [英] Drawing phase space trajectories with arrows in matplotlib
问题描述
我正在尝试为某个动力系统绘制相空间图.实际上,我有一个2d平面,其中有一个起点,然后是下一个点,依此类推.我想将这些点与线连接起来,并在上面绘制一些箭头,以便能够看到方向(起点到下一个点等).我决定使用线型'->'
来实现这一点,但效果不佳,箭头实际上似乎多次指向错误的方向.而且它们之间的间距非常近,因此我看不到单独的线条.
我的代码如下:
将 numpy 导入为 np导入 matplotlib.pylab 作为 plt从scipy.integrate导入odeintdef系统(vect,t):x, y = 向量返回 [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)v 在 vect0 中:溶胶 = odeint(系统,v,t)plt.plot(sol[:, 0], sol[:, 1], '->')plt.show()
结果图如下所示:
可以看出,箭头与连接点的线没有正确对齐.另外,许多箭头正在伸出",我希望它们进入",因为下一点始终位于中间的闭合循环处.此外,情节看起来太乱了,我想绘制更少的箭头,这样情节看起来会更好.有没有人知道如何做到这一点?提前致谢.
我认为解决方案如下:
使用该代码:
将numpy导入为np导入 matplotlib.pylab 作为 plt从scipy.integrate导入odeint从 scipy.misc 导入衍生定义系统(向量,t):x, y = 向量返回 [x - y - x * (x**2 + 5 * y**2), x + y - y * (x**2 + y**2)]vect0 = [(-2)对于范围(5)中的i,为((-2 + 4 * np.random.random(),-2 + 4 * np.random.random())]t = np.linspace(0,100,1000)color=['红色','绿色','蓝色','黄色','洋红色']绘图 = plt.figure()对于i,enumerate(vect0)中的v:sol = odeint(系统,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', 角度='xy', scale=1, color=color[i])plt.show(图)
(第一个索引中的:-1 去掉最后一个坐标)
sol[1:, 0]
(1: 在第一个索引开始下降第一个坐标) sol [1 :, 0]-sol [:-1,0]
是创建长度为n-1的两个矢量并将它们相减的一种便捷方法,其结果是sol[i+1] - sol[i]
I am trying to draw the phase space plot for a certain dynamical system. In effect, I have a 2d plane in which there is a starting point followed by next point and so on. I want to connect these points with lines and on top of that I want to draw some arrows so that I would be able to see the direction (starting point to the next point etc). I decided to use linetype '->'
to achieve this but it doesn't give any good result and arrows actually seem to point in wrong direction many times. Also they are quite closely spaced and hence I can't see the individual lines.
My code is given below:
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()
The resulting plot is shown below:
As can be seen, the arrows are not properly aligned to the lines that connect the points. Also, many arrows are "going out" and I want them to "come in" because the next point always lies towards the close loop at the middle. Moreover, plot looks too messy and I would like to plot fewer arrows so that plot would look better. Does anybody have any idea as how to do it? Thanks in advance.
I think a solution would then look like this:
Using that code:
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: Some explanation on indices:
- A definition of quiver and its arguments can be found here: https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.quiver
- Good examples for quiver can be found here: https://www.getdatajoy.com/examples/python-plots/vector-fields
- quiver requires vectors as inputs, which are defined by a start and end points (start and end points are basically points i and i+1 from the line coordinates stored in sol)
- As a consequence, the length of the vector array will be one shorter than the length of the coordinate array
- In order to compensate for that and to provide arrays with the same length for coordinates and vectors to quiver, we have to play with indices as follows:
sol[:-1, 0]
(:-1 in first index drops the last coordinate)sol[1:, 0]
(1: in first index starts drops first coordinate)sol[1:, 0] - sol[:-1, 0]
is therefore a convenient way to create two vectors of length n-1 and subtract them in a way that the result issol[i+1] - sol[i]
这篇关于在matplotlib中用箭头绘制相空间轨迹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!