curso
Matplotlib Colormaps: Personalizar tus combinaciones de colores
La visualización de datos es una de las mejores formas (si no la mejor) de que los analistas y científicos de datos representen información compleja y generen perspectivas significativas. Para aprovechar al máximo tu oportunidad de comunicarte con las partes interesadas, he recopilado información útil sobre los mapas de colores Matplotlib.
Como verás en este artículo, Matplotlib es una biblioteca de visualización en Python extremadamente versátil y extensible. Ofrece todas las opciones, desde simples gráficos hasta visuales totalmente interactivos. Si en general no estás familiarizado con Python, te animo a que te matricules en nuestro curso Introducción a Python antes de que empecemos para comprender sus fundamentos. Personalmente, también tengo cerca la Python Cheat Sheet porque es una referencia útil para las funciones más comunes.
Elegir el mapa de colores Matplotlib adecuado
Una de las primeras cosas a tener en cuenta es decidir entre mapas de colores secuenciales, divergentes o categóricos. Otros factores importantes que hay que tener en cuenta al elegir mapas de color son la uniformidad perceptiva, es decir, que diferencias iguales en los valores de los datos se perciban como diferencias iguales en el color, y el uso de opciones de mapas de color aptas para daltónicos para que tus visuales sean accesibles a todos los públicos.
También debes tener en cuenta las distintas normas de dominio al elegir los mapas de colores. Por ejemplo, diferentes tonos de azul representan diferentes profundidades del agua en los estudios oceanográficos. Si no estás seguro de cuál es el mapa de colores adecuado para tu visualización, tienes a tu disposición diferentes herramientas y recursos para orientarte. En particular, nuestro propio curso Introducción a la visualización de datos con Matplotlib te ayuda a trabajar en muchos escenarios.
Diferentes mapas de colores en Matplotlib
En Python, el módulo matplotlib.colormaps
proporciona acceso a mapas de colores incorporados, que te ayudan a seleccionar el mejor esquema para tu proyecto. A continuación se indican las categorías más comunes de opciones:
Mapas de colores secuenciales
Los mapas de colores secuenciales representan datos ordenados que progresan de valores bajos a altos. Pasan de tonos claros a oscuros, mostrando la magnitud de los datos en diferentes niveles. Un ejemplo de mapa de colores secuencial es el de los mapas térmicos para datos de temperatura, en los que los colores más claros representan temperaturas más frías y los tonos más oscuros, temperaturas más cálidas.
Supón que tienes un conjunto de datos con columnas de fecha y temperatura. El código siguiente creará un mapa de calor para la temperatura.
# Import required libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
# Step 1: Extract month and day information from the date column
calendar_data = temperature_data.copy() # Create a copy to work with
calendar_data['Month'] = calendar_data['Date'].dt.strftime('%B')
calendar_data['Day'] = calendar_data['Date'].dt.day
# Step 2: Define the order of months for a natural calendar sequence
month_names = ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December']
# Convert the 'Month' column to a categorical type with the specified order
calendar_data['Month'] = pd.Categorical(calendar_data['Month'], categories=month_names, ordered=True)
# Step 3: Pivot the data to create a structured table for the heatmap
monthly_temperature_table = calendar_data.pivot(index='Month', columns='Day', values='Temperature')
# Step 4: Set up the plot for the heatmap
plt.figure(figsize=(12, 8))
# Define a custom normalization for temperature range (optional)
norm = mcolors.Normalize(vmin=15, vmax=35)
# Create the heatmap with a sequential colormap
heatmap = plt.imshow(monthly_temperature_table, cmap='YlOrRd', aspect='auto', norm=norm)
# Add color bar to represent temperature
colorbar = plt.colorbar(heatmap, orientation='horizontal')
colorbar.set_label('Temperature (°C)', labelpad=10)
# Label the axes
plt.xlabel('Day of the Month')
plt.ylabel('Month')
# Set y-ticks to display month names instead of numbers
plt.yticks(ticks=np.arange(len(month_names)), labels=month_names)
# Add a title to the heatmap
plt.title('Monthly Temperature Heatmap (Sequential Colormap)')
# Display the plot
plt.grid(False)
plt.show()
Ejemplo de visualización de mapas de colores secuenciales Matplotlib. Imagen del autor
Mapas de colores divergentes
Los mapas de colores divergentes resaltan los datos con desviaciones de un valor central en ambas direcciones. Los mapas de colores divergentes tienen colores contrastados para las direcciones positiva y negativa. Una aplicación habitual de los mapas de colores divergentes es en los datos financieros para representar pérdidas y ganancias.
# Set 'Month' as the index
monthly_profit_loss_data.set_index('Month', inplace=True)
# Set the figure size
plt.figure(figsize=(8, 4))
# Create a diverging heatmap using Seaborn
# Use 'RdYlGn' colormap for diverging colors (Red for loss, Green for profit)
sns.heatmap(monthly_profit_loss_data.T, cmap='RdYlGn', center=0, annot=True, fmt='.0f', cbar_kws={'label': 'Profit/Loss ($)'})
# Add labels for the axes
plt.xlabel('Month')
plt.ylabel('')
# Add a title
plt.title('Profit/Loss Heatmap (Diverging Colormap)')
# Display the plot
plt.show()
Ejemplo de visualización de mapa de colores divergentes Matplotlib. Imagen del autor.
Mapas de colores cíclicos
Los mapas de colores cíclicos son útiles para visualizar datos que representan un patrón repetitivo o cíclico, como los ángulos, las fases de las olas o la hora del día. Un ejemplo de mapa de colores cíclico en acción es la visualización de las fases de una función periódica, como una onda sinusoidal.
# Create data for a sine wave
x = np.linspace(0, 2 * np.pi, 100) # X values from 0 to 2π (one complete cycle)
y = np.sin(x) # Y values (sine of X)
# Create a figure and axis
plt.figure(figsize=(10, 6))
# Create a scatter plot with a cyclic colormap
# Color points by their position in the sine wave cycle
points = plt.scatter(x, y, c=x, cmap='twilight', edgecolor='black')
# Add a color bar to show the phase of the wave
cbar = plt.colorbar(points)
cbar.set_label('Wave Phase (Radians)', rotation=270, labelpad=15)
# Label the axes
plt.xlabel('Angle (Radians)')
plt.ylabel('Sine Value')
# Add a title
plt.title('Sine Wave with Cyclic Colormap (Twilight)')
# Display the plot
plt.grid(True)
plt.show()
Ejemplo de visualización de mapa de colores cíclico Matplotlib. Imagen del autor.
Mapas de colores cualitativos
Los mapas de colores cualitativos son ideales para representar datos categóricos sin un orden determinado de las categorías. Un caso de uso común de los mapas de colores cualitativos es un gráfico circular en el que cada segmento representa una categoría diferente que puede distinguirse fácilmente.
# Sample categorical data
categories = ['Category A', 'Category B', 'Category C', 'Category D', 'Category E']
values = [20, 35, 25, 10, 10]
# Set the figure size
plt.figure(figsize=(8, 8))
# Define a qualitative colormap manually (similar to 'Set3' in Seaborn)
colors = ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3'] # Manually selected color hex codes
# Create a pie chart
plt.pie(values, labels=categories, autopct='%1.1f%%', startangle=90, colors=colors)
# Equal aspect ratio ensures the pie is drawn as a circle
plt.axis('equal')
# Add a title
plt.title('Pie Chart with Qualitative Colormap')
# Display the chart
plt.show()
Ejemplo de visualización cualitativa de mapa de colores Matplotlib. Imagen del autor.
Mapas de colores arco iris
Los mapas de colores arco iris como hsv
se utilizan cuando se necesita una amplia gama de tonos.
# Generate cyclic data
x = np.linspace(0, 2 * np.pi, 500)
y = np.sin(x)
# Create a plot with rainbow colormap
plt.scatter(x, y, c=x, cmap='hsv', s=50)
# Add a color bar
plt.colorbar(label='Phase')
# Add labels and title
plt.xlabel('Angle (radians)')
plt.ylabel('Sine Value')
plt.title('Cyclic Data Visualization using HSV Colormap')
# Display the plot
plt.show()
Ejemplo de visualización del mapa de colores del arco iris de Matplotlib. Imagen del autor.
Mapas de colores perceptualmente uniformes
Los mapas de colores como inferno
y plasma
ofrecen una mejor visibilidad en diferentes soportes de visualización.
# Generate synthetic elevation data
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 # Elevation data
# Plot the elevation data using the 'plasma' colormap
plt.contourf(X, Y, Z, cmap='plasma')
# Add a color bar
plt.colorbar(label='Elevation (m)')
# Add title and labels
plt.title('Topographic Map (Plasma Colormap)')
plt.xlabel('X Coordinate')
plt.ylabel('Y Coordinate')
# Display the plot
plt.show()
Ejemplo de visualización de mapa de colores perceptualmente uniforme con Matplotlib. Imagen del autor.
Crear y modificar mapas de colores Matplotlib
Aunque Matplotlib tiene una amplia variedad de mapas de colores incorporados, hay situaciones en las que querrás personalizar tus colores. Las herramientas clave para crear mapas de colores personalizados en Matplotlib son ListedColormap
y LinearSegmentedColormap
.
Crear un mapa de colores personalizado con ListedColormap
ListedColomap
te permite crear un mapa de colores a partir de una lista de colores específicos. Este método es útil para asignar colores específicos a categorías distintas en datos categóricos.
from matplotlib.colors import ListedColormap
# Categorical data
categories = ['Category A', 'Category B', 'Category C', 'Category D']
values = [25, 40, 35, 30]
# Custom color list for the colormap (e.g., shades of blue, green, red, and purple)
custom_colors = ['#1f77b4', '#2ca02c', '#d62728', '#9467bd']
# Create a ListedColormap using the custom colors
custom_cmap = ListedColormap(custom_colors)
# Set the figure size
plt.figure(figsize=(8, 6))
# Create a bar plot with the custom colormap
bars = plt.bar(categories, values, color=custom_cmap.colors)
# Add a title
plt.title('Bar Chart with Custom ListedColormap')
# Label the axes
plt.xlabel('Categories')
plt.ylabel('Values')
# Display the plot
plt.show()
Mapa de colores personalizado Matplotlib con ListedColormap. Imagen del autor.
Crear un mapa de colores personalizado con LinearSegmentedColormap
LinearSegmentedColormap
te permite crear mapas de color que pasen suavemente de un color a otro. Merece la pena saberlo, porque los datos continuos a menudo requieren cambios de color gradientes. Aquí también especifico el número de intervalos que quiero para mi visual.
from matplotlib.colors import LinearSegmentedColormap
# Create a grid of values for a 2D Gaussian function
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))
# Define a custom colormap that transitions from blue to white to red
colors = ['blue', 'white', 'red']
custom_cmap = LinearSegmentedColormap.from_list('blue_white_red', colors)
# Adjust the number of color classes (discrete levels)
# Specify the number of levels (e.g., 10 for 10 distinct color bands)
num_classes = 10
levels = np.linspace(Z.min(), Z.max(), num_classes)
# Set the figure size
plt.figure(figsize=(8, 6))
# Plot the 2D Gaussian function with the adjusted colormap
contour = plt.contourf(X, Y, Z, levels=levels, cmap=custom_cmap)
# Add a color bar to show the discrete color classes
plt.colorbar(contour, label='Gaussian Function Value')
# Add labels for the axes
plt.xlabel('X')
plt.ylabel('Y')
# Add a title
plt.title(f'2D Gaussian with {num_classes} Discrete Color Classes')
# Display the plot
plt.show()
Ajuste personalizado de Matplotlib del número de clases de color. Imagen del autor.
Personaliza las gamas de color y la intensidad
Puedes controlar la intensidad o la gama de colores de un mapa de colores existente manipulando su normalización o troceándolo para utilizar un subconjunto de los colores disponibles. En el ejemplo siguiente, las gamas de colores se cortan para mostrar temperaturas entre 16 y 40 grados Celsius.
# Set up the plot for the heatmap
plt.figure(figsize=(12, 8))
# Define a custom normalization for temperature range
norm = mcolors.Normalize(vmin=16, vmax=40)
# Create the heatmap with a sequential colormap
heatmap = plt.imshow(monthly_temperature_table, cmap='YlOrRd', aspect='auto', norm=norm)
# Add color bar to represent temperature
colorbar = plt.colorbar(heatmap, orientation='horizontal')
colorbar.set_label('Temperature (°C)', labelpad=10)
# Label the axes
plt.xlabel('Day of the Month')
plt.ylabel('Month')
# Set y-ticks to display month names instead of numbers
plt.yticks(ticks=np.arange(len(month_names)), labels=month_names)
# Add a title to the heatmap
plt.title('Monthly Temperature Heatmap (Sequential Colormap)')
# Display the plot
plt.grid(False)
plt.show()
Matplotlib personalizando las gamas de color y la intensidad. Imagen del autor.
Combinar mapas de colores existentes
También puedes combinar mapas de colores existentes mezclando varios mapas de colores para crear visualizaciones más complejas.
from matplotlib.colors import LinearSegmentedColormap, Normalize
# Create synthetic elevation data
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) # Synthetic elevation data
# Define the base colormaps ('viridis' and 'cividis')
cmap1 = plt.get_cmap('viridis')
cmap2 = plt.get_cmap('cividis')
# Create a custom colormap by blending the two base colormaps
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)
# Create the blended colormap
custom_cmap = blend_colormaps(cmap1, cmap2, blend_ratio=0.5)
# Normalize the data for visualization
norm = Normalize(vmin=-5000, vmax=5000)
# Set the figure size
plt.figure(figsize=(12, 6))
# Plot the synthetic elevation data with the blended colormap
contour = plt.contourf(X, Y, Z, levels=100, cmap=custom_cmap, norm=norm)
# Add a color bar to show the blended color mapping
plt.colorbar(contour, label='Elevation (meters)')
# Add labels for the axes
plt.xlabel('Longitude')
plt.ylabel('Latitude')
# Add a title
plt.title('Geographical Elevation Data with Blended Colormap (Viridis + Cividis)')
# Display the plot
plt.show()
Matplotlib Combinar mapas de colores existentes. Imagen del autor.
Invertir mapas de colores con el sufijo _r
Puedes invertir cualquier mapa de colores en Matplotlib añadiendo el sufijo _r
en su nombre.
# Import required libraries
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
# Set up the plot for the heatmap
plt.figure(figsize=(12, 8))
# Create a custom normalization for the color range
norm = mcolors.Normalize(vmin=16, vmax=40)
# Set the figure size
plt.figure(figsize=(12, 8))
# Create a heatmap with a sequential colormap
ax = sns.heatmap(temperature_pivot, cmap='YlOrRd_r', cbar=True, square=True, norm=norm, cbar_kws={'orientation': 'horizontal'})
# Add labels for the axes
plt.xlabel('Day of the Month')
plt.ylabel('Month')
# Add a color bar label (temperature in °C)
colorbar = ax.collections[0].colorbar
colorbar.set_label('Temperature (°C)', labelpad=10)
# Add a title
plt.title('Temperature Heatmap (Sequential Colormap)')
# Display the plot
plt.show()
Matplotlib Invertir mapas de colores utilizando el sufijo _r. Imagen del autor.
Errores comunes en los mapas de colores de Matplotlib
Al trabajar con mapas de colores en Matplotlib, puedes encontrarte con errores que afecten a tu flujo de trabajo. A continuación se indican algunos de los errores y cómo solucionarlos.
AttributeError: module 'matplotlib' has no attribute 'colormaps'
Este error se produce cuando utilizas versiones de Matplotlib anteriores a la 3.4.0 para acceder a matplotlib.colormaps
. El atributo colormaps se introdujo en Matplotlib 3.4.0. En primer lugar, comprueba tu versión de Matplotlib utilizando el código siguiente para solucionar este error.
import matplotlib
print(matplotlib.__version__)
Actualiza utilizando el siguiente comando pip.
pip install --upgrade matplotlib
Si tienes problemas para actualizar tu versión de Matplotlib, prueba el siguiente método para acceder a los mapas de colores.
plt.get_cmap('viridis') # instead of matplotlib.colormaps['viridis']
Asignación incorrecta de colores
Puedes experimentar asignaciones de color incorrectas cuando pases un valor fuera del rango esperado o cuando el mapa de color se aplique incorrectamente. También puede producirse una asignación incorrecta de colores si el mapa de colores está pensado para datos continuos, pero se aplica a datos categóricos o viceversa.
Para asegurarte de que tus datos están dentro del rango esperado, normalízalos o escálalos siempre utilizando los parámetros vmax
y vmin
.
import matplotlib.colors as mcolors
# Create a sample temperature dataset
data = np.random.rand(10, 10) * 100 # Adjust the range to match your data
# Create a color normalization instance to scale the data to the colormap's range
norm = mcolors.Normalize(vmin=0, vmax=100)
# Create a heatmap using the 'viridis' colormap and the specified normalization
plt.imshow(data, cmap='viridis', norm=norm, interpolation='nearest')
plt.colorbar()
plt.show()
Para un control más fino, puedes definir explícitamente los límites de color utilizando los parámetros boundaries
o norm
en las funciones de trazado.
Artefactos visuales y resultados inesperados
Cuando trabajes con datos discretos o de baja resolución, puedes experimentar bandas de color no deseadas, contraste excesivo o sangrado de color. El problema se produce cuando tus datos tienen un rango limitado pero se muestran con un mapa de colores continuo.
Para resolver este problema, utiliza más puntos de datos o ajusta el número de niveles de color para suavizar las transiciones.
# Increase the number of bins in the colormap
cmap = plt.get_cmap('viridis', 256)
plt.imshow(data, cmap=cmap)
Puedes dividir el mapa de colores en niveles fijos para manejar datos discretos cuando proceda.
cmap = plt.get_cmap('inferno', 10) # Divide colormap into 10 discrete levels
plt.imshow(data, cmap=cmap)
También puedes comprobar la configuración de la pantalla y ajustar la resolución, especialmente al guardar las visualizaciones, para evitar gráficos de baja resolución.
plt.savefig('plot.png', dpi=300) # Save the figure with a higher resolution
Distorsión del color por recorte
La distorsión del color se produce cuando los datos contienen valores extremos fuera de la gama de colores esperada. Esto hace que se recorten partes de los datos y se les asigne el color mínimo o máximo del mapa de colores.
Para evitar la distorsión del color, ajusta los límites de color mediante vmin
y vmax
para que coincidan con la gama de tus datos, evitando el recorte.
plt.imshow(data, cmap='plasma', vmin=0, vmax=100)
También debes utilizar un escalado robusto para manejar los valores atípicos, estableciendo límites personalizados que excluyan los valores extremos.
import numpy as np
robust_vmin, robust_vmax = np.percentile(data, [2, 98]) # Use percentiles to remove extreme outliers
plt.imshow(data, cmap='inferno', vmin=robust_vmin, vmax=robust_vmax)
El mapa de colores no se muestra correctamente en los gráficos 3D
Si hay un problema con el modo en que se mapean los datos en la superficie 3D, es posible que los mapas de color no se muestren correctamente en las visualizaciones 3D. Para solucionarlo, asegúrate de que los datos del eje z están normalizados para ajustarse al rango esperado del mapa de colores. Utiliza también los límites de mapa de color adecuados para capturar toda la gama de valores z.
from mpl_toolkits.mplot3d import Axes3D
# Generate sample data for a 3D surface plot
X, Y = np.meshgrid(np.linspace(-5, 5, 50), np.linspace(-5, 5, 50))
Z = np.sin(np.sqrt(X**2 + Y**2))
# Create a 3D axes object
ax = plt.axes(projection='3d')
# Plot the surface using the 'viridis' colormap and adjusting the color limits
ax.plot_surface(X, Y, Z, cmap='viridis', vmin=np.min(Z), vmax=np.max(Z))
plt.show()
Conclusión
Elegir el mapa de colores adecuado es un paso importante porque afecta realmente a la forma en que los usuarios ven y comprenden tus datos. En mi opinión, dedicar mucho tiempo al análisis de datos y ser descuidado en el último paso, que es la parte en la que comunicas tus conclusiones, es un gran error.
Por suerte, Matplotlib ofrece muchas opciones para que tus visuales cuenten una historia convincente. Inscríbete en nuestro curso, Introducción a la visualización de datos con Matplotlib, para convertirte en un experto. Además, si eres un usuario de Python que también utiliza Seaborn para la visualización (es estupendo conocer ambos), lee nuestra Guía rápida para elegir colores en Seaborn y síguela con nuestro curso Introducción a la visualización de datos con Seaborn.
Preguntas frecuentes sobre mapas de colores Matplotlib
¿Cuál es el mapa de colores por defecto en Matplotlib?
El mapa de colores por defecto en Matplotlib es viridis
.
¿Cómo corrijo el error 'AttributeError: module 'matplotlib' has no attribute 'colormaps'?
Para solucionar el error AttributeError: module 'matplotlib' has no attribute 'colormaps'
, actualiza tu biblioteca Matplotlib a una versión posterior a la 3.4.0.
¿Cómo puedo comprobar la accesibilidad del mapa de colores para usuarios daltónicos?
Puedes probar la accesibilidad de los mapas de color para los usuarios daltónicos utilizando herramientas como Coblis (Simulador de daltonismo) o bibliotecas de terceros como palettable
para simular cómo aparecen los mapas de color para los espectadores daltónicos.
¿Qué es un mapa de colores perceptualmente uniforme?
Un mapa de colores perceptualmente uniforme garantiza que pasos iguales en los datos den lugar a cambios perceptuales iguales en el color, lo que permite una interpretación precisa de la visualización.
¿Puedo utilizar mapas de colores personalizados de bibliotecas externas en Matplotlib?
Sí, bibliotecas externas como palettable
o cmocean
ofrecen mapas de colores personalizados que pueden integrarse con Matplotlib para necesidades de visualización especializadas.
Aprende Python y Visualización de Datos con DataCamp
curso
Introduction to NumPy
curso
Introduction to Python
tutorial
Histogramas en Matplotlib
tutorial
Introducción al trazado con Matplotlib en Python
Kevin Babitz
25 min
tutorial
Gráficos lineales en MatplotLib con Python
tutorial
Gráfico lineal de series temporales Matplotlib
tutorial
Tipos de gráficos de datos y cómo crearlos en Python
tutorial