Fiquei preso em algo que parece que deveria ser relativamente fácil. O código que trago abaixo é um exemplo baseado em um projeto maior no qual estou trabalhando. Não vi motivo para postar todos os detalhes, então aceite as estruturas de dados que trago como estão.
Basicamente, estou criando um gráfico de barras e só posso descobrir como adicionar rótulos de valor nas barras (no centro da barra ou logo acima dela). Tenho procurado exemplos na web, mas sem sucesso na implementação em meu próprio código. Acredito que a solução seja com 'texto' ou 'anotar', mas eu: a) não sei qual usar (e, em geral, não descobri quando usar qual). b) não consigo ver para apresentar os rótulos de valor. Agradeceria sua ajuda, meu código abaixo. Desde já, obrigado!
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
pd.set_option('display.mpl_style', 'default')
%matplotlib inline
# Bring some raw data.
frequencies = [6, 16, 75, 160, 244, 260, 145, 73, 16, 4, 1]
# In my original code I create a series and run on that,
# so for consistency I create a series from the list.
freq_series = pd.Series.from_array(frequencies)
x_labels = [108300.0, 110540.0, 112780.0, 115020.0, 117260.0, 119500.0,
121740.0, 123980.0, 126220.0, 128460.0, 130700.0]
# Plot the figure.
plt.figure(figsize=(12, 8))
fig = freq_series.plot(kind='bar')
fig.set_title('Amount Frequency')
fig.set_xlabel('Amount ($)')
fig.set_ylabel('Frequency')
fig.set_xticklabels(x_labels)
fonte
Respostas:
Em primeiro lugar,
freq_series.plot
retorna um eixo, não uma figura, então, para tornar minha resposta um pouco mais clara, alterei o código fornecido para se referir a ele como emax
vez defig
ser mais consistente com outros exemplos de código.Você pode obter a lista das barras produzidas na trama do
ax.patches
membro. Então você pode usar a técnica demonstrada nestematplotlib
exemplo de galeria para adicionar os rótulos usando oax.text
método.Isso produz um gráfico rotulado que se parece com:
fonte
text
simplesmente imprime algum texto no gráfico, enquantoannotate
é um auxiliar que você pode usar para adicionar facilmente também uma seta do texto apontando para um ponto específico no gráfico que está sendo referido pelo texto.Com base em um recurso mencionado nesta resposta a outra pergunta , descobri uma solução muito aplicável para colocar rótulos em um gráfico de barras.
Outras soluções infelizmente não funcionam em muitos casos, porque o espaçamento entre o rótulo e a barra é dado em unidades absolutas das barras ou é escalado pela altura da barra . O primeiro só funciona para uma faixa estreita de valores e o último fornece espaçamento inconsistente dentro de um gráfico. Nenhum dos dois funciona bem com eixos logarítmicos.
A solução que proponho funciona independente da escala (ou seja, para números pequenos e grandes) e até mesmo coloca rótulos corretamente para valores negativos e com escalas logarítmicas porque usa a unidade visual
points
para deslocamentos.Eu adicionei um número negativo para mostrar a colocação correta das etiquetas em tal caso.
O valor da altura de cada barra é usado como um rótulo para ela. Outros rótulos podem ser facilmente usados com o
for rect, label in zip(rects, labels)
snippet do Simon .Edit: Extraí a funcionalidade relevante em uma função, conforme sugerido por barnhillec .
Isso produz a seguinte saída:
E com a escala logarítmica (e alguns ajustes nos dados de entrada para mostrar a escala logarítmica), este é o resultado:
fonte
Com base na resposta acima (ótimo!), Também podemos fazer um gráfico de barra horizontal com apenas alguns ajustes:
fonte
freq_series.plot(kind='barh', grid=True)
Se você quiser apenas rotular os pontos de dados acima da barra, você pode usar plt.annotate ()
Meu código:
Bem, o texto com vários caracteres pode ser exibido um pouco fora do centro. Mas isso pode ser superado diminuindo ligeiramente a coordenada x no parâmetro xy dependendo do tamanho do texto
fonte
Se você quiser apenas adicionar pontos de dados acima das barras, pode facilmente fazer isso com:
fonte