2015-09-11 13 views
10

vorrei creare la mia propria mappa colore personalizzato in python, ho guardato in alcuni degli esempi online e ha scoperto i comandipersonalizzato mappa colori in Python

from matplotlib import cm 
import matplotlib.pyplot as plt 
from matplotlib.colors import LinearSegmentedColormap 

cdict1 = {'red': ((0.0, 0.0, 0.0), 
        (0.5, 0.0, 0.1), 
        (1.0, 1.0, 1.0)), 

     'green': ((0.0, 0.0, 0.0), 
        (1.0, 0.0, 0.0)), 

     'blue': ((0.0, 0.0, 1.0), 
        (0.5, 0.1, 0.0), 
        (1.0, 0.0, 0.0)) 
     } 

blue_red1 = LinearSegmentedColormap('BlueRed1', cdict1) 
plt.imshow(big,interpolation='nearest', cmap=blue_red1, aspect='auto') 
plt.colorbar() 
plt.show() 

Con il comando precedente ottengo una mappa a colori che è (Rosso - Nero - Blu), dove il rosso è massimo e il blu è minimo. Mi piacerebbe creare una mappa dei colori che sia (Nero - Bianco - Nero). Qualcuno potrebbe dirmi cosa dovrebbe essere fatto o qualsiasi altro metodo?

risposta

4

Si desidera che tutti e tre i componenti siano 0 su 0 e 1, e tutti e tre su 1 su 0,5. Quindi, si ha:

cdict1 = {'red': ((0.0, 0.0, 0.0), # <- at 0.0, the red component is 0 
        (0.5, 1.0, 1.0), # <- at 0.5, the red component is 1 
        (1.0, 0.0, 0.0)), # <- at 1.0, the red component is 0 

     'green': ((0.0, 0.0, 0.0), # <- etc. 
        (0.5, 1.0, 1.0), 
        (1.0, 0.0, 0.0)), 

     'blue': ((0.0, 0.0, 0.0), 
        (0.5, 1.0, 1.0), 
        (1.0, 0.0, 0.0)) 
     } 

enter image description here

2

Ho anche trovato creazione colormap confusione. Il LinearSegmentedColormap è bello perché è molto flessibile, ma ci vuole un po 'di tempo per abituarsi allo cdict.

La prima e forse la cosa più importante da fare in questo modo in questo modo è che capisci RGB colors. Fondamentalmente, ogni colore ha un valore di intensità da 0 a 1, e valori più alti danno più di quel colore. Nello spazio colori RGB, il bianco è rappresentato da tutti e tre i colori da 1 e il nero è tutti e tre i colori 0.

La seconda cosa che è importante imparare a creare i colori in questo modo è questa: rendere sempre il 2 ° e il 3 ° valore di ogni tupla lo stesso finché non si ha familiarità con la creazione di semplici mappe lineari. Alla fine puoi cambiare quei valori per creare discontinuità nelle mappe dei colori, ma ti confonderà solo all'inizio.

OK, quindi il primo valore in ogni tupla è la 'frazione' della mappa colori e questi devono passare da 0 a 1, il secondo e il terzo valore sono l'intensità per quel colore (limiti inferiore e superiore). Così, per fare un mappa dei colori che è 'nero-bianco-nero', si dovrebbe fare:

cdict1 = { 
    'red': ((0.0, 0.0, 0.0), 
       (0.5, 1.0, 1.0), 
       (1.0, 0.0, 0.0)), 

    'green': ((0.0, 0.0, 0.0), 
       (0.5, 1.0, 1.0), 
       (1.0, 0.0, 0.0)), 

    'blue': ((0.0, 0.0, 0.0), 
       (0.5, 1.0, 1.0), 
       (1.0, 0.0, 0.0)), 
     } 

black_white_black = LinearSegmentedColormap('BlackWhiteBlack', cdict1) 

Per esempio,

plt.imshow(np.arange(100).reshape(10,10), cmap=black_white_black, aspect='auto') 
plt.colorbar() 

Example Image

Good Luck!

1

Prova un cdict1 di

cdict1 = {'red': ((0.0, 0.0, 0.0), 
        (0.5, 1.0, 1.0), 
        (1.0, 0.0, 0.0)), 

     'green': ((0.0, 0.0, 0.0), 
        (0.5, 1.0, 1.0), 
        (1.0, 0.0, 0.0)), 

     'blue': ((0.0, 0.0, 0.0), 
        (0.5, 1.0, 1.0), 
        (1.0, 0.0, 0.0)) 
     } 

Questo dizionario descrive come i colori sono interpolati, guardando ogni componente rosso-verde-blu singolarmente. Per ogni componente gli viene fornita una lista di 3 tuple (x, y0, y1) che specificano come interpolare quel componente e ogni valore che si desidera viene interpolato tra due punti nell'elenco.

In questo caso, vogliamo iniziare con il nero [RGB = (0,0,0)], aumentare con il bianco [RGB = 1,1,1] a metà percorso dell'intervallo di dati e quindi diminuire indietro al nero alla fine.

Per ciascun valore per assegnare un colore, la mappa prima convertirà quel valore in una frazione dell'intervallo di input in modo che abbia qualcosa nell'intervallo [0, 1]. Per ottenere il livello del componente rosso, la mappa eseguirà la scansione del primo elemento di ogni tupla da 3 nella lista "rossa" e afferra il più grande senza superare la frazione. Il livello rosso assegnato sarà interpolato tra l'elemento y1 di quella tupla da 3 e l'elemento y0 della successiva tupla da 3, in base alla differenza di valore x.

E allo stesso modo per i componenti blu e verde.

7

Per quello che vale, c'è anche un metodo più semplice.

Il modulo completo di LinearSegmentedColormap offre la possibilità di avere stop e gradienti "duri" nella stessa mappa colori, quindi è necessariamente complesso. Tuttavia, esiste un costruttore di convenienza per casi semplici come quello che descrivi.

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.colors import LinearSegmentedColormap 

cmap = LinearSegmentedColormap.from_list('mycmap', ['black', 'white', 'black']) 

fig, ax = plt.subplots() 
im = ax.imshow(np.random.random((10, 10)), cmap=cmap, interpolation='nearest') 
fig.colorbar(im) 
plt.show() 

enter image description here