O ciclo de vida de um enredo #

Este tutorial visa mostrar o início, o meio e o fim de uma única visualização usando o Matplotlib. Começaremos com alguns dados brutos e terminaremos salvando a figura de uma visualização personalizada. Ao longo do caminho, tentamos destacar alguns recursos interessantes e melhores práticas usando o Matplotlib.

Observação

Este tutorial é baseado nesta excelente postagem de blog de Chris Moffitt. Ele foi transformado neste tutorial por Chris Holdgraf.

Uma observação sobre interfaces explícitas e implícitas #

Matplotlib tem duas interfaces. Para obter uma explicação das compensações entre as interfaces explícitas e implícitas, consulte Matplotlib Application Interfaces (APIs) .

Na interface orientada a objetos (OO) explícita, utilizamos diretamente instâncias de axes.Axespara construir a visualização em uma instância de figure.Figure. Na interface implícita, inspirada e modelada no MATLAB, usa uma interface baseada em estado global que é encapsulada no pyplotmódulo para plotar os "Eixos atuais". Veja os tutoriais do pyplot para uma visão mais aprofundada da interface do pyplot.

A maioria dos termos é direta, mas a principal coisa a lembrar é que:

  • A Figura é a imagem final que pode conter 1 ou mais Eixos.

  • Os eixos representam um gráfico individual (não confunda isso com a palavra "eixo", que se refere ao eixo x/y de um gráfico).

Chamamos métodos que fazem a plotagem diretamente dos Axes, o que nos dá muito mais flexibilidade e poder na customização da nossa plotagem.

Observação

Em geral, prefira a interface explícita sobre a interface pyplot implícita para plotagem.

Nossos dados #

Usaremos os dados da postagem da qual este tutorial foi derivado. Ele contém informações de vendas para várias empresas.

import numpy as np
import matplotlib.pyplot as plt


data = {'Barton LLC': 109438.50,
        'Frami, Hills and Schmidt': 103569.59,
        'Fritsch, Russel and Anderson': 112214.71,
        'Jerde-Hilpert': 112591.43,
        'Keeling LLC': 100934.30,
        'Koepp Ltd': 103660.54,
        'Kulas Inc': 137351.96,
        'Trantow-Barrows': 123381.38,
        'White-Trantow': 135841.99,
        'Will LLC': 104437.60}
group_data = list(data.values())
group_names = list(data.keys())
group_mean = np.mean(group_data)

Primeiros passos #

Esses dados são naturalmente visualizados como um gráfico de barras, com uma barra por grupo. Para fazer isso com a abordagem orientada a objetos, primeiro geramos uma instância de figure.Figuree axes.Axes. A Figura é como uma tela, e os Eixos são uma parte dessa tela na qual faremos uma determinada visualização.

Observação

As figuras podem ter vários eixos nelas. Para obter informações sobre como fazer isso, consulte o tutorial Tight Layout .

fig, ax = plt.subplots()
ciclo da vida

Agora que temos uma instância de Axes, podemos plotar em cima dela.

ciclo da vida
<BarContainer object of 10 artists>

Controlando o estilo #

Existem muitos estilos disponíveis no Matplotlib para permitir que você adapte sua visualização às suas necessidades. Para ver uma lista de estilos, podemos usar style.

['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn-v0_8', 'seaborn-v0_8-bright', 'seaborn-v0_8-colorblind', 'seaborn-v0_8-dark', 'seaborn-v0_8-dark-palette', 'seaborn-v0_8-darkgrid', 'seaborn-v0_8-deep', 'seaborn-v0_8-muted', 'seaborn-v0_8-notebook', 'seaborn-v0_8-paper', 'seaborn-v0_8-pastel', 'seaborn-v0_8-poster', 'seaborn-v0_8-talk', 'seaborn-v0_8-ticks', 'seaborn-v0_8-white', 'seaborn-v0_8-whitegrid', 'tableau-colorblind10']

Você pode ativar um estilo com o seguinte:

plt.style.use('fivethirtyeight')

Agora vamos refazer o gráfico acima para ver como fica:

ciclo da vida
<BarContainer object of 10 artists>

O estilo controla muitas coisas, como cor, larguras de linha, planos de fundo, etc.

Personalizando o enredo #

Agora temos um gráfico com a aparência geral que queremos, então vamos ajustá-lo para que esteja pronto para impressão. Primeiro, vamos girar os rótulos no eixo x para que apareçam com mais clareza. Podemos obter acesso a esses rótulos com o axes.Axes.get_xticklabels()método:

ciclo da vida

Se quisermos definir a propriedade de muitos itens de uma só vez, é útil usar a pyplot.setp()função. Isso pegará uma lista (ou muitas listas) de objetos Matplotlib e tentará definir algum elemento de estilo de cada um.

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ciclo da vida
[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]

Parece que isso cortou algumas das etiquetas na parte inferior. Podemos dizer ao Matplotlib para abrir espaço automaticamente para elementos nas figuras que criamos. Para fazer isso, definimos o autolayoutvalor de nosso rcParams. Para obter mais informações sobre como controlar o estilo, layout e outros recursos de plotagens com rcParams, consulte Personalizando Matplotlib com folhas de estilo e rcParams .

plt.rcParams.update({'figure.autolayout': True})

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ciclo da vida
[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]

Em seguida, adicionamos rótulos ao gráfico. Para fazer isso com a interface OO, podemos usar o Artist.set()método para definir as propriedades desse objeto Axes.

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
Receita da Empresa
[(-10000.0, 140000.0), Text(0.5, 87.00000000000003, 'Total Revenue'), Text(86.99999999999997, 0.5, 'Company'), Text(0.5, 1.0, 'Company Revenue')]

Também podemos ajustar o tamanho deste gráfico usando a pyplot.subplots() função. Podemos fazer isso com o argumento da palavra-chave figsize .

Observação

Enquanto a indexação no NumPy segue a forma (linha, coluna), o argumento da palavra-chave figsize segue a forma (largura, altura). Isso segue as convenções de visualização, que infelizmente são diferentes daquelas da álgebra linear.

fig, ax = plt.subplots(figsize=(8, 4))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
Receita da Empresa
[(-10000.0, 140000.0), Text(0.5, 86.99999999999997, 'Total Revenue'), Text(86.99999999999997, 0.5, 'Company'), Text(0.5, 1.0, 'Company Revenue')]

Para rótulos, podemos especificar diretrizes de formatação personalizadas na forma de funções. Abaixo definimos uma função que recebe um inteiro como entrada e retorna uma string como saída. Quando usados ​​com Axis.set_major_formatterou Axis.set_minor_formatter, eles criarão e usarão automaticamente uma ticker.FuncFormatterclasse.

Para esta função, o xargumento é o rótulo original do tick e pos é a posição do tick. Usaremos apenas xaqui, mas ambos os argumentos são necessários.

def currency(x, pos):
    """The two arguments are the value and tick position"""
    if x >= 1e6:
        s = '${:1.1f}M'.format(x*1e-6)
    else:
        s = '${:1.0f}K'.format(x*1e-3)
    return s

Podemos então aplicar essa função aos rótulos em nosso gráfico. Para fazer isso, usamos o xaxisatributo de nossos eixos. Isso permite que você execute ações em um eixo específico em nosso gráfico.

fig, ax = plt.subplots(figsize=(6, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
ax.xaxis.set_major_formatter(currency)
Receita da Empresa

Combinando várias visualizações #

É possível desenhar vários elementos de plotagem na mesma instância de axes.Axes. Para fazer isso, simplesmente precisamos chamar outro dos métodos plot naquele objeto de eixos.

fig, ax = plt.subplots(figsize=(8, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

# Add a vertical line, here we set the style in the function call
ax.axvline(group_mean, ls='--', color='r')

# Annotate new companies
for group in [3, 5, 8]:
    ax.text(145000, group, "New Company", fontsize=10,
            verticalalignment="center")

# Now we move our title up since it's getting a little cramped
ax.title.set(y=1.05)

ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
ax.xaxis.set_major_formatter(currency)
ax.set_xticks([0, 25e3, 50e3, 75e3, 100e3, 125e3])
fig.subplots_adjust(right=.1)

plt.show()
Receita da Empresa

Salvando nosso enredo #

Agora que estamos satisfeitos com o resultado de nossa plotagem, queremos salvá-la em disco. Existem muitos formatos de arquivo nos quais podemos salvar no Matplotlib. Para ver uma lista de opções disponíveis, use:

{'eps': 'Encapsulated Postscript', 'jpg': 'Joint Photographic Experts Group', 'jpeg': 'Joint Photographic Experts Group', 'pdf': 'Portable Document Format', 'pgf': 'PGF code for LaTeX', 'png': 'Portable Network Graphics', 'ps': 'Postscript', 'raw': 'Raw RGBA bitmap', 'rgba': 'Raw RGBA bitmap', 'svg': 'Scalable Vector Graphics', 'svgz': 'Scalable Vector Graphics', 'tif': 'Tagged Image File Format', 'tiff': 'Tagged Image File Format', 'webp': 'WebP Image Format'}

Podemos então usar o figure.Figure.savefig()para salvar a figura no disco. Observe que existem vários sinalizadores úteis que mostramos abaixo:

  • transparent=Truetorna o fundo da figura salva transparente se o formato o suportar.

  • dpi=80controla a resolução (pontos por polegada quadrada) da saída.

  • bbox_inches="tight"ajusta os limites da figura ao nosso enredo.

# Uncomment this line to save the figure.
# fig.savefig('sales.png', transparent=False, dpi=80, bbox_inches="tight")

Tempo total de execução do script: ( 0 minutos 3,918 segundos)

Galeria gerada por Sphinx-Gallery