Gráfico de barras en matplotlib usando un mapa de colores
Tengo un df con dos columnas:
- y: diferentes valores numéricos para el eje y
- días: los nombres de cuatro días diferentes (lunes, martes, miércoles, jueves)
También tengo un mapa de colores con cuatro colores diferentes que hice yo mismo y es un objeto ListedColorMap.
Quiero crear un gráfico de barras con las cuatro categorías (días de la semana) en el eje xy sus valores correspondientes en el eje y. Al mismo tiempo, quiero que cada barra tenga un color diferente usando mi mapa de colores.
Este es el código que utilicé para construir mi gráfico de barras:
def my_barchart(my_df, my_cmap):
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
ax.bar(my_df['days'], my_df['y'], color=my_cmap)
return fig
Sin embargo, aparece el siguiente error: "el objeto de tipo 'ListedColormap' no tiene len ()", así que parece que no estoy usando my_cmap correctamente.
Si elimino eso de la función y lo ejecuto, mi gráfico de barras se ve bien, excepto que todas las barras tienen el mismo color. Entonces, mi pregunta es: ¿cuál es la forma correcta de usar un mapa de colores con un gráfico de barras?
Respuestas
El colorargumento quiere una cadena o un valor RGB [A] (puede ser un solo color o una secuencia de colores con uno para cada punto de datos que está trazando). Los mapas de color se pueden llamar típicamente con flotantes en el rango [0, 1].
Entonces, lo que desea hacer es tomar los valores que desea para los colores de cada barra, escalarlos al rango [0, 1] y luego llamar my_cmapcon esos valores reescalados.
Entonces, digamos, por ejemplo, que desea que los colores se correspondan con los valores de y (alturas de las barras), entonces debe modificar su código de esta manera (supone que ha llamado import numpy as npanteriormente):
def my_barchart(my_df, my_cmap):
rescale = lambda y: (y - np.min(y)) / (np.max(y) - np.min(y))
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
ax.bar(my_df['days'], my_df['y'], color=my_cmap(rescale(my_df['y'])))
return fig
Aquí hay un ejemplo mínimo autónomo del uso del colorargumento con la salida de a cmap:
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
my_cmap = plt.get_cmap("viridis")
rescale = lambda y: (y - np.min(y)) / (np.max(y) - np.min(y))
plt.bar(x, y, color=my_cmap(rescale(y)))
plt.savefig("temp")
Salida:
De acuerdo, encontré una manera de hacer esto sin tener que escalar mis valores:
def my_barchart(my_df, my_cmap):
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
ax.bar(my_df['days'], my_df['y'], color=my_cmap.colors)
return fig
¡Simplemente agregando .colorsdespués de las my_cmapobras!