[PYTHON] Two solutions to the problem that it is hard to see the vector field when writing a vector field with quiver () of matplotlib pyplot

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.

Premise

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)

image.png

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')

image.png

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'

Implementation example

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)

Comparison of results

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 image.png

When dt = 0.01 image.png

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.

Postscript

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

Two solutions to the problem that it is hard to see the vector field when writing a vector field with quiver () of matplotlib pyplot
I want to solve the problem of memory leak when outputting a large number of images with Matplotlib
When the variable you want to superscript with matplotlib is two or more characters
Try to find the probability that it is a multiple of 3 and not a multiple of 5 when one is removed from a card with natural numbers 1 to 100 using Ruby and Python.
I thought a little because the Trace Plot of the stan parameter is hard to see.
[VLC] How to deal with the problem that it is not in the foreground during playback
I tried to make a site that makes it easy to see the update information of Azure
How to deal with the problem that the current directory moves when Python is executed from Atom
What to do when a part of the background image becomes transparent when the transparent image is combined with Pillow
It is good to create an environment with runtime error => venv when using pyplot backends of macosx on a virtual environment created with virtualenv.
How to deal with the problem that build fails when CI / CD of Python Function with AWS Amplify
In IPython, when I tried to see the value, it was a generator, so I came up with it when I was frustrated.
It seems that the version of pyflakes is not the latest when flake8 is installed
[Python] Solution to the problem that elements are linked when copying a list
Hackathon's experience that it is most important to understand the feelings of the organizer
A solution to the problem that kernel restarting frequently occurs when running PyQt system with jupyter or Spyder IDE
It is a piggybacking story about the service that returns "Nyan" when you ping
[Python Data Frame] When the value is empty, fill it with the value of another column.
A story that failed when trying to remove the suffix from the string with rstrip
Try to create a battle record table with matplotlib from the data of "Schedule-kun"
It was a little difficult to do flask with the docker version of nginx-unit
[Shell art] Only when it is a multiple of 3 and a number with 3 becomes stupid
A memo on how to overcome the difficult problem of capturing FX with AI
A memo of misunderstanding when trying to load the entire self-made module with Python3
When writing to a csv file with python, a story that I made a mistake and did not meet the delivery date
A script that pings the registered server and sends an email with Gmail a certain number of times when it fails
Add information to the bottom of the figure with Matplotlib
Is it a problem to eliminate the need for analog human resources in the AI era?
The sound of tic disorder at work is ... I managed to do it with the code
When reading an image with SimpleITK, there is a problem if there is Japanese in the path
[Python] I want to make a 3D scatter plot of the epicenter with Cartopy + Matplotlib!
A script that makes it easy to create rich menus with the LINE Messaging API
Summary of points to keep in mind when writing a program that runs on Python 2.5
About the contents of wscript when building a D language environment like that with Waf
A story that makes it easier to see Model debugging in the Django + SQLAlchemy environment
When a character string of a certain series is in the Key of the dictionary, the character string is converted to the Value of the dictionary.
A simple version of government statistics (immigration control) that is easy to handle with jupyter
How to plot a lot of legends by changing the color of the graph continuously with matplotlib
A person who wants to clear the D problem with ABC of AtCoder tried to scratch
When generating a large number of graphs with matplotlib, I do not want to display the graph on the screen (jupyter environment)
I want to output while converting the value of the type (e.g. datetime) that is not supported when outputting json with python
What do you do with configuration management of a server that has implemented Ansible but is already running? I'm hitting the problem