matplotlib pyplot의 quiver ()로 벡터 필드를 작성하면 빌어 먹기 어려워지는 문제의 두 가지 해결책

Matplotlib.pyplot에서 벡터 필드를 작성할 때 클래식한 메소드 plt.quiver()는 매우 사용하기가 어렵습니다.
깔끔하게 그리는 요령과 상위 호환으로서의 plt.streamplot()의 이용을 제안한다.

전제



미분 방정식 U 또는 ("또는") V가 주어진다.

이러한 해궤도의 행동을 알고 싶습니다.

plt.quiver(X,Y,U,V,C,cmap)



초기 값과 거기에서의 차이를 지정하여 벡터를 작성합니다. 기울임꼴은 옵션이지만 매우 편리하므로 추천하는 사람.
X, Y에는 초기값을 mgrid 등으로 설정
U, V에는 그들 격자점에서 새겨진 폭만큼 이동했을 때의 「차분」→미분 방정식의 해궤도를 알고 싶은 경우는 Runge-Kutta 등을 사용해 수치적으로 풀어 줘, 그 때의 차분의 항 또는 너비 $\Delta t$ (상수, X-T 플롯의 경우에만)를 설정합니다. 해궤도를 Runge-Kutta로 어울리는 경우에 자주 사용되기 쉽다.
그대로 벡터의 크기는 그대로 화살표의 크기에 반영되어 버린다!
plt.quiver(u,v,U,V)



아니, 보기 힘들어. 너무 보기 힘들어 물 가지가 됐네
비선형 다이나믹스의 명저 「스트로가츠 비선형 다이나믹스와 혼돈」에는 이렇게 있다.
「ベクトルの矢じりや長さの違いは、残念ながら図を乱雑にしてしまいがちである」(p.162)

말씀하신 대로입니다. 이 책에서는 크기를 통일하여 방향장을 나타내는 것을 제안, 채용하고 있습니다. 표현, 본가 초과을 목표로 한다.

우선 벡터의 크기로 자신을 나누어 크기를 통일.
이 "크기"의 값을 다섯 번째 인수에 제공하여 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')



그렇습니다. 이해하기 쉽습니다. 차이는 엄청납니다.
덧붙여서 이것은 신경의 막 전위를 나타내는 모델에 4차의 Runge-Kutta법을 새겨 폭 0.1로 1스텝 적용한 것.

plt.streamplot(X,Y,U,V)



초기값에 대응한 해궤도를 마음대로 계산해 준다. 정확성에 대해서는 후술.
X, Y에는 초기값을 mgrid등으로 설정하지만, 이때 왠지 Y를 먼저 쓰지 않으면 절대로 에러가 나온다(ValueError: The rows of 'x' must be equal). 바꾸면 좋을 뿐이므로 특히 조사는 하지 않지만, 확실히 아는 분이라면 코멘트로 가르쳐 주세요.

U, V가 달라, 여기에는 그대로 미분 방정식(을 나타내는 변수)을 써 버린다.
연속적인 화살표가 쓰여지기 때문에 벡터의 크기가 화살표의 크기와 대응하지 않지만, 옵션을 사용해 색에 반영시킬 수 있다.

예)
plt.streamplot(X,Y,U,V,color = np.sqrt(U**2+V**2)), cmap='jet'

구현 예



u, v 2 차원의 미분 방정식을 udot, vdot로 정의, quiver 용의 초기 값을 u, v, streamplot 용의 초기 값을 x, y로 주어 둔다. 그래서).
import numpy as np
import matplotlib.pyplot as plt

#考えている微分方程式(cf;ストロガッツ非線形ダイナミクスとカオスp.172)
def udot(u,v):
  return u*(3-u-2*v)
def vdot(u,v):
  return v*(2-u-v)

#streamplot(なんと二行で済む!ヒートマップ的に大きいところは赤、小さいところは青で表示していくれるカラーマップを使用。)
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')

#つぎに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

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

결과 비교



룽게 쿠터에서는 원리적으로 각도 폭을 작게 할수록 정확한 값에 접근하기 때문에, dt=0.1의 경우와 dt=0.01의 경우에서 해궤도가 어떻게 변화하는지를 조사해 보았다.

dt=0.1인 경우


dt=0.01인 경우


dt로 지정하는 각도폭을 작게 하면 streamplot이 내린 해궤도와 평행에 접근하고 있는 것을 알 수 있다. 오른쪽 아래 근처라든지 알기 쉽다. streamplot은 상당히 정확한 계산을 뒤에서 하고 있는 것 같다. 어떤 계산을 하고 있는지는 모두 제대로 읽고 싶다.

추가



이 사이트에 소스 코드가 있어서 주로 적응 각폭 제어를 사용한 2차 Runge-Kutta법을 이용하고 있는 것을 알 수 있었다.
htps // tp t b. rg/3.1.3/_모즈ぇs/마tpぉtぃb/st레 mpぉt. HTML

좋은 웹페이지 즐겨찾기