VOLTAR

In [ ]:
#serve para plotar o gráfico no próprio Command Shell. Você pode ignorar essa linha.
%matplotlib inline
In [ ]:
#O projeto Prediction and Research Moored Array in the Tropical Atlantic (PIRATA) conta com 21 boias fixas na região
#tropical do Atlântico. Este é um programa de cooperação entre Brasil, Estados Unidos e França.

#As variáveis medidas são: vento de superfície, temperatura da superfície, condutividade de superfície (salinidade),
#temperatura do ar, umidade relativa do ar, radiação de ondas curtas, precipitação,
#temperatura de sub-superfície (10 profundidades até 500 m), 
#condutividade de sub-superfície (3 profundidades até 500 m)
#e pressão a 300 e 500 m.

#Baixando o dado:
# Entre no site http://www.goosbrasil.org/pirata/ e clique em "Obter Dados"
# Selecione uma boia (Selecionei a 14S32W) e clique em Download dos dados
#Selecione as propriedades que lhe interessam para o período que queres.
#No nosso caso, como faremos de forma geral, selecionei tudo para o período de 1 ano:
In [2]:
###############################################################################
#                     CABEÇALHO DO PROGRAMA
#    Este programa lê dados de uma boia pirata escritos em .csv
#               Feito por Iury, São Paulo-2016
###############################################################################

#Você deve importar os módulos necessários. Neste caso importaremos o módulo pandas e o módulo numpy:
import pandas as pd
import numpy as np
# Precisamos importar algum módulo gráfico para plotar 
import matplotlib.pyplot as plt

#Agora vamos definir, como uma string (cadeia de caracteres), o caminho até a pasta /dados:
path = '/home/iury/Downloads/'

#Para ler os dados, utilizaremos uma função chamada read_csv do módulo pandas.
# Como se trata de uma série temporal definiremos que a segunda coluna é a coluna 
# de strings que define nossa data e ativamos o parse_dates que fará a conversão para datetime:

DAT = pd.read_csv(path+'dados_pirata.csv',index_col=[1],parse_dates=True)

#Os dados estão com flags, que são valores estranhos que colocamos quando o dado é inválido. 
# Como podemos observar se rodarmos:

DAT.head() # mostra as primeiras linhas dos valores
Out[2]:
Unnamed: 0 s_1 s_10 s_120 s_20 s_40 s_60 s_80 t_1 t_10 ... t_180 t_20 t_300 t_40 t_5 t_500 t_60 t_80 wd ws
datahora
2014-01-09 12:00:00 0 36.911 -99999 -99999 -99999 -99999 -99999 -99999 27.48 -99999 ... -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999
2014-01-10 12:00:00 1 36.916 -99999 -99999 -99999 -99999 -99999 -99999 27.51 -99999 ... -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999
2014-01-11 12:00:00 2 36.905 -99999 -99999 -99999 -99999 -99999 -99999 27.48 -99999 ... -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999
2014-01-12 12:00:00 3 36.868 -99999 -99999 -99999 -99999 -99999 -99999 27.46 -99999 ... -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999
2014-01-13 12:00:00 4 36.850 -99999 -99999 -99999 -99999 -99999 -99999 27.48 -99999 ... -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999 -99999

5 rows × 24 columns

In [3]:
#A flag nestes dados é o valor -99999.000. Assim, substituiremos este por NaNs que significa Not a Number:

DAT.replace(-99999.000,np.nan,inplace=True) # inplace substitui o velho DAT pelo novo sem flags

# Verificando a mudança
DAT.head()
Out[3]:
Unnamed: 0 s_1 s_10 s_120 s_20 s_40 s_60 s_80 t_1 t_10 ... t_180 t_20 t_300 t_40 t_5 t_500 t_60 t_80 wd ws
datahora
2014-01-09 12:00:00 0 36.911 NaN NaN NaN NaN NaN NaN 27.48 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-10 12:00:00 1 36.916 NaN NaN NaN NaN NaN NaN 27.51 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-11 12:00:00 2 36.905 NaN NaN NaN NaN NaN NaN 27.48 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-12 12:00:00 3 36.868 NaN NaN NaN NaN NaN NaN 27.46 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-13 12:00:00 4 36.850 NaN NaN NaN NaN NaN NaN 27.48 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

5 rows × 24 columns

In [4]:
#Agora vamos Selecionar apenas as colunas que apresentarem algum dado válido. 
# Para isso faremos a seguinte operação: 
# Vamos atribuir a DAT o próprio em todas as linhas e em apenas as colunas válidas; 
# As colunas válidas serão aquelas em que não apresentarem todos os seus valores NaNs.

#A função isnan do patone numpy retorna uma variável booleana que se trata de um vetor de sim e não, no caso, 
# True e False. A função all responde se todos os valores em uma variável booleana assinalam True, 
# isto pode ser feito para cada coluna (eixo 0) para cada linha (eixo 1) ou para toda a matriz (eixo não definido). 
# O ~ aplica a negação, ou seja, o contrário do que a variável booleana diz. 
# Como a operação que fizemos foi de se todos de cada coluna são nans, para obtermos se algum é válido, 
# aplicamos a negação, ou oposto, disso.

DAT = DAT.iloc[:,~np.all(np.isnan(DAT),axis=0)]

# verificando a mudança
DAT.head()
Out[4]:
Unnamed: 0 s_1 s_120 s_20 s_40 t_1 t_100 t_120 t_140 t_180 t_20 t_300 t_40 t_500 t_60 t_80 wd ws
datahora
2014-01-09 12:00:00 0 36.911 NaN NaN NaN 27.48 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-10 12:00:00 1 36.916 NaN NaN NaN 27.51 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-11 12:00:00 2 36.905 NaN NaN NaN 27.48 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-12 12:00:00 3 36.868 NaN NaN NaN 27.46 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-13 12:00:00 4 36.850 NaN NaN NaN 27.48 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
In [23]:
#Reorganizando o dado

#Com a direção e intensidade do vento, podemos converter para velocidade zonal (leste-oeste) e meridional (norte-sul).
# Neste tipo de dado, o ângulo fornecido é formado a partir do eixo y (que aponta pro norte). 
# Então a velocidade multiplicada pelo cosseno do ângulo retornará a componenten meridional.

wd,ws = DAT['wd'],DAT['ws']
DAT['u'] = ws*np.sin(np.deg2rad(wd)) #velocidade zonal 
DAT['v'] = ws*np.cos(np.deg2rad(wd)) #velocidade meridional

# verificaremos se foram adicionadas as propriedades
DAT.head()
Out[23]:
Unnamed: 0 s_1 s_120 s_20 s_40 t_1 t_100 t_120 t_140 t_180 t_20 t_300 t_40 t_500 t_60 t_80 wd ws u v
datahora
2014-01-09 12:00:00 0 36.911 NaN NaN NaN 27.48 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-10 12:00:00 1 36.916 NaN NaN NaN 27.51 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-11 12:00:00 2 36.905 NaN NaN NaN 27.48 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-12 12:00:00 3 36.868 NaN NaN NaN 27.46 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-13 12:00:00 4 36.850 NaN NaN NaN 27.48 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
In [24]:
# Vamos observar esses dados de vento
DAT['u'].plot() #plota os índices de DAT (tempo) por velocidade zonal
Out[24]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f1f38752f90>
In [25]:
# Você pode plotar qualquer uma das propriedades de DAT.
# Para saber quais são as opções faça:
DAT.keys()
Out[25]:
Index([u'Unnamed: 0', u's_1', u's_120', u's_20', u's_40', u't_1', u't_100',
       u't_120', u't_140', u't_180', u't_20', u't_300', u't_40', u't_500',
       u't_60', u't_80', u'wd', u'ws', u'u', u'v'],
      dtype='object')
In [26]:
# A propriedade "Unnamed: 0" é uma propriedade genérica que foi criada para o índice das colunas, ela pode ser deletada
del(DAT['Unnamed: 0'])
In [27]:
# Veremos então quais propriedades temos
DAT.keys()
Out[27]:
Index([u's_1', u's_120', u's_20', u's_40', u't_1', u't_100', u't_120',
       u't_140', u't_180', u't_20', u't_300', u't_40', u't_500', u't_60',
       u't_80', u'wd', u'ws', u'u', u'v'],
      dtype='object')
In [37]:
# Este tutorial não tem uma finalidade bem definida, mas apenas na leitura do dado. 
# Assim não faço idéia de onde terminá-lo. Para finalizar, vou concluir com a junção
# dos vários níveis de temperatura e salinidade e plotar uma
# série temporal do fundeio em vários níveis com linhas de contorno

# lista de strings com os nomes que começam com s
l_s = [key.startswith('s') for key in DAT.keys()]
# lista de strings com os nomes que começam com t
l_t = [key.startswith('t') for key in DAT.keys()]

# Estas duas linhas de código rodam um loop ao qual a variável key será, em cada laço um dos nomes das colunas
# da tabelona DAT. A função startswith é uma função embutida no objeto string, que é o texto apresentado entre aspas
# ou apóstrofes que será cada key.
In [36]:
# Vamos ver se funcionou
# keys que começam com s:
DAT.keys()[l_s]
Out[36]:
Index([u's_1', u's_120', u's_20', u's_40'], dtype='object')
In [38]:
# keys que começam com t:
DAT.keys()[l_t]
Out[38]:
Index([u't_1', u't_100', u't_120', u't_140', u't_180', u't_20', u't_300',
       u't_40', u't_500', u't_60', u't_80'],
      dtype='object')
In [40]:
# Como a profundidade está embutida em cada string, ou texto, que representa
# o nome de cada coluna. Temos que ler cada string, separá-la através do 
# caractere underline _ , selecionar o último elemento dessa separação e 
# convertê-lo de texto para número

# A função split() separa a string 't_100' em duas ['t','100'], por exemplo.
# Se o seu argumento for '_' (underline).
# Além de separar, eu preciso selecionar apenas o último elemento, índice -1,
# que é o '100' nesse caso, e converter ele para um número inteiro com a função int()

# Em python a identação pode ser a partir do primeiro valor, que é o 0,
# ou a partir do último, que é o -1. Assim, se eu quero o segundo elemento
# de uma lista, eu uso o índice 1, mas se eu quero o penúltimo, uso o índice -2

# Para isso vamos fazer outro loop em linha
prof_sal = [int(key.split('_')[-1]) for key in DAT.keys()[l_s]]
prof_tmp = [int(key.split('_')[-1]) for key in DAT.keys()[l_t]]

# Vamos ver se funcionou:
print prof_tmp
[1, 100, 120, 140, 180, 20, 300, 40, 500, 60, 80]
In [85]:
# Então vamos definir uma nova variável para temperatura e outra para salinidade
TEMP = DAT[DAT.keys()[l_t]]
SALT = DAT[DAT.keys()[l_s]]

#vamos ver como ficou a variável TEMP, por exemplo
TEMP.head()
Out[85]:
t_1 t_100 t_120 t_140 t_180 t_20 t_300 t_40 t_500 t_60 t_80
datahora
2014-01-09 12:00:00 27.48 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-10 12:00:00 27.51 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-11 12:00:00 27.48 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-12 12:00:00 27.46 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-13 12:00:00 27.48 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
In [74]:
# Agora vamos mudar os nomes das colunas pelos valores de profundidade
TEMP.columns = prof_tmp #usei valores negativos para profundidade, ou seja, z

# trocando as colunas pelos índices
TEMP = TEMP.transpose()

# Colocando as profundidades em ordem
TEMP = TEMP.sort_index()

# Verificando como está a temperatura
TEMP.head()
Out[74]:
datahora 2014-01-09 12:00:00 2014-01-10 12:00:00 2014-01-11 12:00:00 2014-01-12 12:00:00 2014-01-13 12:00:00 2014-01-14 12:00:00 2014-01-15 12:00:00 2014-01-16 12:00:00 2014-01-17 12:00:00 2014-01-18 12:00:00 ... 2016-01-30 12:00:00 2016-01-31 12:00:00 2016-02-01 12:00:00 2016-02-02 12:00:00 2016-02-03 12:00:00 2016-02-04 12:00:00 2016-02-05 12:00:00 2016-02-06 12:00:00 2016-02-07 12:00:00 2016-02-08 12:00:00
1 27.48 27.51 27.48 27.46 27.48 27.51 27.52 27.51 27.49 27.58 ... 27.73 27.72 27.81 27.80 27.93 27.91 27.83 27.83 27.93 27.90
100 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 24.59 24.73 25.04 24.99 24.86 24.93 NaN 25.08 24.93 24.99
120 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 24.20 24.32 24.32 24.28 24.31 24.33 24.23 24.32 24.33 24.30
140 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 23.71 23.85 23.79 23.81 23.78 23.81 23.76 23.67 23.67 23.77
180 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 21.05 21.65 20.95 21.72 21.56 21.84 21.58 21.40 20.76 20.73

5 rows × 761 columns

In [80]:
# para plotar, vamos utilizar o pacote que foi importado no início

plt.figure(figsize=(10,6))                        #criando figura com tamanho 10 por 6
plt.contourf(TEMP.columns,TEMP.index,TEMP.values) #plota contornos preenchidos
plt.gca().invert_yaxis()                          #como profundidade está positiva, inverte-se o eixo
plt.colorbar()                                    #cria barra de cores
Out[80]:
<matplotlib.colorbar.Colorbar at 0x7f1f3822d6d0>
In [86]:
# Agora faremos o mesmo com a salinidade

# Vamos mudar os nomes das colunas pelos valores de profundidade
SALT.columns = prof_sal #usei valores negativos para profundidade, ou seja, z

# trocando as colunas pelos índices
SALT = SALT.transpose()

# Colocando as profundidades em ordem
SALT = SALT.sort_index()

# Verificando como está a temperatura
SALT.head()
Out[86]:
datahora 2014-01-09 12:00:00 2014-01-10 12:00:00 2014-01-11 12:00:00 2014-01-12 12:00:00 2014-01-13 12:00:00 2014-01-14 12:00:00 2014-01-15 12:00:00 2014-01-16 12:00:00 2014-01-17 12:00:00 2014-01-18 12:00:00 ... 2016-01-30 12:00:00 2016-01-31 12:00:00 2016-02-01 12:00:00 2016-02-02 12:00:00 2016-02-03 12:00:00 2016-02-04 12:00:00 2016-02-05 12:00:00 2016-02-06 12:00:00 2016-02-07 12:00:00 2016-02-08 12:00:00
1 36.911 36.916 36.905 36.868 36.85 36.836 36.832 36.826 36.795 36.755 ... 37.149 37.107 37.050 37.054 37.071 37.173 37.244 37.246 37.259 37.255
20 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 37.144 37.101 37.056 37.059 37.139 37.222 37.239 37.238 37.251 37.246
40 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 37.146 37.111 37.181 37.272 37.251 37.234 37.224 37.224 37.237 37.231
120 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 37.205 37.235 37.212 37.211 37.218 37.220 37.196 37.198 37.210 37.177

4 rows × 761 columns

In [87]:
# para plotar, vamos utilizar o pacote que foi importado no início

plt.figure(figsize=(10,6))                        #criando figura com tamanho 10 por 6
plt.contourf(SALT.columns,SALT.index,SALT.values) #plota contornos preenchidos
plt.gca().invert_yaxis()                          #como profundidade está positiva, inverte-se o eixo
plt.colorbar()                                    #cria barra de cores
Out[87]:
<matplotlib.colorbar.Colorbar at 0x7f1f38388f50>