Neste tutorial, vamos aprender como gerar um gráfico do tipo histograma, através da linguagem de programação Python.
O que é um Histograma
Histograma é um tipo de gráfico, com barras verticais, onde cada uma represente uma classe de valores, e a altura representa a frequência que essa classe aparece no seu conjunto de dados. Numa linguagem mais técnica, representa uma distribuição de frequências.
Por exemplo, um consultório médico criou um histograma, para melhor entender a distribuição de idades dos pacientes:
No eixo x, temos as idades dos pacientes. Cada barra dessas representa uma idade ou intervalo de idades. Já o eixo y representa quantas vezes cada intervalo desses apareceu.
Pelo gráfico, podemos ver que cada barra dessas tem um intervalo próximo de 5 anos. A maior parte dos pacientes, tem por volta dos 20-25 anos e 25-30, pois cada barra que representa esses intervalos apareceu (frequência) mais de 50 vezes. Ou seja, tem mais de 100 pacientes com idade entre 20 e 30 anos.
Pacientes com mais de 90 anos? Bem poucos.
Pacientes com 0-5 anos de idade? Quase 20.
O gráfico do tipo histograma é muito útil quando você tem uma grande quantidade de dados e quer, rápida e facilmente, identificar como está a distribuição de determinados valores desses dados. Por ser uma maneira visual de representar e classificar dados, é muito usada para exibir resultados, seja em trabalhos científicos como em reuniões, por exemplo.
Como podem imaginar, existe uma infinidade de tipos de gráficos histograma, e cada um deles nos diz informações muito importante sobre os dados que estamos analisando.
E, obviamente, o Python pode nos ajudar muito, mas muito mesmo, nessa tarefa de plotar e analisar.
Experimento do Pêndulo Simples
No laboratório de Física da Universidade Federal do Ceará (UFC), realizei o famoso experimento do pêndulo simples:
Onde L é o comprimento da corda do pêndulo, e g o valor da gravidade no local, que é 9,78 m/s² dentro do Campus do Pici, local onde foi realizado a medição.
Logo, o valor teórico do período é: T = 2,009141114 s = 2,01s
Vamos usar o mesmo número de algarismos significativos do cronômetro usado, dois.
Os valores que calculei podem ser obtidos em:
https://github.com/jarlissonmoreira/PythonProgressivo/blob/main/Histograma/data.txt
Note que os valores obtidos experimentalmente estão bem próximos do valor teórico. Vamos colocar esses valores em um histograma e ver isso em um gráfico, para confirmar que a maioria das medições estão ali por volta desse valor 2.01s
O meu arquivo tem 135 linhas, divididas em 10 colunas. Mas o script que será apresentado é bem abrangente, você pode colocar seus dados em quaisquer números de linhas e colunas, que ele vai funcionar.
Vamos aprender como usar o script para plotar um histograma.
Como plotar um Histograma em Python
Vamos usar a biblioteca matplotlib e a função hist() dela, para plotar nosso histograma.
Mas, antes, precisamos tratar nossos dados, antes de passar os valores para essa função.
De onde o script vai puxar esses dados? Onde e como você vai armazenar eles? Eles tem vírgula ou ponto, como decimal? Se for vírgula, precisa trocar por ponto. Como estão formatados? Tudo junto? Numa matriz? Em txt ou csv?
Usar as funções é fácil, o que devemos ter cuidado é na hora de tratar os dados.
No script fornecido abaixo, você pode passar os dados de várias maneiras. Eu, por exemplo, coloquei todos os dados no arquivo txt acima mencionado e em seguida usei o endereço desse arquivo "data.txt" (pois o data.txt está na mesma pasta do script histograma.py) para o parâmetro path da minha função plot_histograma().
Se preferir, pode passar diretamente os dados através do parâmetro data (como não usei, coloquei o valor None nele), fornecendo uma string de valores. Obviamente, só é viável se tiver poucos dados.
Por fim, precisamos configurar o bins, que são os intervalos das barras, no eixo x. Eu passei o valor 'auto', para a função hist() fazer o melhor ajuste possível, mas você pode definir manualmente os intervalos que desejar.
Vamos plotar três gráficos. O primeiro, é o histograma da matriz original, com todos os dados, bastando fazer:
- ax1.hist(array, bins)
Onde array são os dados e bins os intervalos.
No segundo gráfico, vamos calcular as médias de cada linha da matriz. Nossa matriz tem 135 linhas com 10 elementos em cada. Logo, nosso segundo gráfico vai ter 135 elementos. Isso é muito usado em Física Experimental, a média das médias, pois fornecem valores mais confiáveis e próximos do teórico, pois 'amenizam' os resultados muito discrepantes.
Por fim, ploetei os dois gráficos juntos, um na frente do outro, para vermos a diferença.
O resultado ficou:
Nosso script, usado para gerar esses plots de histogramas, é:
import numpy as np from matplotlib import pyplot def plot_histograma(path: str = None, data: str = None, bins: float | str = None) -> None: #path: caminho do arquivo .txt com os dados "caminho/do/data.txt" #bins: se nao fornecido retorna o histograma dos valores individuais, #ele pode ser tamanho (float), ou uma string com valores: 'auto', 'fd', 'doane', 'scott', 'stone', 'rice', 'sturges', or 'sqrt' #return: printa na tela o histograma if path is not None: with open(path, "r") as file: content = file.read().replace(',', '.') values: list[float] = [float(i) for i in content.split()] else: content = data.replace(',', '.') values: list[float] = [float(i) for i in content.split(';')] array = np.array(values) if bins is None: bins=sorted(values) if type(bins) is str: bins=bins if type(bins) is float: bins = np.arange(array.min(), array.max() + bins, bins) #Transforma o array/lista de valores em uma matriz com 10 colunas col = 10 lin = int(len(array)/col) array2 = array.reshape(lin,col) #Cria um array, onde cada elemento é uma média de 10 valores, #de cada linha da matriz anterior median=np.mean(array2, axis=1) #Novo código para imprimir os três gráficos, com mesmo eixo x fig, (ax1, ax2, ax3) = pyplot.subplots(3, 1, sharex=True) #Primeiro gráfico, de 1350 medições ax1.hist(array, bins) ax1.xaxis.set_tick_params(labelbottom=True) leg1 = str(lin*col) ax1.set_xlabel(leg1+' medições') #Segundo gráfico, das 135 médias ax2.hist(median,bins) ax2.xaxis.set_tick_params(labelbottom=True) leg2 = str(len(median)) ax2.set_xlabel(leg2+' médias') #Sobrepondo os dois, para efeitos de comparação ax3.hist(array, bins, alpha=0.5, label=leg1) ax3.hist(median, bins, alpha=0.5, label=leg2) ax3.set_xlabel('Gráficos sobrepostos') ax3.legend(loc='upper right') pyplot.tight_layout() pyplot.show() path="data.txt" data=None bins='auto' plot_histograma(path,data,bins)
Nenhum comentário:
Postar um comentário