Como aquecimento e demonstração das possibilidades do ambiente, vamos analisar dados provenientes de um disposito IRGB (infra-red gas analyser). Neste exemplo, 40 plantas foram analisadas em 12 dias diferentes. Em cada dia, para cada planta, foram obtidas 4 medições para as seguintes variáveis:
Uma maneira natural de representar esses dados é utilizar uma tabela de valores numéricos. Computacionalmente, vamos utilizar uma estrutura de dados chamada de matriz ou array.
Python é uma linguagem de programação. Sua funcionalidade básica é expandida com o uso de módulos. Há um conjunto de módulos, chamado de SciPy Stack, que adiciona ao ambiente uma série de funcionalidades comumente utilizadas em computação científica. Um desses módulos é chamado de NumPy e é utilizado para criação e manipulação de arrays.
Resumindo, utilizaremos NumPy para manipular tabelas numéricas com nossos dados de IRGA. Para importar o módulo, basta utilizar o comando:
In [1]:
import numpy
Nossos dados estão em uma tabela CSV (comma-separated values), uma forma simples de representar tabelas em arquivos. Abaixo estão as 10 primeiras linhas do arquivo:
In [3]:
!head data/pheno-irga-day11.csv
Queremos esses dados representados devidamente como um array NumPy que possamos manipular. Podemos utilizar o módulo NumPy para realizar a leitura dos dados:
In [4]:
numpy.loadtxt(fname='data/pheno-irga-day11.csv', delimiter=';', skiprows=1)
Out[4]:
Acima, nós utilizamos a função loadtxt
no módulo NumPy para fazer a leitura do CSV e criar um array com seu conteúdo. A função recebeu 3 parâmetros: o caminho para o arquivo, o caracter delimitador utilizado para separar as colunas no arquivo CSV e o número de colunas de cabeçalho que deveriam ser ignoradas durante a leitura.
O comando acima não armazenou o array em uma variável para que possamos referenciá-lo e manipulá-lo posteriormente. Suponha que desejamos referenciar esses dados pelo nome irga_day1
. Isto pode ser feito facilmente com:
In [5]:
irga_day1 = numpy.loadtxt(fname='data/pheno-irga-day11.csv', delimiter=';', skiprows=1)
In [6]:
print(irga_day1)
In [7]:
%whos
In [8]:
irga_day1.shape
Out[8]:
Como esperado, temos um array $40 \times 4$, correspondendo a 40 plantas e 4 medidas por planta.
In [9]:
irga_day1.dtype
Out[9]:
As medidas estão sendo armazenadas como números reais, representados no computador pelo tipo ponto flutuante com 64 bits.
In [10]:
irga_day1.mean(axis=0)
Out[10]:
Uma das diversas operações implementadas pelo objeto array é o cômputo da média. Acima, podemos ver os valores médios observados para A, gs, E e $C_i$ respectivamente.
In [11]:
irga_day1[4,2]
Out[11]:
Os números acima entre colchetes, [i,j]
, são índices. O primeiro indexa a linha, o segundo a coluna. Assim, irga_day1[4,2]
referencia a linha 4, coluna 2.
O que pode causar estranheza é o fato de desejarmos incialmente a 3ª coluna na 5ª linha. Linguagens de programação como C++, Java e Python iniciam a indexação por 0 (zero). A primeira linha é a linha 0, a segunda a linha 1 e assim por diante. Logo, a 5ª linha corresponde à linha 4:
O mesmo vale para as colunas, de forma que a coluna 2 corresponde à 3ª linha. Assim, nosso array $40 \times 4$ é referenciados por linhas de 0 a 39 e colunas de 0 a 3.
Esta é sem dúvida uma das maiores dificuldades iniciais enfrentada por pesquisadores sem experiência prévia com computação, ou cuja experiência se baseia nas linguagens Fortran ou Matlab, que indexam a partir do índice 1, como é mais intuitivo à maioria das pessoas.
In [12]:
irga_day1[:,2]
Out[12]:
Acima, temos todos os valores de $E$ para as 40 plantas. Podemos facilmente computar a média:
In [13]:
irga_day1[:,2].mean()
Out[13]:
In [14]:
E = irga_day1[:,2]
maxval, minval, stdval, meanval = numpy.max(E), numpy.min(E), numpy.std(E), numpy.mean(E)
print('Taxa de transpiracao:')
print('Maxima:', maxval)
print('Minima:', minval)
print('Media:', meanval)
print('Desvio padrao:', stdval)
In [15]:
from matplotlib import pyplot
%matplotlib inline
import seaborn
In [16]:
pyplot.figure(figsize=(5,3))
pyplot.scatter(irga_day1[:,0], irga_day1[:,2])
pyplot.xlabel(u'$A$ (taxa de assimilação de CO$_2$)')
pyplot.ylabel(u'$E$ (taxa de transpiração)')
Out[16]:
In [17]:
pyplot.figure(figsize=(10,3))
pyplot.subplot(1,2,1)
pyplot.scatter(irga_day1[:,0], irga_day1[:,2])
pyplot.xlabel(u'$A$ (taxa de assimilação de CO$_2$)')
pyplot.ylabel(u'$E$ (taxa de transpiração)')
pyplot.subplot(1,2,2)
pyplot.scatter(irga_day1[:,0], irga_day1[:,1], marker='s', color='y')
pyplot.xlabel(u'$A$ (taxa de assimilação de CO$_2$)')
pyplot.ylabel(u'$gs$ (condutância estomática)')
Out[17]:
In [18]:
numpy.argwhere(irga_day1[:,0] < 10)
Out[18]:
Plantas submetidas a estresse hídrico.
Abaixo, temos uma lista de dias em que as medições foram realizadas:
In [19]:
days = [1, 3, 4, 5, 6, 7, 9, 10, 11, 16, 17]
A partir dela, geramos uma seguda lista, com o nome dos arquivos que armazenam as leituras de cada dia:
In [20]:
csv_files = ['data/pheno-irga-day%.2d.csv' % d for d in days]
csv_files
Out[20]:
Finalmente, uma terceira lista é obtida, contendo os arrays lidos de cada arquivo. Essa lista é então empilhada, formando um array $40 \times 4 \times 11$ (quarenta plantas, 4 medidas, 11 dias):
In [21]:
irga_data_day = [numpy.loadtxt(filename, delimiter=';', skiprows=1) for filename in csv_files]
irga_data = numpy.dstack(irga_data_day)
irga_data.shape
Out[21]:
In [22]:
# Planta 0 (1ª planta), E nos 11 dias
irga_data[0,3,:]
Out[22]:
In [23]:
pyplot.figure(figsize=(10,5))
for p in range(20):
pyplot.plot(irga_data[p,3,:], label='Planta %d' % p)
ticks = pyplot.xticks(range(11), ['Dia %d' % d for d in days])
pyplot.legend(bbox_to_anchor=(1, 1), loc=2, borderaxespad=0.)
pyplot.ylabel(u'$E$ (taxa de transpiração)')
Out[23]:
In [24]:
pyplot.figure(figsize=(10,5))
for p in range(20, 40):
pyplot.plot(irga_data[p,3,:], label='Planta %d' % p)
ticks = pyplot.xticks(range(11), ['Dia %d' % d for d in days])
pyplot.legend(bbox_to_anchor=(1, 1), loc=2, borderaxespad=0.)
pyplot.ylabel(u'$E$ (taxa de transpiração)')
Out[24]:
Vamos carregar as leituras de uma câmera térmica, armazenados em um arquivo texto:
In [25]:
!head -2 data/GR009.txt
In [26]:
T = numpy.loadtxt('data/GR009.txt')
T.shape
Out[26]:
In [27]:
pyplot.figure(figsize=(10,5))
pyplot.imshow(T, cmap=pyplot.cm.viridis)
pyplot.colorbar()
Out[27]:
A câmera térmica opera captando infra-vermelho do espectro. No dispositivo, há um segundo sensor, que capta o espectro visível. Vamos utilizar o módulo skimage.io
para ler a imagem, que está armazenada em um arquivo JPEG:
In [28]:
from skimage import io
I = io.imread('data/DC_0010.jpg')
I.shape
Out[28]:
A imagem foi lifa com uma array com 710 linhas, 947 colunas e 3 canais, correspondendo a vemelho, verde e azul.
In [30]:
fig = pyplot.figure(figsize=(14,10))
pyplot.subplot(2,2,1)
pyplot.imshow(I)
pyplot.subplot(2,2,2)
pyplot.imshow(I[:,:,0], cmap=pyplot.cm.Reds) # Canal vermelho
pyplot.colorbar()
pyplot.title('Vermelho')
pyplot.subplot(2,2,3)
pyplot.imshow(I[:,:,1], cmap=pyplot.cm.Greens) # Canal verde
pyplot.colorbar()
pyplot.title('Verde')
pyplot.subplot(2,2,4)
pyplot.imshow(I[:,:,2], cmap=pyplot.cm.Blues) # Canal azul
pyplot.colorbar()
pyplot.title('Azul')
Out[30]:
In [31]:
pyplot.figure(figsize=(10,5))
pyplot.subplot(1,2,1)
pyplot.imshow(I)
pyplot.subplot(1,2,2)
pyplot.imshow(T, cmap=pyplot.cm.viridis)
pyplot.colorbar()
Out[31]: