Gráfico de Caixas de Fita com Matplotlib

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Matplotlib é uma biblioteca popular de visualização de dados para Python. Este tutorial irá guiá-lo através da criação de um gráfico de caixa de fita (ribbon box chart), uma forma única de visualizar dados. Um gráfico de caixa de fita é um gráfico de barras empilhadas onde cada barra é "semelhante a uma fita" e possui um esquema de cores gradiente.

Dicas para a VM

Após a inicialização da VM, clique no canto superior esquerdo para mudar para a aba Notebook para acessar o Jupyter Notebook para praticar.

Às vezes, pode ser necessário aguardar alguns segundos para que o Jupyter Notebook termine de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se você enfrentar problemas durante o aprendizado, sinta-se à vontade para perguntar ao Labby. Forneça feedback após a sessão, e resolveremos o problema prontamente para você.

Importando bibliotecas e carregando dados

Nesta etapa, importaremos as bibliotecas necessárias e carregaremos os dados.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cbook
from matplotlib import colors as mcolors
from matplotlib.image import AxesImage
from matplotlib.transforms import Bbox, BboxTransformTo, TransformedBbox

Criando a classe RibbonBox

Nesta etapa, criaremos a classe RibbonBox que será usada para criar as cores gradientes para as caixas de fita.

class RibbonBox:
    ## Carrega a imagem da caixa de fita
    original_image = plt.imread(cbook.get_sample_data("Minduka_Present_Blue_Pack.png"))
    cut_location = 70
    b_and_h = original_image[:, :, 2:3]
    color = original_image[:, :, 2:3] - original_image[:, :, 0:1]
    alpha = original_image[:, :, 3:4]
    nx = original_image.shape[1]

    def __init__(self, color):
        rgb = mcolors.to_rgb(color)
        self.im = np.dstack([self.b_and_h - self.color * (1 - np.array(rgb)), self.alpha])

    def get_stretched_image(self, stretch_factor):
        stretch_factor = max(stretch_factor, 1)
        ny, nx, nch = self.im.shape
        ny2 = int(ny*stretch_factor)
        return np.vstack([self.im[:self.cut_location],
                          np.broadcast_to(self.im[self.cut_location], (ny2 - ny, nx, nch)),
                          self.im[self.cut_location:]])

Criando a classe RibbonBoxImage

Nesta etapa, criaremos a classe RibbonBoxImage que será usada para criar as caixas de fita propriamente ditas.

class RibbonBoxImage(AxesImage):
    zorder = 1

    def __init__(self, ax, bbox, color, *, extent=(0, 1, 0, 1), **kwargs):
        super().__init__(ax, extent=extent, **kwargs)
        self._bbox = bbox
        self._ribbonbox = RibbonBox(color)
        self.set_transform(BboxTransformTo(bbox))

    def draw(self, renderer, *args, **kwargs):
        stretch_factor = self._bbox.height / self._bbox.width

        ny = int(stretch_factor*self._ribbonbox.nx)
        if self.get_array() is None or self.get_array().shape[0] != ny:
            arr = self._ribbonbox.get_stretched_image(stretch_factor)
            self.set_array(arr)

        super().draw(renderer, *args, **kwargs)

Criando o gráfico

Nesta etapa, criaremos o gráfico propriamente dito, usando a classe RibbonBoxImage para criar as caixas de fita.

def main():
    fig, ax = plt.subplots()

    years = np.arange(2004, 2009)
    heights = [7900, 8100, 7900, 6900, 2800]
    box_colors = [(0.8, 0.2, 0.2),
                  (0.2, 0.8, 0.2),
                  (0.2, 0.2, 0.8),
                  (0.7, 0.5, 0.8),
                  (0.3, 0.8, 0.7)]

    for year, h, bc in zip(years, heights, box_colors):
        bbox0 = Bbox.from_extents(year - 0.4, 0., year + 0.4, h)
        bbox = TransformedBbox(bbox0, ax.transData)
        ax.add_artist(RibbonBoxImage(ax, bbox, bc, interpolation="bicubic"))
        ax.annotate(str(h), (year, h), va="bottom", ha="center")

    ax.set_xlim(years[0] - 0.5, years[-1] + 0.5)
    ax.set_ylim(0, 10000)

    ## Create a background gradient
    background_gradient = np.zeros((2, 2, 4))
    background_gradient[:, :, :3] = [1, 1, 0]
    background_gradient[:, :, 3] = [[0.1, 0.3], [0.3, 0.5]]
    ax.imshow(background_gradient, interpolation="bicubic", zorder=0.1,
              extent=(0, 1, 0, 1), transform=ax.transAxes, aspect="auto")

    plt.show()

main()

Entendendo o gráfico

Nesta etapa, discutiremos o gráfico que criamos. O gráfico consiste em caixas de fita empilhadas umas sobre as outras para formar um gráfico de barras. A altura de cada caixa de fita corresponde a um valor no conjunto de dados. As caixas de fita possuem um esquema de cores gradiente que as torna visualmente atraentes.

Resumo

Neste tutorial, aprendemos como criar um gráfico de caixas de fita usando Matplotlib. Criamos as classes RibbonBox e RibbonBoxImage para criar as cores gradientes e as caixas de fita propriamente ditas, respectivamente. Em seguida, usamos essas classes para criar o gráfico, que consiste em caixas de fita empilhadas umas sobre as outras para formar um gráfico de barras.