Altere os valores no eixo do gráfico matplotlib imshow ()

90

Digamos que eu tenha alguns dados de entrada:

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))

Posso traçar usando imshow():

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

obtendo:

insira a descrição da imagem aqui

No entanto, os valores do eixo x não correspondem aos dados de entrada (ou seja, média de 100, faixa de 80 a 122). Portanto, gostaria de alterar o eixo x para mostrar os valores em edges.

Eu tentei:

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

e

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

insira a descrição da imagem aqui

Alguma ideia de como posso alterar os valores do eixo para refletir os dados de entrada que estou usando?

atomh33ls
fonte
Use em pcolorvez de imshowconforme mencionado nesta resposta .
Nirmal

Respostas:

144

Eu tentaria evitar alterar o, xticklabelsse possível, caso contrário, pode ficar muito confuso se você, por exemplo, overplot seu histograma com dados adicionais.

Definir o intervalo de sua grade é provavelmente o melhor e com imshowisso pode ser feito adicionando a extentpalavra - chave. Desta forma, os eixos são ajustados automaticamente. Se você quiser alterar os rótulos, eu usaria set_xtickstalvez com algum formatador. Alterar os rótulos diretamente deve ser o último recurso.

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

insira a descrição da imagem aqui

Rutger Kassies
fonte
18
Também é importante notar que interpolation="none"foi usado aqui uma representação muito mais precisa de dados reais.
Hooked
4
Uma resposta muito útil; Eu o usei para fazer um gráfico de cores de uma função de duas variáveis ​​(ou seja, dados sísmicos). Eu também adicionei a opção "aspect = 'auto'" em imshow () para que eu possa 'esticar e comprimir' a exibição sísmica.
Kurt Peek de
11

Eu tive um problema semelhante e o Google estava me enviando para este post. Minha solução foi um pouco diferente e menos compacta, mas espero que isso possa ser útil para alguém.

Mostrar sua imagem com matplotlib.pyplot.imshow geralmente é uma maneira rápida de exibir dados 2D. No entanto, isso por padrão rotula os eixos com a contagem de pixels. Se os dados 2D que você está plotando correspondem a alguma grade uniforme definida pelos arrays xey, então você pode usar matplotlib.pyplot.xticks e matplotlib.pyplot.yticks para rotular os eixos xey usando os valores desses arrays. Estes irão associar alguns rótulos, correspondentes aos dados reais da grade, às contagens de pixels nos eixos. E fazer isso é muito mais rápido do que usar algo como pcolor, por exemplo.

Aqui está uma tentativa de fazer isso com seus dados:

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
rxs
fonte