Corso
La data visualization è uno dei modi migliori (se non il migliore) per analisti e data scientist di rappresentare informazioni complesse e generare insight significativi. Per aiutarti a comunicare al meglio con gli stakeholder, ho raccolto informazioni utili sulle colormap di Matplotlib.
Come vedrai in questo articolo, Matplotlib è una libreria di visualizzazione in Python estremamente versatile ed estensibile. Offre ogni opzione, dai grafici semplici ai visual interattivi completi. Se non hai familiarità con Python, ti consiglio di iscriverti al nostro corso Introduzione a Python prima di iniziare, così da comprenderne le basi. Personalmente, tengo anche a portata di mano il Python Cheat Sheet perché è un riferimento utile per le funzioni più comuni.
Scegliere la colormap giusta in Matplotlib
Una delle prime cose da valutare è la scelta tra colormap sequenziali, divergenti o categoriali. Altri fattori importanti nella scelta includono l’uniformità percettiva, ovvero che differenze uguali nei valori dei dati siano percepite come differenze uguali nel colore, e l’uso di opzioni adatte ai daltonici per rendere i tuoi visual accessibili a tutti.
Dovresti anche considerare gli standard del tuo dominio quando scegli le colormap. Ad esempio, in oceanografia diverse tonalità di blu rappresentano differenti profondità dell’acqua. Se non sei sicuro della colormap giusta per la tua visualizzazione, sono disponibili diversi strumenti e risorse per orientarti. In particolare, il nostro corso Introduzione alla Data Visualization con Matplotlib ti aiuta a lavorare su molti scenari.
Le diverse colormap in Matplotlib
In Python, il modulo matplotlib.colormaps fornisce accesso alle colormap integrate, aiutandoti a selezionare lo schema migliore per il tuo progetto. Le seguenti sono le categorie più comuni:
Colormap sequenziali
Le colormap sequenziali rappresentano dati ordinati che vanno da valori bassi ad alti. Passano da tonalità chiare a scure, mostrando la magnitudo dei dati a livelli differenti. Un esempio è la heatmap per i dati di temperatura, dove i colori più chiari rappresentano temperature più basse e le tonalità più scure temperature più alte.
Supponi di avere un dataset con colonne data e temperatura. Il seguente codice creerà una heatmap per 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()

Esempio di visualizzazione con colormap sequenziali in Matplotlib. Immagine dell’autore
Colormap divergenti
Le colormap divergenti mettono in evidenza dati con deviazioni da un valore centrale in entrambe le direzioni. Hanno colori a contrasto per le direzioni positiva e negativa. Un’applicazione comune è nei dati finanziari per rappresentare profitti e perdite.
# Set 'Month' as the index
profit_loss_df.set_index('Month', inplace=True)
# Set the figure size
plt.figure(figsize=(8, 4))
# Create a diverging colormap
cmap = plt.cm.RdYlGn
# Display the data as a heatmap using 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)))
# Add color bar with label
cbar = plt.colorbar(im)
cbar.set_label('Profit/Loss ($)')
# Add annotations to each cell
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')
# Set x-axis and y-axis labels and ticks
plt.xlabel('Month')
plt.ylabel('') # No label needed for y-axis
plt.xticks(ticks=range(len(profit_loss_df.index)), labels=profit_loss_df.index, rotation=45)
plt.yticks([]) # Hide y-axis ticks as we only have one row
# Add title
plt.title('Profit/Loss Heatmap (Diverging Colormap)')
# Adjust layout for better display
plt.tight_layout()
# Show plot
plt.show()

Esempio di visualizzazione con colormap divergente in Matplotlib. Immagine dell’autore.
Colormap cicliche
Le colormap cicliche sono utili per visualizzare dati che rappresentano un pattern ripetitivo o ciclico, come angoli, fasi d’onda o ore del giorno. Un esempio è la visualizzazione delle fasi di una funzione periodica, come un’onda sinusoidale.
# 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()

Esempio di visualizzazione con colormap ciclica in Matplotlib. Immagine dell’autore.
Colormap qualitative
Le colormap qualitative sono ideali per rappresentare dati categoriali senza un ordine particolare delle categorie. Un caso d’uso comune è il grafico a torta, in cui ogni segmento rappresenta una categoria diversa facilmente distinguibile.
# 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
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()

Esempio di visualizzazione con colormap qualitativa in Matplotlib. Immagine dell’autore.
Colormap arcobaleno
Le colormap arcobaleno come hsv si usano quando serve un’ampia gamma di tonalità.
# 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()

Esempio di visualizzazione con colormap arcobaleno in Matplotlib. Immagine dell’autore.
Colormap percettivamente uniformi
Colormap come inferno e plasma offrono migliore visibilità su diversi supporti di visualizzazione.
# 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()

Esempio di visualizzazione con colormap percettivamente uniforme in Matplotlib. Immagine dell’autore.
Creare e modificare le colormap in Matplotlib
Sebbene Matplotlib offra un’ampia varietà di colormap integrate, ci sono scenari in cui potresti voler personalizzare i colori. Gli strumenti chiave per creare colormap personalizzate in Matplotlib sono ListedColormap e LinearSegmentedColormap.
Creare una colormap personalizzata con ListedColormap
ListedColomap ti permette di creare una colormap da un elenco di colori specifici. Questo metodo è utile quando assegni colori specifici a categorie distinte in dati categoriali.
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()

Colormap personalizzata di Matplotlib con ListedColormap. Immagine dell’autore.
Creare una colormap personalizzata con LinearSegmentedColormap
LinearSegmentedColormap ti permette di creare colormap che passano gradualmente da un colore all’altro. È utile perché i dati continui richiedono spesso cambiamenti graduali. Qui specifico anche il numero di intervalli che voglio per il mio 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()

Matplotlib: personalizzazione del numero di classi di colore. Immagine dell’autore.
Personalizzare intervalli e intensità dei colori
Puoi controllare l’intensità o l’intervallo dei colori in una colormap esistente manipolandone la normalizzazione o selezionandone una sotto-porzione. Nell’esempio seguente, gli intervalli sono limitati per mostrare temperature tra 16 e 40 gradi 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: personalizzazione di intervalli e intensità dei colori. Immagine dell’autore.
Combinare colormap esistenti
Puoi anche combinare colormap esistenti fondendone più di una per creare visualizzazioni più complesse.
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: combinare colormap esistenti. Immagine dell’autore.
Invertire le colormap usando il suffisso _r
Puoi invertire qualsiasi colormap in Matplotlib aggiungendo il suffisso _r al suo nome.
# 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)
# Plot the heatmap using imshow with the sequential colormap
im = plt.imshow(monthly_temperature_table, cmap='YlOrRd_r', norm=norm, aspect='equal')
# Add a color bar with a horizontal orientation
cbar = plt.colorbar(im, orientation='horizontal', pad=0.1)
cbar.set_label('Temperature (°C)', labelpad=10)
# Add labels for 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
plt.title('Temperature Heatmap (Sequential Colormap)')
# Display the plot
plt.show()

Matplotlib: inversione delle colormap usando il suffisso _r. Immagine dell’autore.
Gestire gli errori comuni nelle colormap di Matplotlib
Lavorando con le colormap in Matplotlib, potresti incontrare errori che impattano il tuo flusso di lavoro. Ecco alcuni errori comuni e come risolverli.
AttributeError: module 'matplotlib' has no attribute 'colormaps’
Questo errore si verifica quando usi versioni di Matplotlib precedenti alla 3.4.0 per accedere a matplotlib.colormaps. L’attributo colormaps è stato introdotto in Matplotlib 3.4.0. Per prima cosa verifica la tua versione di Matplotlib con il codice sotto per risolvere l’errore.
import matplotlib
print(matplotlib.__version__)
Aggiorna usando il seguente comando pip.
pip install --upgrade matplotlib
Se riscontri problemi nell’aggiornare la versione di Matplotlib, prova il metodo seguente per accedere alle colormap.
plt.get_cmap('viridis') # instead of matplotlib.colormaps['viridis']
Assegnazioni di colore errate
Potresti incorrere in assegnazioni di colore errate quando passi un valore fuori dall’intervallo atteso o quando la colormap è applicata in modo scorretto. Ciò può accadere anche se la colormap è pensata per dati continui ma viene applicata a dati categoriali o viceversa.
Per assicurarti che i dati siano nell’intervallo atteso, normalizzali o scalali sempre usando i parametri vmax e 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()
Per un controllo più fine, puoi definire esplicitamente i confini di colore usando i parametri boundaries o norm nelle funzioni di plotting.
Artefatti visivi e risultati imprevisti
Con dati discreti o a bassa risoluzione, potresti vedere bande di colore indesiderate, contrasto eccessivo o “sbavature” di colore. Il problema si verifica quando i dati hanno un intervallo limitato ma sono mostrati con una colormap continua.
Per risolvere, usa più punti dati o regola il numero di livelli di colore per rendere più uniformi le transizioni.
# Increase the number of bins in the colormap
cmap = plt.get_cmap('viridis', 256)
plt.imshow(data, cmap=cmap)
Puoi suddividere la colormap in livelli fissi per gestire i dati discreti dove appropriato.
cmap = plt.get_cmap('inferno', 10) # Divide colormap into 10 discrete levels
plt.imshow(data, cmap=cmap)
Controlla anche le impostazioni di visualizzazione e regola la risoluzione, soprattutto quando salvi le visualizzazioni, per evitare grafici a bassa risoluzione
plt.savefig('plot.png', dpi=300) # Save the figure with a higher resolution
Distorsione del colore dovuta al clipping
La distorsione del colore si verifica quando i dati contengono valori estremi fuori dall’intervallo colore atteso. Ciò fa sì che alcune parti siano troncate e assegnate al colore minimo o massimo della colormap.
Per evitarla, regola i limiti di colore usando vmin e vmax per farli corrispondere all’intervallo dei tuoi dati, prevenendo il clipping.
plt.imshow(data, cmap='plasma', vmin=0, vmax=100)
Puoi anche usare uno scaling robusto per gestire gli outlier impostando limiti personalizzati che escludano i valori estremi.
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)
Colormap non visualizzata correttamente nei grafici 3D
Se c’è un problema nel mapping dei dati sulla superficie 3D, le colormap potrebbero non apparire correttamente nelle visualizzazioni 3D. Per risolvere, assicurati che i dati dell’asse z siano normalizzati per rientrare nell’intervallo atteso dalla colormap. Inoltre, usa limiti appropriati per catturare l’intero range dei valori 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()
Conclusione
Scegliere la colormap giusta è un passaggio importante perché influisce davvero su come gli utenti vedono e comprendono i tuoi dati. A mio parere, passare molto tempo sull’analisi dei dati ma essere approssimativi nell’ultimo passaggio, quello in cui comunichi i risultati, è un grande errore.
Per fortuna, Matplotlib offre molte opzioni per assicurarti che i tuoi visual raccontino una storia efficace. Iscriviti al nostro corso, Introduzione alla Data Visualization con Matplotlib, per diventare un esperto. Inoltre, se usi Python e anche Seaborn per le visualizzazioni (ottimo conoscerli entrambi), leggi la nostra Guida rapida alla scelta dei colori in Seaborn e continua con il corso Introduzione alla Data Visualization con Seaborn.
FAQ sulle colormap di Matplotlib
Qual è la colormap predefinita in Matplotlib?
La colormap predefinita in Matplotlib è viridis.
Come risolvo l’errore 'AttributeError: module 'matplotlib' has no attribute 'colormaps'?
Per risolvere l’errore AttributeError: module 'matplotlib' has no attribute 'colormaps', aggiorna la tua libreria Matplotlib a una versione successiva alla 3.4.0.
Come posso testare l’accessibilità delle colormap per utenti daltonici?
Puoi testare l’accessibilità delle colormap per utenti daltonici usando strumenti come Coblis (Color Blindness Simulator) o librerie di terze parti come palettable per simulare come le colormap appaiono a chi è daltonico.
Che cos’è una colormap percettivamente uniforme?
Una colormap percettivamente uniforme assicura che passi uguali nei dati producano cambiamenti percettivi uguali nel colore, consentendo un’interpretazione accurata della visualizzazione.
Posso usare colormap personalizzate da librerie esterne in Matplotlib?
Sì, librerie esterne come palettable o cmocean offrono colormap personalizzate che possono essere integrate con Matplotlib per esigenze di visualizzazione specializzate.


