¿Por qué mi barra de colores tiene líneas en ella?

Edit : dado que parece ser una publicación popular, aquí está la solución que parece funcionar bien para mí. Gracias @gazzar y @mfra.

cbar.solids.set_rasterized(True) cbar.solids.set_edgecolor("face") 

¿Alguien sabe por qué mi barra de colores tiene lo que parecen ser líneas? O más bien, ¿por qué la transición de color no es suave? Estoy usando un mapa base, obviamente, pero eso no debería importar ya que son todas las llamadas de matplotlib bajo el capó de AFAICT. Creo el mapa haciendo algo como

 grays = plt.cm.get_cmap("Grays") sc = mymap.scatter(xpoints, ypoints, s=sizes, c=color_values, cmap=grays, alpha=.75, marker="o", zorder=10, vmin=0, vmax=1) cbar = mymap.colorbar(sc, drawedges=True, location="bottom") 

Lo intenté sin y sin alfa y el resultado fue el mismo. Tal vez sea porque mi matriz color_values ​​no es lo suficientemente buena? ¿Puedo establecer los valores subyacentes que se asignan a la barra de colores en algún lugar? No veo cómo, y no veo este problema en otra parte. Es decir, puedo replicar el ejemplo de matplotlib show_colorbars sin este problema.

Ejemplo de barra de colores incorrecta

En caso de que cree gráficos vectoriales, ¿ha intentado esto (tomado de http://matplotlib.org/api/pyplot_api.html?highlight=colorbar#matplotlib.pyplot.colorbar ):

“Se sabe que algunos visores de gráficos vectoriales (svg y pdf) representan espacios en blanco entre los segmentos de la barra de colores. Esto se debe a errores en los visores, no en matplotlib. Como solución alternativa, la barra de colores se puede representar con segmentos superpuestos:

 cbar = colorbar() cbar.solids.set_edgecolor("face") draw() 

Sin embargo, esto tiene consecuencias negativas en otras circunstancias. Particularmente con las imágenes semitransparentes (alfa <1) y las extensiones de la barra de colores y no está habilitado de forma predeterminada, vea (número de problema 1188) ".

Por lo general, prefiero rasterizar los contenidos de la barra de colores para evitar este problema utilizando los consejos de Eric Firing agregando la siguiente línea.

 cbar.solids.set_rasterized(True) 

Esta solución supuestamente falla para imágenes con transparencia, pero para la mayoría de los casos normales produce el resultado deseado.

Parece que tu ttwig usa algunos valores transparentes (alfa). Estaba teniendo el mismo problema (ttwig semitransparente, pero quería que la barra de colores fuera sólida), ¡y esta pregunta y respuesta lo resolvieron para mí! Para referencia:

 cbar.set_alpha(1) cbar.draw_all() 

Probé ambas configuraciones dadas en los otros comentarios, a saber:

 cbar.solids.set_rasterized(True) cbar.solids.set_edgecolor("face") 

Y desafortunadamente ninguno de los dos trabajó para mí.

Así que probé un enfoque completamente diferente, que es un gran hack, pero al menos hace el trabajo. Cuando se pasa alpha a imshow se establece un valor alfa que se usará para mezclar con otras imágenes. Debido a razones de mayor poder (como lo mencionó @mfra) esto crea las líneas blancas que tanto despreciamos. Claramente, la clave entonces es no pasar un valor alfa para hacer una imshow . Sin embargo, todavía tenemos que crear de alguna manera la barra de colores.

Por lo tanto, como solución alternativa, podemos hacer la mezcla alfa por nosotros mismos antes de ofrecerle imshow de imshow para hacer una imshow . Como ejemplo, usemos el mapa de colores de winter :

 import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt xx, yy = np.meshgrid(np.linspace(-1, 1, 100), np.linspace(-1, 1, 100)) zz = xx**2 + yy**2 my_cmap_rgb = plt.get_cmap('winter')(np.arange(256)) alpha = 0.5 for i in range(3): # Do not include the last column! my_cmap_rgb[:,i] = (1 - alpha) + alpha*my_cmap_rgb[:,i] my_cmap = mpl.colors.ListedColormap(my_cmap_rgb, name='my_cmap') 

Aquí creo un nuevo mapa de my_cmap_rgb , my_cmap_rgb , basado en el winter y luego edito los canales no alfa (0, 1 y 2) para hacer la mezcla alfa. Entonces puedo simplemente usar este nuevo mapa de colores para trazar mi figura.

 f, ax = plt.subplots() cim = ax.imshow(zz, cmap=my_cmap) cbar = plt.colorbar(cim) ax.set_title("No lines and no transparency") 

Sin líneas y sin transparencia. Ahora compáralo con la imagen que obtendrías sin este truco:

 f, ax = plt.subplots() cim = ax.imshow(zz, cmap='winter', alpha=0.5) cbar = plt.colorbar(cim) ax.set_title("Lines and transparency") 

Líneas y transparencia.

Es evidente que el problema se resuelve si no necesita transparencia. Por otro lado, si necesita transparencia, hay una solución más. Primero debe trazar una imagen sin transparencia para obtener la barra de colores, y luego trazar una con transparencia, pero cuya barra de colores no se usará.

 f, ax = plt.subplots() cim = ax.imshow(zz, cmap=my_cmap) cbar = plt.colorbar(cim) plt.cla() # Clears axis ax.plot(50,50, 'ko') ax.imshow(zz, cmap='winter', alpha=0.5) ax.set_title("No lines and transparency") 

Esto da como resultado una imagen cuya barra de colores no tiene líneas y aún así conserva la transparencia. Si bien sigue siendo un ataque masivo, al menos ya no tenemos que soportar estas líneas.

Sin líneas y transparencia.

Tratar:

 cbar = mymap.colorbar(sc, drawedges=False, location="bottom") 

Ahora está bien documentado en la web (que pude encontrar), pero

 *drawedges* [ False | True ] If true, draw lines at color boundaries. 

(extraído de matplotlib/lib/matplotlib/colorbar.py ) Creo que al establecer los drawedges en True le está diciendo que dibuje esas líneas.

La siguiente puede ser otra solución, incluso si no es elegante.

 In [1]: children = cbar.ax.get_children() In [2]: children Out[2]: [, , , , , , , , , , , , , ] In [3]: obj = children[1] # Get the LineCollection object In [4]: obj.set_linewidth(0) 

Como ninguna de las otras sugerencias me funcionó, terminé eliminando el canal alfa de la instancia de la barra de colores:

 from matplotlib.colors import to_rgb lut = colorbar.solids.get_facecolor() bg_color = to_rgb('white') lut[:, :3] *= lut[:, 3:] lut[:, :3] += (1 - lut[:, 3:]) * bg_color lut[:, 3] = 1. colorbar.solids.set_facecolor(lut) 

La barra de colores tuvo que dibujarse una vez antes de poder acceder a los colores de la cara.