Gráficos de Pizza com Matplotlib
Aprenda a criar e personalizar gráficos de pizza em Python com Matplotlib: cores, explode, donuts, rótulos, legendas e como salvar em arquivo.
Os gráficos de pizza dividem um círculo em fatias, onde o ângulo de cada fatia é proporcional ao valor que ela representa. Eles funcionam melhor quando você tem um número pequeno de categorias (idealmente 2–6) e deseja mostrar como cada parte se relaciona com o todo — por exemplo, participação de mercado por produto ou alocação de orçamento por departamento.
Este capítulo abrange desde um primeiro gráfico mínimo até técnicas avançadas como gráficos de rosca, posicionamento personalizado de rótulos e como salvar figuras prontas para publicação. Todos os exemplos usam matplotlib.pyplot, a API padrão de alto nível.
Instalação e Configuração
Se você ainda não instalou o Matplotlib, execute este comando no seu terminal:
pip install matplotlibCada exemplo neste capítulo começa com esta importação:
import matplotlib.pyplot as pltplt é o alias convencional para matplotlib.pyplot. Ele fornece funções como plt.pie(), plt.title() e plt.show().
Criando um Gráfico de Pizza Básico
plt.pie() é a função principal. No mínimo, ela recebe uma sequência de valores numéricos — as proporções são calculadas automaticamente.
import matplotlib.pyplot as plt
labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
plt.pie(values, labels=labels, autopct='%1.1f%%')
plt.title('Website Visitors by Device')
plt.show()Parâmetros principais usados aqui:
| Parâmetro | Finalidade |
|---|---|
values | Dados numéricos; o Matplotlib os converte em proporções |
labels | Nomes das categorias desenhados ao lado de cada fatia |
autopct | String de formato para os rótulos de porcentagem; '%1.1f%%' gera 60.0% |
Por padrão, o gráfico começa a desenhar as fatias no sentido anti-horário a partir da posição das 3 horas. A próxima seção explica como alterar isso.
Controlando a Rotação com startangle
Definir startangle=90 rotaciona todo o gráfico para que a primeira fatia comece na posição das 12 horas, que é o ponto de partida mais natural para a maioria dos leitores.
import matplotlib.pyplot as plt
labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
plt.pie(
values,
labels=labels,
autopct='%1.1f%%',
startangle=90,
)
plt.title('Website Visitors by Device')
plt.show()startangle aceita qualquer ângulo em graus, medido no sentido anti-horário a partir do eixo x positivo. Um valor de 90 aponta diretamente para cima.
Personalizando Cores
Passe uma lista de códigos de cor hexadecimais ou nomes de cores para o parâmetro colors. A lista deve ter pelo menos o mesmo tamanho que seus dados.
import matplotlib.pyplot as plt
labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']
plt.pie(
values,
labels=labels,
colors=colors,
autopct='%1.1f%%',
startangle=90,
)
plt.title('Website Visitors by Device')
plt.show()Você também pode usar qualquer um dos mapas de cores integrados do Matplotlib. Por exemplo, para extrair três cores da paleta tab10:
import matplotlib.pyplot as plt
import matplotlib.cm as cm
labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
cmap = cm.get_cmap('tab10')
colors = [cmap(i) for i in range(len(values))]
plt.pie(values, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
plt.title('Website Visitors by Device')
plt.show()Destacando uma Fatia (Explode)
O parâmetro explode desloca uma ou mais fatias para fora, chamando atenção para elas. Ele recebe uma tupla de valores float, um por fatia. Um valor de 0.1 desloca a fatia em 10% do raio do gráfico.
import matplotlib.pyplot as plt
labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']
explode = (0.1, 0, 0) # offset the first slice (Desktop) only
plt.pie(
values,
labels=labels,
colors=colors,
explode=explode,
autopct='%1.1f%%',
startangle=90,
shadow=True, # drop shadow for depth
)
plt.title('Website Visitors by Device')
plt.show()Definir shadow=True adiciona uma sutil sombra que enfatiza ainda mais a fatia destacada.
Adicionando Título e Legenda
Use plt.title() para o título do gráfico e plt.legend() para uma caixa de legenda separada. Uma legenda é útil quando o texto dos rótulos é longo ou quando as fatias são pequenas demais para rotular claramente.
import matplotlib.pyplot as plt
labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']
plt.pie(
values,
labels=labels,
colors=colors,
autopct='%1.1f%%',
startangle=90,
)
plt.title('Website Visitors by Device')
plt.legend(title='Device type', loc='lower right')
plt.show()loc aceita strings de posição padrão como 'upper right', 'lower left' e 'center'. Você também pode fornecer uma tupla bbox_to_anchor para posicionamento preciso em nível de pixel.
Controlando a Distância dos Rótulos
Dois parâmetros controlam a distância dos rótulos em relação ao centro do gráfico:
labeldistance— distância do rótulo da categoria em relação ao centro, como fração do raio. O padrão é1.1(logo fora da fatia).pctdistance— distância do rótulo de porcentagem gerado pelo autopct em relação ao centro. O padrão é0.6(dentro da fatia).
import matplotlib.pyplot as plt
labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
plt.pie(
values,
labels=labels,
autopct='%1.1f%%',
startangle=90,
labeldistance=1.2, # push category labels further out
pctdistance=0.75, # move percentages slightly outward from center
)
plt.title('Website Visitors by Device')
plt.show()Aumente pctdistance quando as fatias forem grandes e a posição padrão parecer congestionada; diminua quando houver muitas fatias pequenas.
Criando um Gráfico de Rosca (Donut)
Um gráfico de rosca é um gráfico de pizza com um buraco no meio. Use o parâmetro wedgeprops para definir a largura do anel, expressa como fração do raio. Por exemplo, width=0.5 deixa 50% do raio como o buraco.
import matplotlib.pyplot as plt
labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']
plt.pie(
values,
labels=labels,
colors=colors,
autopct='%1.1f%%',
startangle=90,
pctdistance=0.85,
wedgeprops=dict(width=0.5), # ring width = 50 % of radius
)
plt.title('Website Visitors by Device')
plt.show()Gráficos de rosca são populares porque o centro vazio fornece espaço para um total ou métrica resumida, que você pode adicionar com plt.text(0, 0, 'Total\n100', ha='center', va='center', fontsize=14).
Múltiplos Gráficos de Pizza Lado a Lado
Use plt.subplots() para colocar dois ou mais gráficos de pizza na mesma figura. Cada chamada ax.pie() opera em seu próprio objeto de eixos.
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
# --- Chart 1: this month ---
labels = ['Desktop', 'Mobile', 'Tablet']
values_this_month = [60, 30, 10]
ax1.pie(values_this_month, labels=labels, autopct='%1.1f%%', startangle=90)
ax1.set_title('This Month')
# --- Chart 2: last month ---
values_last_month = [70, 20, 10]
ax2.pie(values_last_month, labels=labels, autopct='%1.1f%%', startangle=90)
ax2.set_title('Last Month')
fig.suptitle('Website Visitors by Device', fontsize=14)
plt.tight_layout()
plt.show()fig.suptitle() adiciona um título acima de todos os subgráficos. plt.tight_layout() evita sobreposição de rótulos entre os gráficos.
Salvando um Gráfico de Pizza em Arquivo
Substitua plt.show() por plt.savefig() para gravar o gráfico em disco em vez de exibi-lo em uma janela. Isso é essencial para scripts executados em servidores sem interface gráfica ou para gerar recursos de relatório.
import matplotlib.pyplot as plt
labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
plt.pie(values, labels=labels, autopct='%1.1f%%', startangle=90)
plt.title('Website Visitors by Device')
plt.savefig('pie_chart.png', dpi=150, bbox_inches='tight')Opções comuns do savefig():
| Opção | Efeito |
|---|---|
dpi=150 | Resolução em pontos por polegada (72–300 para uso típico) |
bbox_inches='tight' | Remove espaço em branco ao redor da figura |
transparent=True | Salva com fundo transparente |
format='svg' | Gera SVG vetorial em vez de PNG raster |
Erros Comuns
Valores que não somam 100. plt.pie() sempre normaliza os valores para que as fatias preencham o círculo completo. Se seus valores representam porcentagens que já somam 100, está correto. Se representam contagens brutas, também está correto — o Matplotlib divide cada valor pelo total. O rótulo autopct sempre mostra a proporção, não o valor bruto.
Valores zero ou negativos. O Matplotlib ignora silenciosamente fatias com valor zero (elas não produzem fatia visível). Valores negativos geram um ValueError. Filtre-os antes de chamar plt.pie().
Fatias em excesso. Gráficos de pizza se tornam ilegíveis com mais de 6–8 fatias. Para muitas categorias, considere um gráfico de barras em vez disso. Como alternativa, agrupe as categorias menores em uma fatia "Outros".
Sobreposição de rótulos. Quando as fatias são pequenas, os rótulos colidem. As soluções incluem aumentar labeldistance, usar uma legenda em vez de rótulos inline (defina labels=None e chame plt.legend()), ou usar um gráfico de rosca com mais espaço na parte externa.
Referência Rápida
| Parâmetro | Tipo | Padrão | Finalidade |
|---|---|---|---|
x | sequence | — | Os valores dos dados |
labels | list | None | Nomes das categorias |
colors | list | cycle | Cores das fatias |
explode | tuple | None | Deslocamento de cada fatia em relação ao centro |
autopct | str / callable | None | Formato para rótulos de porcentagem |
pctdistance | float | 0.6 | Distância do rótulo de porcentagem ao centro |
labeldistance | float | 1.1 | Distância do rótulo de categoria ao centro |
startangle | float | 0 | Ângulo inicial em graus |
shadow | bool | False | Sombra projetada |
wedgeprops | dict | None | Propriedades passadas a cada fatia (ex.: width para rosca) |
counterclock | bool | True | Direção em que as fatias são desenhadas |
Tópicos Relacionados
- Gráficos de Barras com Matplotlib — melhor que gráficos de pizza quando você tem muitas categorias ou precisa de comparações precisas.
- Histogramas com Matplotlib — para visualizar a distribuição de dados contínuos.
- Rótulos no Matplotlib — como adicionar e estilizar rótulos de eixos, títulos e anotações.
- Subplots no Matplotlib — como posicionar múltiplos gráficos em uma única figura.