web-dev-qa-db-fra.com

Définir la gamme Colorbar dans matplotlib

J'ai le code suivant:

import matplotlib.pyplot as plt

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

plt.clf()
plt.pcolor(X, Y, v, cmap=cm)
plt.loglog()
plt.xlabel('X Axis')
plt.ylabel('Y Axis')

plt.colorbar()
plt.show()

Donc, cela produit un graphique des valeurs 'v' sur les axes X vs Y, en utilisant la palette de couleurs spécifiée. Les axes X et Y sont parfaits, mais la palette de couleurs s'étend entre le minimum et le maximum de v. Je voudrais forcer la palette de couleurs à se situer entre 0 et 1.

J'ai pensé à utiliser:

plt.axis(...)

Pour définir les plages des axes, mais cela ne prend que des arguments pour les min et max de X et Y, pas pour la palette de couleurs.

Edit:

Par souci de clarté, supposons que j'ai un graphique dont les valeurs sont comprises entre 0 ... 0,3 et un autre graphique dont les valeurs (0,2 ... 0,8).

Dans les deux graphiques, je veux que la plage de la barre de couleurs soit (0 ... 1). Dans les deux graphiques, je souhaite que cette plage de couleurs soit identique à celle utilisée pour la plage complète de cdict ci-dessus (donc 0,25 dans les deux graphiques aura la même couleur). Dans le premier graphique, toutes les couleurs comprises entre 0,3 et 1,0 ne figureront pas dans le graphique, mais le seront dans la touche de barre de couleur sur le côté. Dans l’autre, toutes les couleurs comprises entre 0 et 0,2 et entre 0,8 et 1 ne figureront pas dans le graphique, mais le seront dans la barre de couleur sur le côté.

126
Paul

Utiliser vmin et vmax force la plage des couleurs. Voici un exemple:

enter image description here

import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)

data = 2*( np.sin(X) + np.sin(3*Y) )

def do_plot(n, f, title):
    #plt.clf()
    plt.subplot(1, 3, n)
    plt.pcolor(X, Y, f(data), cmap=cm, vmin=-4, vmax=4)
    plt.title(title)
    plt.colorbar()

plt.figure()
do_plot(1, lambda x:x, "all")
do_plot(2, lambda x:np.clip(x, -4, 0), "<0")
do_plot(3, lambda x:np.clip(x, 0, 4), ">0")
plt.show()
150
tom10

Utilisez la fonction CLIM (équivalente à la fonction CAXIS dans MATLAB):

plt.pcolor(X, Y, v, cmap=cm)
plt.clim(-4,4)
plt.show()
69
Amro

Vous ne savez pas si c'est la solution la plus élégante (c'est ce que j'ai utilisé), mais vous pouvez redimensionner vos données dans la plage de 0 à 1, puis modifier la barre de couleurs:

import matplotlib as mpl
...
ax, _ = mpl.colorbar.make_axes(plt.gca(), shrink=0.5)
cbar = mpl.colorbar.ColorbarBase(ax, cmap=cm,
                       norm=mpl.colors.Normalize(vmin=-0.5, vmax=1.5))
cbar.set_clim(-2.0, 2.0)

Avec les deux limites différentes, vous pouvez contrôler la plage et la légende de la barre de couleur. Dans cet exemple, seule la plage comprise entre -0,5 et 1,5 est affichée dans la barre, tandis que la palette de couleurs couvre -2 à 2 (il peut donc s'agir de la plage de données que vous avez enregistrée avant la mise à l'échelle).

Ainsi, au lieu de mettre à l'échelle la palette de couleurs, vous mettez à l'échelle vos données et y adaptez la barre de couleurs.

15
nikow

Utilisation de figure figure et .set_clim ()

Pourrait être plus facile et plus sûr cette alternative si vous avez plusieurs parcelles:

import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)

data = 2*( np.sin(X) + np.sin(3*Y) )
data1 = np.clip(data,0,6)
data2 = np.clip(data,-6,0)
vmin = np.min(np.array([data,data1,data2]))
vmax = np.max(np.array([data,data1,data2]))

fig = plt.figure()
ax = fig.add_subplot(131)
mesh = ax.pcolormesh(data, cmap = cm)
mesh.set_clim(vmin,vmax)
ax1 = fig.add_subplot(132)
mesh1 = ax1.pcolormesh(data1, cmap = cm)
mesh1.set_clim(vmin,vmax)
ax2 = fig.add_subplot(133)
mesh2 = ax2.pcolormesh(data2, cmap = cm)
mesh2.set_clim(vmin,vmax)
# Visualizing colorbar part -start
fig.colorbar(mesh,ax=ax)
fig.colorbar(mesh1,ax=ax1)
fig.colorbar(mesh2,ax=ax2)
fig.tight_layout()
# Visualizing colorbar part -end

plt.show()

enter image description here

Une seule barre de couleur

La meilleure alternative consiste alors à utiliser une seule barre de couleur pour l’ensemble du tracé. Il y a différentes façons de le faire, le tutoriel this est très utile pour comprendre la meilleure option. Je préfère cette solution que vous pouvez simplement copier et coller au lieu de la précédente visualisation de la partie colorbar du code.

fig.subplots_adjust(bottom=0.1, top=0.9, left=0.1, right=0.8,
                    wspace=0.4, hspace=0.1)
cb_ax = fig.add_axes([0.83, 0.1, 0.02, 0.8])
cbar = fig.colorbar(mesh, cax=cb_ax)

enter image description here

P.S.

Je suggérerais d'utiliser pcolormesh au lieu de pcolor car c'est plus rapide (plus infos ici ).

6
G M