Enviar um café pro programador

Mostrando postagens com marcador Ciência de dados. Mostrar todas as postagens
Mostrando postagens com marcador Ciência de dados. Mostrar todas as postagens

Gráfico de Densidade em Python - Mapas de Calor (Heat Maps Graphics)

Neste tutorial de nosso curso Python Científico , vamos aprender o que é um gráfico de densidade (density plot), para que serve, quando usar, como funciona e como criar em Python.


Como plotar heat maps em Python


O que é um gráfico de densidade

No tutorial passado, sobre gráficos de dispersão (scatter plots), mostramo seguinte gráfico:

Programação científica em Python

Note que diversos pontos estão um por cima do outro. Muitas vezes é interessante saber quantos pontos desses estão sobrepostos, afinal devem ter regiões onde há maior sobreposição que outras.

Então essas regiões com mais pontos, são mais frequentes e certamente pode ser útil saber disso. Mas como ver isso? Numericamente é possível, mas obviamente é bem trabalhoso, pois estamos lidando com milhares e milhares de dados.

Uma possibilidade é através dos gráficos de densidade. Imagine que os pontos que ocorrem pouco tenham essa cor azulada, porém a medida que vamos sobrepondo um ponto acima do outro, este ponto vai mudando de cor, ficando mais vermelho, por exemplo.

Ou seja, um vermelho bem fraco sinalizaria uma poucas sobreposições, porém um vermelho bem forte nos diria que ali ocorreu uma grande sobreposição de pontos.

Então, através dessa densidade de cores e brilhos, podemos saber que região é ou menos densa. Assim, podemos analisar a distribuição de dados através de um gráfico.


Quando usar um gráfico de densidade

Nós já estudamos um tipo de visualização que é, de certo modo, semelhante aos density plots, que são os gráficos de histograma. Porém, o gráfico de densidade é algo contínuo, diferente do histograma que é algo discretizado (com valores fixos, nas barras).

Talvez você já tenha ouvido falar na expressão 'mapa de calor' (heat maps), onde as coisas menos densas (como temperatura) estão em azul e vão migrando até o vermelho mais 'quente' (regiões mais densas de dados). São gráficos de densidade.

Como plotar heat maps em Python

Quando queremos plotar dados mais contínuos (ao invés dos pontos do scatter, linhas do plot() ou barras de histograma), devemos optar pelos gráficos de densidade para melhor representar e entender as informações que temos que analisar.


Como plotar um gráfico de densidade em Python

Vamos usar os dados do arquivo de texto abaixo (aproveite e nos siga no GitHub):

https://github.com/jarlissonmoreira/PythonProgressivo/blob/main/Grafico-Densidade-Density-Plot-in-Python/densidade.txt

Para carregar esse txt em nosso código Python, usamos a função loadtxt da NumPy. E para interpretar esses dados,vamos usar a função imshow() do Pyplot da Matplotlib. Salve o arquivo de texto acima como densidade.txt e deixe na mesma pasta do script:

import matplotlib.pyplot as plt import numpy as np dados = np.loadtxt("densidade.txt",float) plt.imshow(dados) plt.show()

O resultado será essa bela imagem:

Density plot graphic in Python
A função loadtxt() colocous as informações do arquivo de texto em uma matriz 500 x 500, e passou para a imshow() plotar o gráfico de densidade.

Note que os eixos são diferentes do cartesiano que estamos habituados a ver desde a época da escola. Aqui, o eixo y cresce de cima para baixo. Ou seja, a origem está acima e na esquerda. Esse é um padrão na computação, de um modo geral.

Podemos mudar isso adicionando o argumento origin="lower" na função imshow():

import matplotlib.pyplot as plt import numpy as np dados = np.loadtxt("densidade.txt",float) plt.imshow(dados, origin="lower") plt.show()

E o resultado:

Eixos cartesianos em programação Python

Se quiser usar um mapa de densidade do tipo mapa de calor, chame a função jet() do Matplotlib.Pyplot ou passe o argumento cmap='jet' na função imshow():

import matplotlib.pyplot as plt import numpy as np dados = np.loadtxt("densidade.txt",float) plt.imshow(dados, origin="lower") plt.jet() plt.show()


Como plotar heat maps em Python


É muito comum, principalmente em trabalhos acadêmicos, como em revistas, artigos, teses etc, você usar apenas gráficos em preto e branco. Nesse caso, devemos usar a escola de cor gray():

import matplotlib.pyplot as plt import numpy as np dados = np.loadtxt("densidade.txt",float) plt.imshow(dados, origin="lower") plt.gray() plt.show()

Como plotar heat maps em escala gray no Python

Veja alguns tipos de mapas de cores (colormaps) disponível no Python, através do módulo Pyplot da biblioteca Matplotlib:

Escalas de cor de colormaps do Python

Veja a documentação para saber de todas as possibilidades:

https://matplotlib.org/stable/users/explain/colors/colormaps.html

Gráficos em Python - Como ler arquivos, Definir tamanho dos eixos, Rótulos (labels), Cores, Tipos de linha e Legendas

 Neste tutorial de nosso curso de Programação Científica em Python, vamos continuar aprendendo como gerar gráficos em Python usando o módulo Pyplot da biblioteca Matplotlib, ferramentas nativas, gratuitas, flexíveis e extremamente poderosas da linguagem Python.

No tutorial anterior, aprendemos como plotar gráficos simples em Python, usando a função plot(). Agora, vamos aprender mais algumas técnicas e possibilidades, para incrementar nossas figuras.


Como gerar gráficos a partir de arquivos: loadtxt()

Nos exemplos do tutorial anterior, usamos apenas alguns poucos dados, mas o comum em Ciência de Dados é usar centenas, milhares e até milhões de informações, tanto para gerar gráficos como para encontrar padrões.

No exemplo a seguir, vamos usar a função loadtxt(), do NumPy, ideal para ler dados de arquivos txt de uma maneira bem simples. Basicamente, essa função recebe uma string com o endereço do arquivo de texto e o tipo de dado que queremos usar para gerar o array.

Baixe esse arquivo itub.txt e salve na mesma pasta do seu script em Python:
https://github.com/jarlissonmoreira/PythonProgressivo

Esse arquivo tem 250 colunas e duas colunas, representando os últimos 250 preços de fechamento da ação do Itaú (ITUB3), na bolsa de valores, que é minha ação favorita para receber dividendos.

Nosso código fica assim:

import matplotlib.pyplot as plt import numpy as np dados = np.loadtxt("itub.txt", float) x = dados[:, 0] y = dados[:, 1] plt.plot(x,y)

A função loadtxt() colocou esses dados em uma matriz 250 x 2.
Usamos nosso conhecimento de slicing de arrays para pegar a coluna 1 da matriz e usar como eixo x, e a coluna 2 como eixo y, para enfim usar a função plot() para gerar o gráfico de cotações:

Como gerar gráfico de cotações em Python

Definindo os limites dos eixos X e Y: xlim() e ylim()

Veja que, em todos nossos gráficos, o Python automaticamente definiu a faixa de valores que é exibida nos eixos X e Y, de maneira automática.

Porém, como tudo na programação, isso é ajustável. E para tal, vamos usar as funções xlim() e ylim(), do módulo Pyplot.

Vamos gerar um gráfico da função 2*cosseno, no intervalo de 0 até 2pi, e deixar o Pyplot setar automaticamente os valores dos eixos:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 2*np.pi, 1000) y = 2 * np.cos(x) plt.plot(x,y)

Como plotar gráficos em Python

Agora vamos definir o eixo x de 0 até 4pi e o eixo y de -2.5 até 2.5, veja como fica o código:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 2*np.pi, 1000) y = 2 * np.cos(x) plt.xlim(0, 4*np.pi) plt.ylim(-2.5, 2.5) plt.plot(x,y)

E o gráfico, como ficou mais 'de longe', pois os eixos agora são maiores:

xlim() e ylim() em gráficos Python

Ou seja, basta fornecer o intervalo de valores nas funções xlim() e ylim()


Rótulos (labels) dos eixos: xlabel() e ylabel()

Se você olhar bem, todos os gráficos em livros, artigos científicos e até na internet, possuem descrições sobre o que representa cada eixo.

São os rótulos, ou labels, e basta usarmos as funções xlabel() e ylabel() do Pyplot, fornecendo a string que você quer que seja exibida nos respectivos eixos.

Veja como fica nosso código do gráfico do cosseno:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 2*np.pi, 1000) y = 2 * np.cos(x) plt.xlim(0, 4*np.pi) plt.ylim(-2.5, 2.5) plt.xlabel("Ângulo x, em radianos") plt.ylabel("2*cos(x)") plt.plot(x,y) plt.show()

Nosso gráfico ficou:

Labels xlabel() e ylabel() em gráficos do Matplotlib

É sempre interessante você colocar o que é cada eixo, bem como as respectivas unidades que foi utilizado.


Plotando dois gráficos numa mesma imagem

Também é comum plotarmos duas ou mais funções em um mesmo gráfico, algo que é particularmente útil principalmente para compararmos valores, funções e padrões.

Por exemplo, no código abaixo, vamos plotar as funções seno e cosseno, com valores de x indo de 0 até 10pi:

import matplotlib.pyplot as plt import numpy as np x1 = np.linspace(0, 10*np.pi, 1000) x2 = np.linspace(0, 10*np.pi, 1000) y1 = np.cos(x1) y2 = np.sin(x2) plt.xlim(0, 10*np.pi) plt.ylim(-1.5, 1.5) plt.xlabel("Ângulo x, em radianos") plt.ylabel("cos(x) (azul) e sen(x) (em laranja)") plt.plot(x1,y1) plt.plot(x2,y2) plt.show()

Vejamos o resultado:

Como plotar várias coisas no mesmo gráfico em Python

Note que o Pyplot colocou, automaticamente, cada gráfico de uma função com uma cor diferente.

Como alterar Cores e Tipos de linhas dos gráficos

No exemplo anterior, vimos que os gráficos ficaram com as cores azul e laranja. Isso também pode ser alterado conforme seu gosto.

Se desejar que seu gráfico seja vermelho, fornece um argumento adicional na função plot(), com as string 'red' ou 'r': plot(x, y, 'r')

Se desejar que a linha seja pontilhada, ao invés de contínua, forneça a string '--':
plot(x, y, '--')

E se quiser que ela seja vermelha e pontilhada? Simples, use: 'r--'
Veja:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-2*np.pi, 2*np.pi, 1000) y = np.tan(x) plt.ylim(-2, 2) plt.xlabel("x, em rad") plt.ylabel("$tg(x)$") plt.grid() plt.plot(x,y, 'r--') plt.show()

Veja como ficou o gráfico:

Alterar cor e formato da linha no Matplotlib

Note que usamos a função grid() do Pyplot, para exibir as 'grades' (quadriculado).
As cores principais podem ser:

  • b : blue
  • g : green
  • r : red
  • c : cyan
  • m : magenta
  • y : yellow
  • k : black
  • w : white
Já os estilos de linha são:
linestyle solid dotted dashed dashdot


Você pode fornecer esses argumento da seguinte maneira: color = 'green', linestyle='dotted'
Veja como ficou o código e gráfico:

import matplotlib.pyplot as plt import numpy as np x = np.linspace(-2*np.pi, 2*np.pi, 1000) y = np.tan(x) plt.ylim(-2, 2) plt.xlabel("x, em rad") plt.ylabel("$tg(x)$") plt.grid() plt.plot(x,y, color='green', linestyle='dotted') plt.show()

Como plotar gráficos com o Pyplot

Outras possibilidades são alterar o tamanho das fontes, espessura das linhas, marcadores e estilos etc, veja:

https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html


Legendas dos gráficos: legend()

Muitas vezes é interessante fornecer informações sobre os gráficos não apenas nos eixos (labels), mas diretamente dentro do plot.

É especialmente útil quando plotamos várias funções em um imagem só. Para especificar cada gráfico do plot, colocamos o argumento label dentro de cada plot(), com a string que queremos exibir. Depois, chamamos a função legend() do pyplot:

import matplotlib.pyplot as plt import numpy as np x1 = np.linspace(0, 10, 11) x2 = np.linspace(0, 5, 11) y1 = x1 y2 = x2**2 plt.plot(x1,y1, label='Função linear y=x') plt.plot(x2,y2, label='Função quadrática y=x²') plt.legend() plt.show()

Veja o resultado:

Como inserir legendas em Python

Você pode inclusive definir onde quer que essas legendas apareçam. Por exemplo, para aparecer embaixo (lower) e no centro (center), basta colocar essas informações no argumento 'loc' da função legend():

import matplotlib.pyplot as plt import numpy as np x1 = np.linspace(0, 10, 11) x2 = np.linspace(0, 5, 11) y1 = x1 y2 = x2**2 plt.plot(x1,y1) plt.plot(x2,y2) plt.legend(['Função linear y=x', 'Função quadrática y=x²'], loc='lower center') plt.show()

Veja não usamos os argumentos label dentro das funções plot(). Ao invés disso, passamos uma lista com as strings, uma para cada plot, diretamente na função legend, e em seguida usamos o loc para dar a localização desejada da legenda.

Para ver mais variações e possibilidades, acesse:

https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.legend.html


Exercício de programação científica

Mostramos exemplos de gráficos seno, cosseno e tangente. Porém, o NumPy não tem, nativamente, as funções secante, cossecante e cotagente. Ou seja, você vai ter que implementar elas. Lembra das aulas de trigonometria?

Gere um gráfico, com intervalo de -2pi até +2pi, plotando essas três funções, com as cores vermelhas, verde e azul, respectivamente.

Reshape e Resize: Como mudar o tamanho e formato de dados em Python

 Neste tutorial, de nosso curso de Ciência de Dados com Python, vamos aprender como usar as funções de reshaping e resizing, para alterar o formato e tamanho dos arrays.

É muito comum, quando trabalhamos com dados em programação, termos a necessidade de alterar a maneira como as informações são armazenadas e exibidas, para facilitar nossa tarefa.

Por exemplo, vamos supor que você um array unidimensional com as notas de todos os alunos de uma turma, ou seja, tudo numa linha. Ora, essa é uma péssima maneira de armazenar esses dados. Seria melhor uma tabela (matriz), onde uma linha se refere a somente um aluno, e as colunas são as notas de cada matéria, concorda?

reshape() - Mudando o formato de arrays

Nas funções de reshape, não vamos alterar o número de elementos total, vamos apenas reorganizar, ou seja, mudar o formato como as dados são exibidos, ok?

np.reshape( info, formato(linhas, colunas) )

Vamos usar a função reshape, da biblioteca NumPy, para alterar o formato de um array. Para isso, vamos fornecer dois argumentos para a função: o array com as informações e o formato na qual queremos exibir, onde o formato deve ser da seguinte maneira: (linhas, colunas)

Vamos supor que temos o array arr1 que tem uma linha e 4 colunas, e queremos criar o array arr2 com duas linhas e duas colunas. Ou seja, vamos mudar o array de 1x4 para 4x4:

import numpy as np arr1 = np.array([1,2,3,4]) arr2 = np.reshape(arr1, (2,2)) print("Array original 1x4: ", arr1) print("Array reshape 2x2 : \n", arr2)

Mais uma vez é importante salientar: não alteramos o número de elementos, nem seus valores, apenas vamos alterar seu formato (shape).

Agora vamos fazer o contrário, vamos pegar um array arr1 que é uma matriz 3x3 e vamos transformar um array unidimensional, de 9 elementos:

import numpy as np arr1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) arr2 = arr1.reshape(1,9) print("Array original 3x3: \n", arr1) print("Array reshape 1x9 : \n", arr2)

Note que chamamos a função reshape diretamente do array arr1, bastando então fornecer o formato que queremos salvar em arr2, pois já fica subtendido que vamos usar os dados de arr1.


Transformando tudo em um array unidimensional: ravel()

Veja que no último caso foi preciso explicitar as dimensões do array unidimensional. Porém, as vezes não sabemos ou não queremos nos incomodar com o tanto de elementos, apenas queremos transformar a matriz de dados em um array unidimensional. Para fazer isto, basta usar a função ravel():

import numpy as np arr1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) arr2 = np.array([ [9,8], [7,6], [5,4], [3,2]]) print("ravel() de arr1: ", arr1.ravel()) print("ravel() de arr2: ", arr2.ravel())

Lembrando que, tanto a reshape() como a ravel() não vão alterar o formato dos arrays originais.


Resize - mudando o tamanho de arrays

Uma outra operação bem comum em data science, é a de alterar o tamanho de arrays, como por exemplo, unir duas matriz, concatenar arrays ou simplesmente adicionar ou retirar elementos desses arrays.

  • append() : acrescentando elementos ao final

A maneira mais simples de se mudar o tamanho de um array, é adicionando um elemento ao final dele. Para isso, vamos usar a função append(), que cria um novo array, com o original acrescido do que você adicionou.

Por exemplo:

import numpy as np arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) arr3 = np.append(arr1, arr2) arr4 = np.append(arr3, 7) print(arr4)

Para criar o arr3, unimos o arr2 ao final do arr1. Assim, temos : arr3 = [1,2,3,4,5,6]
Já para criar o arr4, simplesmente adicionamos o valor 7 a ele: arr4 = [1,2,3,4,5,6,7]

Se não especificarmos o eixo (axis), essa função primeiro deixar os arrays como unidimensionais e depois faz a junção. Mas, podemos, por exemplo, adicionar elementos ao final tanto no eixo vertical (axis=0), ou seja abaixo, como ao final horizontalmente (axis=1).

import numpy as np

arr1 = np.array([[1, 2],
[3, 4]])

arr2 = np.array([[5, 6],
[7, 8]])

arr3 = np.append(arr1, arr2, axis=0)
arr4 = np.append(arr1, arr2, axis=1)

print("axis=0: \n", arr3)
print("axis=1: \n", arr4)

O resultado é:

axis=0: 
 [1 2]
 [3 4]
 [5 6]
 [7 8]

axis=1: 
 [1 2 5 6]
 [3 4 7 8]

  • concatenate() : juntando quaisquer arrays

Os dois exemplos anteriores de append só funcionaram porque as duas matrizes eram arrays de mesmas dimensões. Experimente usar o append de um array 2x1 em uma matriz 2x2.

Intuitivamente, esperaríamos que o array fosse anexado ao final da matriz. Porém, teste. Teste e veja que não funciona.

Uma maneira de resolver isso, é usar a função concatenate(), que recebe uma lista com os arrays a serem concatenados e se desejar, você pode especificar como vai ocorrer o concatenamento. 

No exemplo abaixo, arr1 é uma matriz 2x2, arr2 é um vetor de linha 1x2 e arr3 é um vetor de coluna 2x1. Criamos arr4 concatenando a linha embaixo da matriz e arr5 é criado concatenando arr3 à direita da matriz, veja:

import numpy as np arr1 = np.array([[1, 2], [3, 4]]) arr2 = np.array([ [5, 6] ]) arr3 = np.array([ [5], [6]]) arr4 = np.concatenate((arr1, arr2), axis=0) arr5 = np.concatenate((arr1, arr3), axis=1) print("axis=0: \n", arr4) print("axis=1: \n", arr5)

Onde a saída será:

axis=0: 
 [[1 2]
  [3 4]
  [5 6]]

axis=1: 
 [[1 2 5]
  [3 4 6]]

Veja que os três arrays declarados são de dimensões diferentes.

  • resize() : criando arrays de quaisquer tamanhos

Por fim, é bem comum termos a necessidade de alterar as dimensões diretamente em um array, seja através da união de outros arrays ou simplesmente expandindo o próprio array.

Através da resize() podemos sempre alterar o tamanho e dimensão do array, e mesmo que isso signifique acrescentar novos elementos, sem termos que especificar novos valores ou fornecer sequer um outro array para fazer ele mudar de tamanho.

Por exemplo, vamos mudar um matriz 2x2 para uma 3x3:

import numpy as np arr = np.array([[1, 2], [3, 4]]) arr2 = np.resize(arr, (3,3)) print(arr2)

E o resultado é:

[[1 2 3]
 [4 1 2]
 [3 4 1]]

Ou seja, o NumPy cria uma cópia do array original, coloca no novo array e repete os valores do array original, até preencher as novas posições da matriz 3x3.

Já se chamarmos a função resize() diretamente do array, sem criar uma nova matriz, ele vai alterar a matriz original, preenchendo ela com valores 0:

import numpy as np arr = np.array([[1, 2], [3, 4]]) arr.resize((3,3)) print(arr)

Saída:

[[1 2 3]
 [4 0 0]
 [0 0 0]]