A visualização de dados é uma das melhores maneiras (se não a melhor) para analistas de dados e cientistas de dados representarem informações complexas e gerarem insights significativos. Para aproveitar ao máximo sua oportunidade de se comunicar com os interessados, compilei informações úteis sobre mapas de cores do Matplotlib.
Como você verá neste artigo, o Matplotlib é uma biblioteca extremamente versátil e extensível de visualização em Python. Ele oferece todas as opções, desde gráficos simples até visuais completamente interativos. Se você não está geralmente familiarizado com Python, recomendo que você se inscreva em nosso curso Introdução ao Python antes de começarmos para entender sua fundação. Pessoalmente, também mantenho o Cheat Sheet do Python à mão, pois é uma referência útil para funções comuns.
Escolhendo o Mapa de Cores Certo do Matplotlib
Uma das primeiras coisas a considerar é decidir entre escalas de cores sequenciais, divergentes ou categóricas. Outros fatores importantes a considerar ao escolher escalas de cores incluem a uniformidade perceptiva, ou seja, que diferenças iguais nos valores dos dados sejam percebidas como diferenças iguais na cor, e usar opções de escalas de cores amigáveis para daltônicos para tornar seus visuais acessíveis a todos os públicos.
Você também deve considerar diferentes padrões de domínio ao escolher escalas de cores. Por exemplo, diferentes tons de azul representam diferentes profundidades de água em estudos oceanográficos. Se você estiver em dúvida sobre a escala de cores certa para sua visualização, diferentes ferramentas e recursos estão disponíveis para orientação. Em particular, nosso próprio curso Introdução à Visualização de Dados com Matplotlib ajuda você a trabalhar através de muitos cenários.
/settingsdialog
Diferentes Escalas de Cores no Matplotlib
No Python, o módulo matplotlib.colormaps
fornece acesso às escalas de cores embutidas, o que ajuda você a selecionar o esquema mais adequado para seu projeto. A seguir estão as categorias mais comuns de opções:
Escalas de cores sequenciais
As colormaps sequenciais representam dados ordenados que progressem de valores baixos para altos. Elas transitam de tons claros para escuros, mostrando a magnitude dos dados em diferentes níveis. Um exemplo de uma colormap sequencial é em mapas de calor para dados de temperatura, onde cores mais claras representam temperaturas mais frias e tons mais escuros representam temperaturas mais quentes.
Suponha que você tenha um conjunto de dados com colunas de data e temperatura. O código a seguir criará um mapa de calor para a temperatura.
# Importar bibliotecas necessárias import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.colors as mcolors # Passo 1: Extrair informações de mês e dia da coluna de data calendar_data = temperature_data.copy() # Criar uma cópia para trabalhar calendar_data['Month'] = calendar_data['Date'].dt.strftime('%B') calendar_data['Day'] = calendar_data['Date'].dt.day # Passo 2: Definir a ordem dos meses para uma sequência de calendário natural month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] # Converter a coluna 'Month' para um tipo categórico com a ordem especificada calendar_data['Month'] = pd.Categorical(calendar_data['Month'], categories=month_names, ordered=True) # Passo 3: Pivotar os dados para criar uma tabela estruturada para o mapa de calor monthly_temperature_table = calendar_data.pivot(index='Month', columns='Day', values='Temperature') # Passo 4: Configurar o gráfico para o mapa de calor plt.figure(figsize=(12, 8)) # Definir uma normalização personalizada para o intervalo de temperatura (opcional) norm = mcolors.Normalize(vmin=15, vmax=35) # Criar o mapa de calor com uma colormap sequencial heatmap = plt.imshow(monthly_temperature_table, cmap='YlOrRd', aspect='auto', norm=norm) # Adicionar uma barra de cores para representar a temperatura colorbar = plt.colorbar(heatmap, orientation='horizontal') colorbar.set_label('Temperature (°C)', labelpad=10) # Nomear os eixos plt.xlabel('Day of the Month') plt.ylabel('Month') # Definir os ticks do eixo y para exibir nomes de meses em vez de números plt.yticks(ticks=np.arange(len(month_names)), labels=month_names) # Adicionar um título ao mapa de calor plt.title('Monthly Temperature Heatmap (Sequential Colormap)') # Exibir o gráfico plt.grid(False) plt.show()
Exemplo de visualização de colormaps sequenciais do Matplotlib. Imagem pelo Autor
Colormaps divergentes
Mapas de cores divergentes destacam dados com desvios de um valor central em ambas as direções. Os mapas de cores divergentes têm cores contrastantes para as direções positiva e negativa. Uma aplicação comum dos mapas de cores divergentes é em dados financeiros para representar lucro e perda.
# Definir 'Mês' como índice profit_loss_df.set_index('Month', inplace=True) # Definir o tamanho da figura plt.figure(figsize=(8, 4)) # Criar um mapa de cores divergente cmap = plt.cm.RdYlGn # Exibir os dados como um mapa de calor usando imshow im = plt.imshow(profit_loss_df.T, cmap=cmap, aspect='auto', vmin=-np.max(np.abs(profit_loss_data)), vmax=np.max(np.abs(profit_loss_data))) # Adicionar uma barra de cores com rótulo cbar = plt.colorbar(im) cbar.set_label('Profit/Loss ($)') # Adicionar anotações em cada célula for i, month in enumerate(profit_loss_df.index): plt.text(i, 0, f'{profit_loss_df.loc[month, "Profit/Loss"]:.2f}', ha='center', va='center', color='black') # Definir rótulos e ticks dos eixos x e y plt.xlabel('Month') plt.ylabel('') # Não é necessário rótulo para o eixo y plt.xticks(ticks=range(len(profit_loss_df.index)), labels=profit_loss_df.index, rotation=45) plt.yticks([]) # Ocultar os ticks do eixo y, pois temos apenas uma linha # Adicionar título plt.title('Profit/Loss Heatmap (Diverging Colormap)') # Ajustar o layout para melhor exibição plt.tight_layout() # Mostrar o gráfico plt.show()
Exemplo de visualização de mapa de cores divergente do Matplotlib. Imagem pelo Autor.
Mapas de cores cíclicos
Mapas de cores cíclicos são úteis para visualizar dados que representam um padrão repetitivo ou cíclico, como ângulos, fases de onda ou hora do dia. Um exemplo de um mapa de cores cíclico em ação é a visualização das fases de uma função periódica, como uma onda senoidal.
# Criar dados para uma onda senoidal x = np.linspace(0, 2 * np.pi, 100) # Valores X de 0 a 2π (um ciclo completo) y = np.sin(x) # Valores Y (seno de X) # Criar um gráfico e eixo plt.figure(figsize=(10, 6)) # Criar um gráfico de dispersão com um mapa de cores cíclico # Colorir pontos pela sua posição no ciclo da onda senoidal points = plt.scatter(x, y, c=x, cmap='twilight', edgecolor='black') # Adicionar uma barra de cores para mostrar a fase da onda cbar = plt.colorbar(points) cbar.set_label('Wave Phase (Radians)', rotation=270, labelpad=15) # Rotular os eixos plt.xlabel('Angle (Radians)') plt.ylabel('Sine Value') # Adicionar um título plt.title('Sine Wave with Cyclic Colormap (Twilight)') # Exibir o gráfico plt.grid(True) plt.show()
Exemplo de visualização de mapa de cores cíclico com Matplotlib. Imagem do Autor.
Mapas de cores qualitativos
Colormap qualitativas são ideais para representar dados categóricos sem uma ordem particular das categorias. Um caso de uso comum de colormaps qualitativas é um gráfico de pizza onde cada segmento representa uma categoria diferente que pode ser facilmente distinguida.
# Exemplo de dados categóricos categories = ['Category A', 'Category B', 'Category C', 'Category D', 'Category E'] values = [20, 35, 25, 10, 10] # Definir o tamanho do gráfico plt.figure(figsize=(8, 8)) # Definir um colormap qualitativo manualmente colors = ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3'] # Códigos hexadecimais de cores selecionadas manualmente # Criar um gráfico de pizza plt.pie(values, labels=categories, autopct='%1.1f%%', startangle=90, colors=colors) # Proporção equal garante que o pizza seja desenhado como um círculo plt.axis('equal') # Adicionar um título plt.title('Pie Chart with Qualitative Colormap') # Exibir o gráfico plt.show()
Exemplo de visualização de colormap qualitativo do Matplotlib. Imagem do Autor.
Colormaps Arco-Íris
Colormaps arco-íris como hsv
são usadas quando é necessário uma ampla gama de tons.
# Gerar dados cíclicos x = np.linspace(0, 2 * np.pi, 500) y = np.sin(x) # Criar um gráfico com colormap arco-íris plt.scatter(x, y, c=x, cmap='hsv', s=50) # Adicionar uma barra de cores plt.colorbar(label='Phase') # Adicionar rótulos e título plt.xlabel('Angle (radians)') plt.ylabel('Sine Value') plt.title('Cyclic Data Visualization using HSV Colormap') # Exibir o gráfico plt.show()
Exemplo de visualização de colormap arco-íris com Matplotlib. Imagem pelo Autor.
Colormaps uniformes perceptualmente
Colormaps como inferno
e plasma
oferecem melhor visibilidade em diferentes meios de exibição.
# Gerar dados de elevação sintéticos x = np.linspace(-5, 5, 100) y = np.linspace(-5, 5, 100) X, Y = np.meshgrid(x, y) Z = np.sin(np.sqrt(X**2 + Y**2)) * 100 # Dados de elevação # Plotar os dados de elevação usando o colormap 'plasma' plt.contourf(X, Y, Z, cmap='plasma') # Adicionar uma barra de cores plt.colorbar(label='Elevation (m)') # Adicionar título e rótulos plt.title('Topographic Map (Plasma Colormap)') plt.xlabel('X Coordinate') plt.ylabel('Y Coordinate') # Exibir o gráfico plt.show()
Exemplo de visualização de colormap perceptualmente uniforme do Matplotlib. Imagem do Autor.
Criando e Modificando Colormaps do Matplotlib
Embora o Matplotlib tenha uma ampla variedade de colormaps内置, há cenários onde você desejaria personalizar suas cores. As ferramentas chave para criar colormaps personalizados no Matplotlib são ListedColormap
e LinearSegmentedColormap
.
Criando um colormap personalizado com ListedColormap
ListedColormap
permite criar um colormap a partir de uma lista de cores específicas. Este método é útil ao atribuir cores específicas a categorias distintas em dados categóricos.
from matplotlib.colors import ListedColormap Dados categóricos categories = ['Category A', 'Category B', 'Category C', 'Category D'] values = [25, 40, 35, 30] Lista de cores personalizadas para o colormap (por exemplo, tons de azul, verde, vermelho e púrpura) custom_colors = ['#1f77b4', '#2ca02c', '#d62728', '#9467bd'] Criar um ListedColormap usando as cores personalizadas custom_cmap = ListedColormap(custom_colors) Definir o tamanho da figura plt.figure(figsize=(8, 6)) Criar um gráfico de barras com o colormap personalizado bars = plt.bar(categories, values, color=custom_cmap.colors) Adicionar um título plt.title('Bar Chart with Custom ListedColormap') Rotular os eixos plt.xlabel('Categories') plt.ylabel('Values') Exibir o gráfico plt.show()
Matplotlib colormap personalizado com ListedColormap. Imagem pelo Autor.
Criando um colormap personalizado com LinearSegmentedColormap
LinearSegmentedColormap
permite criar colormaps que transicionam suavemente entre cores. Isso é útil porque os dados contínuos frequentemente requerem mudanças degradê de cor. Aqui, também estou especificando o número de intervalos que quero para minha visualização.
from matplotlib.colors import LinearSegmentedColormap # Criar uma grelha de valores para uma função Gaussiana 2D x = np.linspace(-2, 2, 500) y = np.linspace(-2, 2, 500) X, Y = np.meshgrid(x, y) Z = np.exp(- (X**2 + Y**2)) # Definir um mapa de cores personalizado que transita do azul para o branco e para o vermelho colors = ['blue', 'white', 'red'] custom_cmap = LinearSegmentedColormap.from_list('blue_white_red', colors) # Ajustar o número de classes de cores (níveis discretos) # Especificar o número de níveis (ex, 10 para 10 bandas de cores distintas) num_classes = 10 levels = np.linspace(Z.min(), Z.max(), num_classes) # Definir o tamanho da figura plt.figure(figsize=(8, 6)) # Traçar a função Gaussiana 2D com o mapa de cores ajustado contour = plt.contourf(X, Y, Z, levels=levels, cmap=custom_cmap) # Adicionar uma barra de cores para mostrar as classes de cores discretas classes de cores discretas plt.colorbar(contour, label='Gaussian Function Value') # Adicionar rótulos para os eixos plt.xlabel('X') plt.ylabel('Y') # Adicionar um título plt.title(f'2D Gaussian with {num_classes} Discrete Color Classes') # Exibir o gráfico plt.show()
Matplotlib custom ajustando o número de classes de cores. Imagem do autor.
Personalização de intervalos de cores e intensidade
Você pode controlar a intensidade ou o intervalo de cores em uma colormap existente manipulando sua normalização ou fatiando-a para usar um subconjunto das cores disponíveis. No exemplo a seguir, os intervalos de cores são fatiados para mostrar temperaturas entre 16 e 40 graus Celsius.
# Configurar o gráfico para o mapa de calor plt.figure(figsize=(12, 8)) # Definir uma normalização personalizada para o intervalo de temperatura norm = mcolors.Normalize(vmin=16, vmax=40) # Criar o mapa de calor com uma colormap sequencial heatmap = plt.imshow(monthly_temperature_table, cmap='YlOrRd', aspect='auto', norm=norm) # Adicionar a barra de cores para representar a temperatura colorbar = plt.colorbar(heatmap, orientation='horizontal') colorbar.set_label('Temperature (°C)', labelpad=10) # Nomear os eixos plt.xlabel('Day of the Month') plt.ylabel('Month') # Definir os ticks do eixo y para exibir nomes de meses em vez de números plt.yticks(ticks=np.arange(len(month_names)), labels=month_names) # Adicionar um título ao mapa de calor plt.title('Monthly Temperature Heatmap (Sequential Colormap)') # Exibir o gráfico plt.grid(False) plt.show()
Customização de intervalos de cores e intensidade no Matplotlib. Imagem do Autor.
Combinando colormaps existentes
Você também pode combinar colormaps existentes misturando múltiplas colormaps para criar visualizações mais complexas.
from matplotlib.colors import LinearSegmentedColormap, Normalize # Criar dados sintéticos de elevação x = np.linspace(-180, 180, 500) # Longitude y = np.linspace(-90, 90, 250) # Latitude X, Y = np.meshgrid(x, y) Z = 5000 * np.sin(np.sqrt(X**2 + Y**2) * np.pi / 180) # Dados sintéticos de elevação # Definir as colormaps base ('viridis' e 'cividis') cmap1 = plt.get_cmap('viridis') cmap2 = plt.get_cmap('cividis') # Criar uma colormap personalizada misturando as duas colormaps base def blend_colormaps(cmap1, cmap2, blend_ratio=0.5): """Blend two colormaps together.""" c1 = cmap1(np.linspace(0, 1, 256)) c2 = cmap2(np.linspace(0, 1, 256)) blended_colors = (1 - blend_ratio) * c1 + blend_ratio * c2 return LinearSegmentedColormap.from_list('blended_cmap', blended_colors) # Criar a colormap misturada custom_cmap = blend_colormaps(cmap1, cmap2, blend_ratio=0.5) # Normalizar os dados para visualização norm = Normalize(vmin=-5000, vmax=5000) # Definir o tamanho da figura plt.figure(figsize=(12, 6)) # Plotar os dados sintéticos de elevação com a colormap misturada contour = plt.contourf(X, Y, Z, levels=100, cmap=custom_cmap, norm=norm) # Adicionar uma barra de cores para mostrar o mapeamento de cores misturadas plt.colorbar(contour, label='Elevation (meters)') # Adicionar rótulos para os eixos plt.xlabel('Longitude') plt.ylabel('Latitude') # Adicionar um título plt.title('Geographical Elevation Data with Blended Colormap (Viridis + Cividis)') # Exibir o gráfico plt.show()
Matplotlib Combinando colormaps existentes. Imagem do Autor.
Invertendo colormaps usando o sufixo _r
Você pode inverter qualquer colormap no Matplotlib adicionando o sufixo _r
no seu nome.
# Configurar o gráfico para o heatmap plt.figure(figsize=(12, 8)) # Criar uma normalização personalizada para o intervalo de cores norm = mcolors.Normalize(vmin=16, vmax=40) # Plotar o heatmap usando imshow com o colormap sequencial im = plt.imshow(monthly_temperature_table, cmap='YlOrRd_r', norm=norm, aspect='equal') # Adicionar uma barra de cores com orientação horizontal cbar = plt.colorbar(im, orientation='horizontal', pad=0.1) cbar.set_label('Temperature (°C)', labelpad=10) # Adicionar rótulos para os eixos plt.xlabel('Day of the Month') plt.ylabel('Month') # Definir os ticks do eixo y para exibir nomes de meses em vez de números plt.yticks(ticks=np.arange(len(month_names)), labels=month_names) # Adicionar um título plt.title('Temperature Heatmap (Sequential Colormap)') # Exibir o gráfico plt.show()
Matplotlib Invertendo colormaps usando o sufixo _r. Imagem do Autor.
Tratamento de Erros Comuns em Colormaps do Matplotlib
Quando trabalha com mapas de cores no Matplotlib, pode encontrar erros que afetam seu fluxo de trabalho. A seguir estão alguns desses erros e como solucioná-los.
AttributeError: o módulo ‘matplotlib’ não tem o atributo ‘colormaps’
Este erro ocorre quando você usa versões do Matplotlib anteriores a 3.4.0 para acessar matplotlib.colormaps
. O atributo colormaps foi introduzido no Matplotlib 3.4.0. Primeiro, verifique sua versão do Matplotlib usando o código abaixo para solucionar esse erro.
import matplotlib print(matplotlib.__version__)
Atualize usando o seguinte comando pip.
pip install --upgrade matplotlib
Se você encontrar problemas ao atualizar sua versão do Matplotlib, tente o seguinte método para acessar mapas de cores.
plt.get_cmap('viridis') # em vez de matplotlib.colormaps['viridis']
Atribuição incorreta de cores
Você pode experimentar atribuições de cor incorretas ao passar um valor fora do intervalo esperado ou quando a paleta de cores é aplicada incorretamente. A atribuição incorreta de cor também pode surgir se a paleta de cores é destinada a dados contínuos, mas é aplicada a dados categóricos ou vice-versa.
Para garantir que seus dados estejam dentro do intervalo esperado, sempre normalize ou escalone-os usando os parâmetros vmax
e vmin
.
import matplotlib.colors as mcolors # Crie um conjunto de dados de temperatura de exemplo data = np.random.rand(10, 10) * 100 # Ajuste o intervalo para corresponder aos seus dados # Crie uma instância de normalização de cor para escalonar os dados ao intervalo da paleta de cores norm = mcolors.Normalize(vmin=0, vmax=100) # Crie um mapa de calor usando a paleta de cores 'viridis' e a normalização especificada plt.imshow(data, cmap='viridis', norm=norm, interpolation='nearest') plt.colorbar() plt.show()
Para um controle mais fino, você pode definir explicitamente os limites de cor usando os parâmetros boundaries
ou norm
nas funções de plotagem.
Artifacts visuais e resultados inesperados
Quando se trabalha com dados discretos ou de baixa resolução, pode-se experimentar faixas de cor indesejadas, contraste excessivo ou sangramento de cor. O problema ocorre quando seus dados têm um intervalo limitado, mas são exibidos com uma colormap contínua.
Para resolver esse problema, use mais pontos de dados ou ajuste o número de níveis de cor para suavizar as transições.
# Aumente o número de bins na colormap cmap = plt.get_cmap('viridis', 256) plt.imshow(data, cmap=cmap)
Você pode dividir a colormap em níveis fixos para lidar com dados discretos, quando apropriado.
cmap = plt.get_cmap('inferno', 10) # Divida a colormap em 10 níveis discretos plt.imshow(data, cmap=cmap)
Também pode verificar as configurações de exibição e ajustar a resolução, especialmente ao salvar as visualizações, para evitar gráficos de baixa resolução
plt.savefig('plot.png', dpi=300) # Salve a figura com uma resolução mais alta
Distorção de cor devido ao clipping
Distorção de cor ocorre quando os dados contêm valores extremos fora do intervalo de cor esperado. Isso faz com que partes dos dados sejam cortadas e atribuídas a cor mínima ou máxima no colormap.
Para evitar a distorção de cor, ajuste os limites de cor usando vmin
e vmax
para corresponder ao intervalo dos seus dados, prevenindo o corte.
plt.imshow(data, cmap='plasma', vmin=0, vmax=100)
Você também deve usar escalonamento robusto para lidar com valores atípicos, definindo limites personalizados que excluem valores extremos.
import numpy as np robust_vmin, robust_vmax = np.percentile(data, [2, 98]) # Use percentis para remover valores atípicos extremos plt.imshow(data, cmap='inferno', vmin=robust_vmin, vmax=robust_vmax)
Colormap não está sendo exibido corretamente em gráficos 3D
Se há um problema com como os dados são mapeados na superfície 3D, os colormaps podem não mostrar corretamente nas visualizações 3D. Para resolver, certifique-se de que os dados do eixo z estão normalizados para se encaixar dentro do intervalo esperado do colormap. Além disso, use os limites apropriados do colormap para capturar o intervalo completo dos valores z.
from mpl_toolkits.mplot3d import Axes3D # Gerar dados de exemplo para um gráfico de superfície 3D X, Y = np.meshgrid(np.linspace(-5, 5, 50), np.linspace(-5, 5, 50)) Z = np.sin(np.sqrt(X**2 + Y**2)) # Criar um objeto de eixos 3D ax = plt.axes(projection='3d') # Plotar a superfície usando a paleta de cores 'viridis' e ajustando os limites de cor ax.plot_surface(X, Y, Z, cmap='viridis', vmin=np.min(Z), vmax=np.max(Z)) plt.show()
Conclusão
Escolher a paleta de cores certa é um passo importante, pois realmente afeta como os usuários veem e entendem seus dados. Na minha opinião, gastar muito tempo com análise de dados e ser descuidado na etapa final, que é a parte onde você comunica seus achados, é um grande erro.
Felizmente, o Matplotlib oferece muitas opções para garantir que seus visuaiscontem uma história convincente. Inscreva-se em nosso curso, Introdução à Visualização de Dados com Matplotlib, para se tornar um especialista. E se você é um usuário de Python que também usa Seaborn para visualização (é ótimo conhecer ambos), leia nosso Guia Rápido para Escolher Cores no Seaborn e complemente com nosso Introdução à Visualização de Dados com Seaborn curso.
Source:
https://www.datacamp.com/tutorial/matplotlib-colormaps