pcolormesh con valores inválidos enmascarados

Estoy tratando de trazar una matriz unidimensional como una pcolormesh (por lo que el color varía a lo largo del eje x, pero es constante en el eje y para cada x). Pero mis datos tienen algunos valores incorrectos, así que estoy usando una matriz enmascarada y un mapa de colores personalizado con valores enmascarados establecidos en azul:

import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm import copy a = np.array([3, 5, 10, np.inf, 5, 8]) a = np.ma.masked_where(np.isinf(a), a) imdata = np.vstack((a, a)) myhot = copy.copy(cm.hot) myhot.set_bad('b', 1) fig, ax = plt.subplots() im = ax.pcolormesh(imdata, cmap=myhot) plt.colorbar(im) plt.show() 

Funciona bien si no tengo el valor np.inf , pero si lo hago, solo obtengo un gráfico en blanco. Parece que he entendido mal algo acerca de la forma en que funciona set_bad porque recibo una advertencia adicional:

 RuntimeWarning: invalid value encountered in true_divide resdat /= (vmax - vmin) 

¿Qué debo hacer para obtener el efecto que quiero?

Necesitas enmascarar imdata , no necesariamente a

 import numpy as np import matplotlib.pyplot as plt a = np.array([3, 5, 10, np.inf, 5, 8]) imdata = np.ma.masked_invalid(np.atleast_2d(a)) cmap = plt.cm.hot cmap.set_bad('b', 1) fig, ax = plt.subplots() im = ax.pcolormesh(imdata, cmap=cmap) plt.colorbar(im) plt.show() 

introduzca la descripción de la imagen aquí


Si imdata en una sesión interactiva, verás

 In [185]: imdata Out[185]: masked_array(data = [[ 3. 5. 10. inf 5. 8.] [ 3. 5. 10. inf 5. 8.]], mask = False, fill_value = 1e+20) 

Arriba, mask=False significa que nada está enmascarado. Si envuelve eso con np.ma.masked_invalid entonces:

 In [186]: np.ma.masked_invalid(imdata) Out[186]: masked_array(data = [[3.0 5.0 10.0 -- 5.0 8.0] [3.0 5.0 10.0 -- 5.0 8.0]], mask = [[False False False True False False] [False False False True False False]], fill_value = 1e+20) 

El problema con la máscara a es que np.vstack no respeta la máscara. Alternativamente, podrías haber usado np.ma.vstack . En términos generales, solo las funciones en el espacio de nombres np.ma respetan la máscara.

Sin embargo, no es necesario usar vstack aquí; np.atleast_2d hará. vstack crea una matriz de forma (2, N) , mientras que np.atleast_2d crea una matriz de forma (1, N) .


Otra alternativa es usar set_over lugar de set_bad . Esto le permitiría evitar la necesidad de una matriz enmascarada por completo:

 import numpy as np import matplotlib.pyplot as plt a = np.array([3, 5, 10, np.inf, 5, 8]) imdata = np.atleast_2d(a) cmap = plt.cm.hot cmap.set_over('b') cmap.set_under('g') fig, ax = plt.subplots() b = a[np.isfinite(a)] im = ax.pcolormesh(imdata, cmap=cmap, vmin=b.min(), vmax=b.max()) plt.colorbar(im, extend='both') plt.show() 

introduzca la descripción de la imagen aquí

La extend='both' junto con set_over y set_under dan flechas de colores pequeños en la barra de colores que indican el color utilizado para los valores más allá del rango de la barra de colores.