2011-06-27 15 views
8

El siguiente código de pitón crea un mapa de calor de una matriz que contiene los valores distribuidos normalmentede escala no lineal de un mapa de colores para mejorar el contraste

import numpy as np 
from matplotlib import pylab as plt 


np.random.seed(123) #make sure we all have same data 
m = np.random.randn(200).reshape(10, 20) 
plt.imshow(m, cmap='RdYlGn', interpolation='nearest') 
plt.colorbar() 

Ésta es la salida de este código

example 1

Me gustaría mejorar el contraste de esta imagen al "atenuar" los valores cercanos a cero. me puede hacer esto mediante el uso de la escala disigmoid de los datos originales de la siguiente manera:

def disigmoidScaling(values, steepnessFactor=1, ref=None): 
    ''' Sigmoid scaling in which values around a reference point are flattened 
    arround a reference point 

    Scaled value y is calculated as 
     y = sign(v - d)(1 - exp(-((x - d)/s)**2))) 
    where v is the original value, d is the referenc point and s is the 
    steepness factor 
    ''' 
    if ref is None: 
     mn = np.min(values) 
     mx = np.max(values) 
     ref = mn + (mx - mn)/2.0 

    sgn = np.sign(values - ref) 
    term1 = ((values - ref)/steepnessFactor) ** 2 
    term2 = np.exp(- term1) 
    term3 = 1.0 - term2 
    return sgn * term3 


plt.imshow(disigmoidScaling(m, 4), cmap='RdYlGn', interpolation='nearest') 
plt.colorbar() 

Aquí está la salida.

example 2

Estoy satisfecho con el resultado, salvo el hecho de que en esta versión los valores originales han sido intercambiados por los escalados.

¿Hay alguna manera de realizar un mapeo no lineal de valores en el mapa de colores?

+0

Esta pregunta también puede ser de interés aquí: https://stackoverflow.com/questions/46038206/arbirtrary-non-linear-colorbar-using-matplotlib – ImportanceOfBeingErnest

Respuesta

4

Un mapa de color contiene un diccionario de valores rojos, verdes y azules mapeados en el intervalo [0,1]. Los Linear Segmented Colormap docs clase dan el ejemplo

cdict = {'red': [(0.0, 0.0, 0.0), 
       (0.5, 1.0, 1.0), 
       (1.0, 1.0, 1.0)], 

    'green': [(0.0, 0.0, 0.0), 
       (0.25, 0.0, 0.0), 
       (0.75, 1.0, 1.0), 
       (1.0, 1.0, 1.0)], 

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

"Cada fila en la tabla para un color dado es una secuencia de x, y0, y1 tuplas. En cada secuencia, x debe aumentar monótonamente de 0 a 1. Para cualquier valor de entrada z comprendido entre x [i] yx [i + 1], el valor de salida de un color determinado se interpolará linealmente entre y1 [i] y y0 [i + 1]: "

El mapa de color RdYlGn ha 11 valores x para cada color que va de 0 a 1.0 en pasos de 0.1. Usted puede obtener los cdict valores llamando

plt.cm.RdYlGn._segmentdata 

continuación, puede cambiar los valores de x a todas las medidas que desee (siempre y cuando van en aumento y el rango de 0 a 1 monótonamente) y obtener un nuevo mapa de colores llamando matplotlib.colors.LinearSegmentedColormap en su nuevo cdict. Hay varios ejemplos excelentes de esto en el Matplotlib Cookbook.

Cuestiones relacionadas