Pular para o conteúdo principal
InicioTutoriaisPython

Histogramas no Matplotlib

Aprenda sobre histogramas e como você pode usá-los para obter insights dos dados com a ajuda do matplotlib.
abr. de 2024  · 8 min leer

Introdução

De acordo com a Wikipediaum histograma é uma representação gráfica precisa da distribuição de dados numéricos. É uma estimativa da distribuição de probabilidade de uma variável contínua (variável quantitativa) e foi introduzida pela primeira vez por Karl Pearson. É um tipo de gráfico de barras. Para construir um histograma, a primeira etapa é "classificar" o intervalo de valores, ou seja, dividir todo o intervalo de valores em uma série de intervalos e, em seguida, contar quantos valores se enquadram em cada intervalo. Os compartimentos geralmente são especificados como intervalos consecutivos e não sobrepostos de uma variável. Os compartimentos (intervalos) devem ser adjacentes e geralmente são (mas não precisam ser) de tamanho igual.

Além dos dados numéricos, os histogramas também podem ser usados para visualizar a distribuição de imagens, pois as imagens nada mais são do que uma combinação de elementos de imagem (pixels) que variam de $0$ a $255$. O eixo x do histograma indica o número de compartimentos, enquanto o eixo y representa a frequência de um compartimento específico. O número de compartimentos é um parâmetro que pode ser variado com base em como você deseja visualizar a distribuição dos dados.

Por exemplo: Digamos que você queira traçar um histograma de uma imagem RGB com valores de pixel que variam de $0$ a $255$. O máximo de compartimentos que essa imagem pode ter é $255$. Se você mantiver o eixo x (número de compartimentos) como $255$, o eixo y indicará a frequência de cada pixel nessa imagem.

Os histogramas são semelhantes em espírito aos gráficos bar. Vamos dar uma olhada em um exemplo pictórico de um histograma:

Um histograma é uma excelente ferramenta para visualizar e compreender a distribuição probabilística de dados numéricos ou dados de imagem que é intuitivamente compreendida por quase todo mundo. O Python tem muitas opções diferentes para criar e plotar histogramas. O Python tem poucas bibliotecas embutidas para criar gráficos, e uma delas é a matplotlib.

No tutorial de hoje, você usará principalmente o matplotlib para criar e visualizar histogramas em vários tipos de conjuntos de dados.

Portanto, sem mais delongas, vamos começar.

Plotagem de histograma usando NumPy e Matplotlib

import numpy as np

Para fins de reprodutibilidade, você usará a função seed do numPy, que fornecerá o mesmo resultado sempre que for executada.

Você traçará o histograma de gaussian (normal) distribution, que terá uma média de $0$ e um desvio padrão de $1$.

np.random.seed(100)
np_hist = np.random.normal(loc=0, scale=1, size=1000)
np_hist[:10]
array([-1.74976547,  0.3426804 ,  1.1530358 , -0.25243604,  0.98132079,
        0.51421884,  0.22117967, -1.07004333, -0.18949583,  0.25500144])

Vamos verificar a média e o desvio padrão da distribuição acima.

np_hist.mean(),np_hist.std()
(-0.016772157343909157, 1.0458427194167)

Em seguida, você usará a função histogram do numPy, que retornará hist e bin_edges.

hist,bin_edges = np.histogram(np_hist)
hist
array([  7,  37, 111, 207, 275, 213, 105,  31,  10,   4])
bin_edges
array([-3.20995538, -2.50316588, -1.79637637, -1.08958687, -0.38279736,
        0.32399215,  1.03078165,  1.73757116,  2.44436066,  3.15115017,
        3.85793967])

Em seguida, vamos plotar o histograma usando a função plt.bar do matplotlib, em que o eixo x e o eixo y serão bin_edges e hist, respectivamente.

import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=[10,8])

plt.bar(bin_edges[:-1], hist, width = 0.5, color='#0504aa',alpha=0.7)
plt.xlim(min(bin_edges), max(bin_edges))
plt.grid(axis='y', alpha=0.75)
plt.xlabel('Value',fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.title('Normal Distribution Histogram',fontsize=15)
plt.show()

Vamos arredondar o bin_edges para um número inteiro.

bin_edges = np.round(bin_edges,0)
plt.figure(figsize=[10,8])

plt.bar(bin_edges[:-1], hist, width = 0.5, color='#0504aa',alpha=0.7)
plt.xlim(min(bin_edges), max(bin_edges))
plt.grid(axis='y', alpha=0.75)
plt.xlabel('Value',fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.title('Normal Distribution Histogram',fontsize=15)
plt.show()

Agora o gráfico está muito melhor, não é mesmo?

Para entender hist e bin_edges, vejamos um exemplo:

Você definirá uma matriz com valores arbitrários e definirá compartimentos com um intervalo de $5$.

hist, bin_edges = np.histogram([1, 1, 2, 2, 2, 2, 3],bins=range(5))
hist
array([0, 2, 4, 1])

Na saída acima, hist indica que há itens de $0$ no compartimento $0$, $2$ no compartimento $1$, $4$ no compartimento $3$, $1$ no compartimento $4$.

bin_edges
array([0, 1, 2, 3, 4])

Da mesma forma, a saída do site bin_edges acima significa que a posição $0$ está no intervalo $[0,1)$, a posição $1$ está no intervalo $[1,2)$, a posição $2$ está no intervalo $[2,3)$, a posição $3$ está no intervalo $[3,4)$.

Plotagem de histograma usando apenas o Matplotlib

Traçar um histograma usando matplotlib é muito fácil. Tudo o que você precisa fazer é usar a função plt.hist() do matplotlib e passar os dados juntamente com o número de compartimentos e alguns parâmetros opcionais.

Em plt.hist(), passar bins='auto' lhe dá o número "ideal" de bins. A ideia é selecionar uma largura de compartimento que gere a representação mais fiel de seus dados.

Isso é tudo. Então, vamos traçar o histograma do normal_distribution que você criou usando numpy.

plt.figure(figsize=[10,8])
n, bins, patches = plt.hist(x=np_hist, bins=8, color='#0504aa',alpha=0.7, rwidth=0.85)
plt.grid(axis='y', alpha=0.75)
plt.xlabel('Value',fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.title('Normal Distribution Histogram',fontsize=15)
plt.show()

Plotagem conjunta de dois histogramas

plt.figure(figsize=[10,8])
x = 0.3*np.random.randn(1000)
y = 0.3*np.random.randn(1000)
n, bins, patches = plt.hist([x, y])

Traçando o histograma de dados da íris usando o Pandas

Você usará o site sklearn para carregar um conjunto de dados chamado iris. No sklearn, você tem uma biblioteca chamada datasets, na qual está o conjunto de dados do Iris, que pode ser carregado em tempo real. Então, vamos carregar rapidamente o conjunto de dados da íris.

from sklearn.datasets import load_iris
import pandas as pd
data = load_iris().data
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width']

Em seguida, você criará o dataframe do conjunto de dados iris.

dataset = pd.DataFrame(data,columns=names)
dataset.head()
  sepal-length largura da sépala petal-length largura da pétala
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
dataset.columns[0]
'sepal-length'

Por fim, você usará a função incorporada do pandas .hist() , que traçará histogramas para todos os recursos presentes no conjunto de dados.

Isso não é maravilhoso?

fig = plt.figure(figsize = (8,8))
ax = fig.gca()
dataset.hist(ax=ax)
plt.show()

O comprimento da pétala, a largura da pétala e o comprimento da sépala mostram uma distribuição unimodal, enquanto a largura da sépala reflete uma curva gaussiana. Todas essas análises são úteis, pois assim você pode pensar em usar um algoritmo que funcione bem com esse tipo de distribuição.

Plotar histograma com Matplotlib

plt.figure(figsize=[10,10])
f,a = plt.subplots(2,2)
a = a.ravel()
for idx,ax in enumerate(a):
    ax.hist(dataset.iloc[:,idx], bins='auto', color='#0504aa',alpha=0.7, rwidth=0.85)
    ax.set_title(dataset.columns[idx])
plt.tight_layout()
<Figure size 720x720 with 0 Axes>

Traçado de histograma de imagens binárias e RGB

No segmento final do tutorial, você visualizará duas imagens de domínios diferentes: imagens binárias (documentos) e naturais. As imagens binárias são aquelas em que os valores de pixel são, em sua maioria, $0$ ou $255$, enquanto uma imagem de canal colorido pode ter um valor de pixel que varia entre $0$ e $255$.

Analisar a distribuição de pixels traçando um histograma de valores de intensidade de uma imagem é a maneira correta de medir a ocorrência de cada pixel em uma determinada imagem. Para uma imagem em escala de cinza de 8 bits, há 256 valores de intensidade possíveis. Portanto, para estudar a diferença entre o documento e as imagens naturais no domínio da distribuição de pixels, você traçará dois histogramas para o documento e a imagem natural, respectivamente. Considerando que os documentos legíveis têm esparsidade, a distribuição de pixels nessas imagens de documentos deve ser mais distorcida.

Você usará o módulo opencv para carregar as duas imagens, convertê-las em escala de cinza passando um parâmetro $0$ durante a leitura e, por fim, redimensioná-las para o mesmo tamanho.

import cv2
lena_rgb = cv2.imread('lena.png')
lena_gray = cv2.cvtColor(lena_rgb,cv2.COLOR_BGR2GRAY)
lena_gray.shape
(512, 512)
binary = cv2.imread('binary.png')
binary.shape
(1394, 2190, 3)
binary = cv2.resize(binary,(512,512),cv2.INTER_CUBIC)
binary.shape
(512, 512, 3)
binary_gray = cv2.cvtColor(binary,cv2.COLOR_BGR2GRAY)
binary_gray.shape
(512, 512)

Vamos visualizar a imagem natural e a imagem do documento.

plt.figure(figsize=[10,10])

plt.subplot(121)
plt.imshow(lena_rgb[:,:,::-1])
plt.title("Natural Image")

plt.subplot(122)
plt.imshow(binary[:,:,::-1])
plt.title("Document Image")
plt.show()

Observação: Você usará bins igual a $255$, pois há um total de $255$ pixels em uma imagem e você deseja visualizar a frequência de cada valor de pixel da imagem variando de $0$ a $255$.

hist, edges = np.histogram(binary_gray,bins=range(255))
plt.figure(figsize=[10,8])

plt.bar(edges[:-1], hist, width = 0.8, color='#0504aa')
plt.xlim(min(edges), max(edges))
plt.grid(axis='y', alpha=0.75)
plt.xlabel('Value',fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.title('Document Image Histogram',fontsize=15)
plt.show()
hist, edges = np.histogram(lena_gray,bins=range(260))
plt.figure(figsize=[10,8])

plt.bar(edges[:-1], hist, width = 0.5, color='#0504aa')
plt.xlim(min(edges), max(edges))
plt.grid(axis='y', alpha=0.75)
plt.xlabel('Pixels',fontsize=15)
plt.ylabel('Frequency of Pixels',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.ylabel('Frequency',fontsize=15)
plt.title('Natural Image Histogram',fontsize=15)
plt.show()

Nas figuras acima, você pode observar que o natural image está espalhado por todas as 256 intensidades, tendo uma distribuição random, enquanto a imagem do documento mostra uma distribuição unimodal e é mais inclinada entre os valores de pixel $0$ e $255$.

Conclusão

Parabéns por terminar o tutorial.

Este tutorial foi um bom ponto de partida para saber como você pode criar um histograma usando o matplotlib com a ajuda do numpy e do pandas.

Você também aprendeu como aproveitar o poder do histograma para diferenciar dois domínios de imagem diferentes, ou seja, documento e imagem natural.

Se você quiser saber mais sobre técnicas de visualização de dados, considere fazer o curso DataCamp's Data Visualization with Matplotlib.

Fique à vontade para fazer qualquer pergunta relacionada a este tutorial na seção de comentários abaixo.

Temas

Saiba mais sobre Python

Course

Introduction to Data Visualization with Matplotlib

4 hr
170.8K
Learn how to create, customize, and share data visualizations using Matplotlib.
See DetailsRight Arrow
Start Course
Veja MaisRight Arrow
Relacionado

blog

Como aprender Python do zero em 2024: um guia especializado

Descubra como aprender Python, suas aplicações e a demanda por competências em Python. Comece sua jornada em Python hoje mesmo ​com nosso guia detalhado.
Matt Crabtree's photo

Matt Crabtree

19 min

blog

Explorando 12 das melhores ferramentas de visualização de dados em 2023 com exemplos

Há muitas ferramentas de visualização de dados disponíveis. Neste artigo, preparamos uma lista abrangente de algumas das ferramentas de visualização de dados mais úteis na ciência de dados.
Javier Canales Luna 's photo

Javier Canales Luna

17 min

blog

Mais de 60 projetos Python para todos os níveis de conhecimento

60 ideias de projetos de ciência de dados que os cientistas de dados podem usar para criar um portfólio sólido, independentemente de sua especialização.
Bekhruz Tuychiev's photo

Bekhruz Tuychiev

16 min

tutorial

Como comentar um bloco de código em Python

O uso de comentários é fundamental para trabalhar efetivamente com Python. Neste breve tutorial, aprenda a comentar um bloco de código em Python.
Adel Nehme's photo

Adel Nehme

3 min

tutorial

Como aparar uma cadeia de caracteres em Python: Três métodos diferentes

Aprenda os fundamentos do corte de caracteres à esquerda e à direita de uma string em Python.
Adel Nehme's photo

Adel Nehme

5 min

tutorial

Tutorial de Python

Em Python, tudo é objeto. Números, cadeias de caracteres (strings), DataFrames, e até mesmo funções são objetos. Especificamente, qualquer coisa que você usa no Python tem uma classe, um modelo associado por trás.
DataCamp Team's photo

DataCamp Team

3 min

See MoreSee More