Neste notebook são criados dados fictícios e analisados os contornos, seguindo o seguinte algoritmo:
Os ângulos e o algoritmo foi adaptado de (Chaigneau et. al, 2008):
In [15]:
import itertools
import numpy as np
import numpy.linalg as la
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.mlab import bivariate_normal
import matplotlib._cntr as cntr
import seaborn as sns
In [16]:
def windingAngle(v1, v2):
cosang = np.dot(v1, v2)
sinang = la.norm(np.cross(v1, v2))
return np.arctan2(sinang, cosang)
def isEddy(seg,threshold=2*np.pi,onlyclosed=True):
x,y = seg.T
dx,dy = np.diff(x),np.diff(y)
try:
angles = []
for first,second in zip(range(0,len(dx)-1),range(1,len(dx))):
angles.append(windingAngle([dx[second],dy[second]],[dx[first],dy[first]]))
if sum(angles)>=threshold:
out = True
else:
out = False
if onlyclosed:
if not(all(seg[-1]==seg[0])):
out = False
except:
out = False
return out
In [17]:
def extLines(segs):
ind = range(0,len(segs))
# Para cada contorno, verificar quais este contém
contem = []
for i in ind:
c = []
for ic in ind:
try:
c.append(Path(segs[i]).contains_path(Path(segs[ic])))
except:
c.append(False)
contem.append(c)
contem = np.vstack(contem)
# Para cada contorno, verificar quais este está contido
estacontido = contem.T
# Encontrando aqueles que não contem nada
minimos = (contem.sum(1)==0)
# Encontrando aqueles que não contem mais do que um dos que não contem nada
multiplosminimos = contem[:,minimos].sum(1)>1
# Considerando apenas os contornos que não contem mais de um dos que não contem nada
estacontido = estacontido[~multiplosminimos,:][:,~multiplosminimos]
# Inicia array como uma lista de Falses para todos os contornos
isext = np.array([False]*len(segs))
# Considerando apenas os que não estão contidos em nenhum outro contorno
isext[~multiplosminimos] = (estacontido.sum(1)==0)
return isext
In [480]:
# Definindo alguns parâmetros
amp = 4
# Criando grid
X,Y = np.meshgrid(*([range(-80,90)]*2))
# Adicionando algumas oscilações como o somatório de várias gaussianas
n = 70
i,j = X.ravel()[np.random.randint(0,X.size,n)],Y.ravel()[np.random.randint(0,Y.size,n)]
Z = np.zeros_like(X)
for ii,jj in zip(i,j):
Zp = bivariate_normal(X,Y,np.random.randint(1,6)*3,
np.random.randint(1,6)*3,
ii,jj)
Zp = Zp/np.abs(Zp).max()
Z = Z+Zp*0.5*np.random.randint(-2,3)
sns.set()
vmax = np.abs(Z).max()
levels = np.linspace(-vmax,vmax,50)
# Apresentando o dado
fig,ax = plt.subplots()
ct = ax.contourf(X,Y,Z,levels,vmin=-vmax,vmax=vmax,cmap='seismic')
ax.contour(X,Y,Z,10,colors='k')
fig.colorbar(ct)
Out[480]:
In [34]:
import scipy.io as sio
mat = sio.loadmat('/home/iury/Downloads/pickle_paraguay.mat')
X,Y,Z = mat['LON'],mat['LAT'],mat['PSI']
vmax = np.abs(Z).max()
levels = np.linspace(-vmax,vmax,50)
sns.set()
vmax = np.abs(Z).max()
levels = np.linspace(-vmax,vmax,70)
# Apresentando o dado
fig,ax = plt.subplots()
ct = ax.contourf(X,Y,Z,levels,vmin=-vmax,vmax=vmax,cmap='seismic')
ax.contour(X,Y,Z,10,colors='k')
fig.colorbar(ct)
Out[34]:
In [35]:
c = cntr.Cntr(X, Y, Z)
segs = []
for lvl in levels:
trace = c.trace(lvl,lvl,0)
[segs.append(seg) for seg in trace[:len(trace)//2]]
plt.figure()
for seg in segs:
plt.plot(*seg.T,linewidth=0.5,color='0.4')
In [36]:
whichsegs = [isEddy(seg,1.5*np.pi) for seg in segs]
plt.figure()
for which,seg in zip(whichsegs,segs):
if which:
kw = dict(linewidth=0.5,color='r')
else:
kw = dict(linewidth=0.5,color='0.4')
plt.plot(*seg.T,**kw)
In [37]:
eddysegs = np.array(segs)[whichsegs]
isext = extLines(eddysegs)
fig,ax = plt.subplots()
ct = ax.contourf(X,Y,Z,levels,vmin=-vmax,vmax=vmax,cmap='seismic')
fig.colorbar(ct)
for ext,seg in zip(isext,eddysegs):
if ext:
kw = dict(linewidth=1.5,color='k')
else:
kw = dict(linewidth=0.5,color='0.8',alpha=0.5)
ax.plot(*seg.T,**kw)
In [ ]:
In [ ]: