Векторное поле Python оды из трех переменных



Я пытаюсь построить векторное поле модели оды с тремя переменными. Я хотел бы усреднить векторы вдоль третьей оси и представить векторное поле вместе с информацией о стандартном отклонении их значений.
Система оды такова:



a  = 1.
b1 = 0.1
b2 = 0.11
c1 = 1.5
c2 = 1.6
d = 0.75
def dudt(a,b1,b2,u,v1,v2):
return a*u - b1*u*v1 - b2*u*v2
def dv1dt(d,c1,b1,u,v1):
return -c1*v1 + d*b1*u*v1
def dv2dt(d,c2,b2,u,v2):
return -c2*v2 + d*b2*u*v2


Функция, которую я в данный момент использую:



import numpy as np
import matplotlib.pyplot as plt
def plotVF(mS=None, density= 20,color='k'):
mB1 = np.linspace(0,1.1,int(density))
mB2 = np.linspace(0,1.1,int(density))
if mS==None:
mS = np.linspace(0,1.1,int(density))
B1,B2,S = np.meshgrid(mB1,mB2,mS)
average=True
else:
B1,B2 = np.meshgrid(mB1,mB2)
S = mS
average=False
DB1 = dv1dt(d,c1,b1,S,B1)
DB2 = dv2dt(d,c2,b2,S,B2)
DS = dudt(a,b1,b2,S,B1,B2)
if average:
print "Averaging"
DB1std = np.std(DB1,axis=2)
DB2std = np.std(DB2,axis=2)
DB1 = np.mean(DB1,axis=2)
DB2 = np.mean(DB2,axis=2)
DS = np.mean(DS,axis=2)
vecstd = np.hypot(DB1std,DB2std)
plt.imshow(vecstd)
plt.colorbar()
B1,B2 = np.meshgrid(mB1,mB2)
M = (np.hypot(DB1, DB2, DS))
M[ M == 0] = 1.
DB1=DB1/M
DB2=DB2/M
DS=DS/M
print B1.shape,B2.shape,DB1.shape,DB2.shape
plt.quiver(B1, B2, DB1, DB2, pivot='mid', color=color)
plt.xlim(0,1.1), plt.ylim(0,1.1)
plt.grid('on')
plt.show()


Это дает мне, что стандартное отклонение вдоль третьей оси равно нулю, что не имеет смысла.
векторное поле
Кто-то догадывается, что я делаю. неправильно?
669   1  

1 ответ:

Ваш код почти идеально подходит. Есть только одна проблема: вы строите цветовую карту с ванильным вызовом plt.imshow.

Как следует из его названия, imshow используется для построения изображений. Таким образом, он по умолчанию не ожидает ввода координат, а только один массив, содержащий пиксельные данные. Это означает, что простой вызов imshow будет иметь ограничения по осям, соответствующие количеству пикселей в вашем изображении - в вашем случае размеры ваших 2d-массивов данных. Если вы взглянете на изображение, непосредственно созданное imshow, вы увидите, что пределы доходят до x,y=20. Позже вы устанавливаете новые ограничения в соответствии с вашей фактической базовой сеткой, усекая график до первых 2 точек данных.

Решение состоит в том, чтобы явно указать plt.imshow(), где вы хотите, чтобы ваш участок находился в координатном пространстве:

plt.imshow(vecstd, extent=[B1.min(),B1.max(),B2.min(),B2.max()], origin='lower')

Первый аргумент ключевого слова extent задает пределы x и y, в которые должны быть помещены данные. Обратите внимание на важный второй аргумент ключевого слова origin. По умолчанию imshow рисует вещи "вверх ногами", чтобы не строить реальные изображения вверх ногами. Когда вы используете imshow для построения материала, определенного с Декартовыми координатами, вы должны сказать ему, что начало системы координат не должно быть верхним левым углом фигуры (как для изображений), а скорее нижним левым углом (как для регулярных графиков).

Comments

    Ничего не найдено.