Extension de la barre de couleurs pour inclure des données hors plage

2020-08-02 python matplotlib colorbar colormap

J'essayais de créer une carte thermique Polar en utilisant le code suivant.

# Plotting the polar plot 
from matplotlib.colorbar import ColorbarBase
from matplotlib.colors import LogNorm
import matplotlib.pyplot as plt
cmap = obspy_sequential 

# Have defined the variables to be used for pointing to the coordinates 
# baz is angular, slow is radial, abs_power is the value at every co-ordinate
# Choose number of fractions in plot (desirably 360 degree/N is an integer!)
N = 72
N2 = 30
abins = np.arange(N + 1) * 360. / N
sbins = np.linspace(0, 3, N2 + 1)

# Sum rel power in bins given by abins and sbins
hist, baz_edges, sl_edges = \
    np.histogram2d(baz, slow, bins=[abins, sbins], weights=abs_power)

# Transform to radian
baz_edges = np.radians(baz_edges)

# Add polar and colorbar axes
fig = plt.figure(figsize=(8, 8))
cax = fig.add_axes([0.85, 0.2, 0.05, 0.5])
ax = fig.add_axes([0.10, 0.1, 0.70, 0.7], polar=True)
ax.set_theta_direction(-1)
ax.set_theta_zero_location("N")

dh = abs(sl_edges[1] - sl_edges[0])
dw = abs(baz_edges[1] - baz_edges[0])

# Circle through backazimuth
for i, row in enumerate(hist):
    bars = ax.bar((i * dw) * np.ones(N2),
                  height=dh * np.ones(N2),
                  width=dw, bottom=dh * np.arange(N2),color=cmap(row / hist.max()))

ax.set_xticks(np.linspace(0, 2 * np.pi, 10, endpoint=False))
ax.set_yticklabels(velocity)
ax.set_ylim(0, 3)
[i.set_color('white') for i in ax.get_yticklabels()]
ColorbarBase(cax, cmap=cmap,
             norm=LogNorm(vmin=hist.min(),vmax=hist.max()))
plt.show()

Je crée plusieurs graphiques comme celui-ci et je dois donc étendre la plage de la barre de couleurs au-delà du maximum de la plage de données abs_power. J'ai essayé de changer le vmax et le vmin aux nombres cibles maximum-minimum que je veux, mais cela trace exactement le même tracé à chaque fois. La valeur maximale de la barre de couleurs change sans cesse mais le tracé ne change pas. Pourquoi cela arrive-t-il? Voici à quoi ça ressemble,


Couleurs polaires


Ici, la puissance maximale réelle est bien inférieure au maximum spécifié dans la barre de couleurs. Une tache jaune vif est toujours visible. PS: J'obtiens ce même graphique pour toutes les valeurs vmax, vmin que je fournis.

Answers

La modification de la barre de couleurs n'a pas d'effet sur le tracé principal. Vous devez changer la formule utilisée dans color=cmap(row / hist.max()) pour changer le barplot. La «norme» est uniquement destinée à cette tâche. La norme mappe la plage de nombres à l'intervalle [0, 1] . Chaque valeur mappée à une valeur supérieure à 1 (c'est-à-dire une valeur supérieure à hist.max() dans l'exemple) reçoit la couleur la plus élevée.

Pour que la barre de couleurs reflète les informations correctes, vous avez besoin du même cmap et de la même norme pour le tracé et la barre de couleurs:

my_norm = LogNorm(vmin=hist.min(),vmax=hist.max())
for i, row in enumerate(hist):
    bars = ax.bar((i * dw) * np.ones(N2),
                  height=dh * np.ones(N2),
                  width=dw, bottom=dh * np.arange(N2),color=cmap(my_norm(row)))

et

ColorbarBase(cax, cmap=cmap, norm=my_norm)

D'un autre côté, si vous ne voulez pas que la couleur jaune apparaisse, vous pouvez essayer quelque chose comme my_norm = LogNorm(vmin=hist.min(), vmax=hist.max()*100) dans le code ci-dessus.

Au lieu de créer la barre de couleurs via ColorbarBase , il peut être utile d'utiliser un plt.colorbar() standard, mais avec un ScalarMappable qui indique la ScalarMappable couleurs et la norme utilisée. Dans le cas d'un LogNorm cela affichera les coches au format journal.

from matplotlib.cm import ScalarMappable
plt.colorbar(ScalarMappable(cmap=cmap, norm=my_norm), ax=ax, cax=cax)

Related