web-dev-qa-db-fra.com

Modifier les valeurs sur l’axe du graphique matplotlib imshow ()

Disons que j'ai des données d'entrée:

data = np.random.normal(loc=100,scale=10,size=(500,1,32))
hist = np.ones((32,20)) # initialise hist
for z in range(32):
    hist[z],edges = np.histogram(data[:,0,z],bins=np.arange(80,122,2))

Je peux le tracer en utilisant imshow():

plt.imshow(hist,cmap='Reds')

obtenir: 

enter image description here

Cependant, les valeurs de l’axe des abscisses ne correspondent pas aux données d’entrée (c’est-à-dire une moyenne de 100, comprise entre 80 et 122). Par conséquent, j'aimerais changer l'axe des x pour afficher les valeurs dans edges.

J'ai essayé:

ax = plt.gca()
ax.set_xlabel([80,122]) # range of values in edges
...
# this shifts the plot so that nothing is visible

et 

ax.set_xticklabels(edges)
...
# this labels the axis but does not centre around the mean:

enter image description here

Des idées sur la façon dont je peux changer les valeurs de l'axe pour refléter les données d'entrée que j'utilise?

58
atomh33ls

J'essayerais d'éviter de changer le xticklabels si possible, sinon cela peut devenir très déroutant si vous par exemple superposez votre histogramme avec des données supplémentaires. 

Définir la plage de votre grille est probablement le meilleur et avec imshow cela peut être fait en ajoutant le mot clé extent. De cette façon, les axes sont ajustés automatiquement. Si vous voulez changer les étiquettes, je voudrais utiliser set_xticks avec peut-être un formateur. Modifier les étiquettes directement devrait être le dernier recours.

fig, ax = plt.subplots(figsize=(6,6))

ax.imshow(hist, cmap=plt.cm.Reds, interpolation='none', extent=[80,120,32,0])
ax.set_aspect(2) # you may also use am.imshow(..., aspect="auto") to restore the aspect ratio

enter image description here

96
Rutger Kassies

J'ai eu un problème similaire et Google m'envoyait à ce poste. Ma solution était un peu différente et moins compacte, mais j'espère que cela pourra être utile à quelqu'un.

Afficher votre image avec matplotlib.pyplot.imshow est généralement un moyen rapide d'afficher des données 2D. Cependant, cela attribue par défaut aux axes le nombre de pixels. Si les données 2D que vous tracez correspondent à une grille uniforme définie par les tableaux x et y, vous pouvez utiliser matplotlib.pyplot.xticks et matplotlib.pyplot.yticks pour identifier les axes x et y à l'aide des valeurs de ces tableaux. Celles-ci associeront certaines étiquettes, correspondant aux données de grille réelles, au nombre de pixels sur les axes. Et cela est beaucoup plus rapide que d’utiliser quelque chose comme pcolor par exemple.

Voici une tentative avec vos données:

import matplotlib.pyplot as plt

# ... define 2D array hist as you did

plt.imshow(hist, cmap='Reds')
x = np.arange(80,122,2) # the grid to which your data corresponds
nx = x.shape[0]
no_labels = 7 # how many labels to see on axis x
step_x = int(nx / (no_labels - 1)) # step between consecutive labels
x_positions = np.arange(0,nx,step_x) # pixel count at label position
x_labels = x[::step_x] # labels you want to see
plt.xticks(x_positions, x_labels)
# in principle you can do the same for y, but it is not necessary in your case
0
rxs