Matplotlib imshow – ‘acelera’ el cambio de color en ciertos rangos de valores

Actualmente estoy trabajando para trazar algunas tags sobre el eje x, y en la imagen, pero más del 95% de los puntos se ubican en el rango 0-0.2, mientras que menos del 10% se ubica en el rango 0.2-1.0. Al usar el mapa de colores ‘jet’ predeterminado, esto hace que casi todos los gráficos se muestren en azul, aunque existe una variación en el 95% de los datos que se vuelven visualmente inobservables.

¿Hay alguna manera de decirle a matplotlib que, por ejemplo, cuadruplique la velocidad a la que cambian los colores en el rango de 0.0-0.1, y escale el rango de 0.2-1.0 restante en consecuencia? Cualquier ayuda sería muy apreciada.

¡Gracias por adelantado!

EDITAR: Al ver esto es solo una representación visual, me di cuenta de que una opción que tengo es, en cambio, volver a escalar los datos en el rango de 0.2 hasta el valor que considere adecuado para que los cambios sean más visibles y luego crear el color manualmente. bar en consecuencia. Aun así, preferiría poder hacer el show de matplotlib de forma nativa si es posible.

En caso de que quiera enfatizar valores pequeños en sus datos en un gráfico de imagen, nunca cambiaría los datos en sí. Eso puede llevar a mucha confusión. En cambio, como dije en los comentarios, cambia el mapa de colores.

Las formas de hacerlo se documentan en el Tutorial de normalización de color de Matplotlib , así como aquí en SO. Especialmente este artículo y las respuestas son realmente ilustrativos de las posibilidades que uno tiene.

Combiné dos conceptos en el siguiente ejemplo para mostrar las opciones.

  • Una es volver a escalar el mapa de colores de manera que el valor que inicialmente estaba en el centro ( midpoint ) de su mapa de colores se reduzca. De esta manera, se agrega más variación entre 0 y el nuevo midpoint , mientras que todo lo anterior se estira. Uno puede pensar en esto como dos mapas lineales empalmados juntos.
  • La otra es simplemente usar una escala logarítmica de los colores.

Este es el código de ejemplo.

 import numpy as np import matplotlib import matplotlib.pyplot as plt import matplotlib.colors as colors def shiftedColorMap(cmap, start=0, midpoint=0.5, stop=1.0, name='shiftedcmap'): ''' function taken from https://stackoverflow.com/questions/7404116/... ...defining-the-midpoint-of-a-colormap-in-matplotlib Function to offset the "center" of a colormap. Useful for data with a negative min and positive max and you want the middle of the colormap's dynamic range to be at zero Input ----- cmap : The matplotlib colormap to be altered start : Offset from lowest point in the colormap's range. Defaults to 0.0 (no lower ofset). Should be between 0.0 and `midpoint`. midpoint : The new center of the colormap. Defaults to 0.5 (no shift). Should be between 0.0 and 1.0. In general, this should be 1 - vmax/(vmax + abs(vmin)) For example if your data range from -15.0 to +5.0 and you want the center of the colormap at 0.0, `midpoint` should be set to 1 - 5/(5 + 15)) or 0.75 stop : Offset from highets point in the colormap's range. Defaults to 1.0 (no upper ofset). Should be between `midpoint` and 1.0. ''' cdict = { 'red': [], 'green': [], 'blue': [], 'alpha': [] } # regular index to compute the colors reg_index = np.linspace(start, stop, 257) # shifted index to match the data shift_index = np.hstack([ np.linspace(0.0, midpoint, 128, endpoint=False), np.linspace(midpoint, 1.0, 129, endpoint=True) ]) for ri, si in zip(reg_index, shift_index): r, g, b, a = cmap(ri) cdict['red'].append((si, r, r)) cdict['green'].append((si, g, g)) cdict['blue'].append((si, b, b)) cdict['alpha'].append((si, a, a)) newcmap = matplotlib.colors.LinearSegmentedColormap(name, cdict) plt.register_cmap(cmap=newcmap) return newcmap x = np.linspace(-3, 3, num=601) X,Y = np.meshgrid(x,x) Z = np.sinc( (X*np.cos(1)+Y*np.sin(1))**2 +(-X*np.sin(1)+0.2*Y*np.cos(1))**2 )**2 orig_cmap = matplotlib.cm.viridis shifted_cmap = shiftedColorMap(orig_cmap, midpoint=0.05, name='shifted') fig = plt.figure(figsize=(4,9)) ax = [fig.add_subplot(3,1,n+1) for n in range(3)] # normal cmap im0 = ax[0].imshow(Z, interpolation="none", cmap=orig_cmap) fig.colorbar(im0, ax=ax[0]) ax[0].set_title('Default behavior (hard to see small values)', fontsize=10) #example using the custom shiftedColorMap function #taken from https://stackoverflow.com/questions/7404116/defining-the-midpoint-of-a-colormap-in-matplotlib im1 = ax[1].imshow(Z, interpolation="none", cmap=shifted_cmap) fig.colorbar(im1, ax=ax[1]) ax[1].set_title('Center of colormap shifted to 0.05', fontsize=10) #example using colors.LogNorm() #taken from http://matplotlib.org/users/colormapnorms.html im2 = ax[2].imshow(Z, interpolation="none", norm=colors.LogNorm(vmin=10e-5, vmax=Z.max()), cmap=orig_cmap) fig.colorbar(im2, ax=ax[2]) ax[2].set_title('Logarithmically scaled Colormap', fontsize=10) for axis in ax: axis.set_yticks([]) axis.set_xticks([]) plt.tight_layout() plt.show() 

productor

introduzca la descripción de la imagen aquí