The method plt.quiver (), which is a standard method when writing vector fields with Matplotlib.pyplot, is very difficult to use. We suggest the tips for drawing beautifully and the use of plt.streamplot () for upward compatibility.
Given the differential equation U or ("or") V
I want to know the behavior of these solution trajectories
plt.quiver(X,Y,U,V,C,cmap) It writes a vector by specifying the initial value and the difference from it. Italics are optional but very convenient, so I recommend them. Set the initial value for X and Y withmgrid etc. For U and V, "difference" when moving from those lattice points by the step size → If you want to know the solution trajectory of the differential equation, solve it numerically using Runge-Kutta etc., and the difference at that time Set the term or step size $ \ Delta t $ (constant, XT plot only). It is often used when the solution orbit is calculated by Runge-Kutta. If it is left as it is, the size of the vector will be reflected as it is in the size of the arrow! In this case, if the size of the vector is relatively different within the drawing range, this will happen.
plt.quiver(u,v,U,V)
No, it's hard to see. It's too hard to see and it became a water eggplant. It makes me wonder if I made a mistake in the calculation anymore. The masterpiece of nonlinear dynamics, "Strogats Nonlinear Dynamics and Chaos," states:
"Unfortunately, vector arrowheads and differences in length tend to clutter the figure."(p.162)
You're right. The book proposes and adopts a unified size to show the direction field. Following this, we will introduce a ** color map ** that was not possible with black and white books. Expressing speed by doing so, aiming to exceed the original family.
First, unify the size by dividing itself by the size of the vector. By giving this "size" value to the fifth argument, it is linked to the "color map" specified by cmap.
plt.quiver(u,v,U/np.sqrt(pow(U,2)+pow(V,2)),V/np.sqrt(pow(U,2)+pow(V,2)),np.sqrt(pow(U,2)+pow(V,2)), cmap='jet')
Yes, it's easy to understand. The difference is clear. By the way, this is a model that represents the membrane potential of nerves, and the 4th-order Runge-Kutta method is applied in 1 step with a step width of 0.1.
plt.streamplot(X,Y,U,V) ** It will calculate the solution trajectory according to the initial value **. The accuracy will be described later. The initial value is set for X and Y by mgrid etc., but for some reason, if Y is not written first, an error will definitely occur (Value Error: The rows of'x' must be equal). I haven't investigated it because it's just a matter of replacing it, but if you can understand it, please let me know in the comments.
U and V are different, and the differential equation (variable representing) is written here as it is. Since a continuous arrow is drawn, the size of the vector does not correspond to the size of the arrow, but it can be reflected in the color using the option.
Example)
plt.streamplot(X,Y,U,V,color = np.sqrt(U**2+V**2)), cmap='jet'
u, v Define the two-dimensional differential equation with udot, vdot, give the initial value for quiver with u, v, and the initial value for stream plot with x, y (as mentioned above, an error will occur unless the order is changed. Because).
import numpy as np
import matplotlib.pyplot as plt
#Differential equation you are thinking(cf;Strogats Nonlinear Dynamics and Chaos p.172)
def udot(u,v):
return u*(3-u-2*v)
def vdot(u,v):
return v*(2-u-v)
#streamplot (What a two line! Use a color map that displays red for large heatmaps and blue for small heatmaps.)
y, x= np.mgrid[0:2:20j,0:3:20j]
plt.streamplot(x,y,udot(x,y),vdot(x,y),color=np.sqrt(udot(x,y)**2+vdot(x,y)**2),cmap='jet')
#Next, prepare Runge-Kutta for quiver.
def rk4th_1step_2d(func,u,v,dt):
k1 = func(u,v)*dt
k2 = func(u+k1/2, v+k1/2)*dt
k3 = func(u+k2/2, v+k2/2)*dt
k4 = func(u+k3, v+k3)*dt
return (k1+2*k2+2*k3+k4)/6
#Plot quiver
u, v = np.mgrid[0:3:20j,0:2:20j]
U = rk4th_1step_2d(udot,u,v,0.1)
V = rk4th_1step_2d(vdot,u,v,0.1)
plt.quiver(u,v,U,V)
In Runge-Kutta, in principle, the smaller the step size, the closer to the accurate value, so I investigated how the solution orbit changes between the cases of dt = 0.1 and dt = 0.01.
When dt = 0.1
When dt = 0.01
It can be seen that when the step size specified by dt is reduced, it approaches parallel to the solution trajectory issued by the stream plot. The lower right corner is easy to understand. streamplot seems to be doing fairly accurate calculations behind the scenes. I want to read what kind of calculation I am doing.
The source code is on this site, and it turns out that it mainly uses the second-order Runge-Kutta method that uses adaptive step size control. https://matplotlib.org/3.1.3/_modules/matplotlib/streamplot.html
Recommended Posts