Lorsque vous souhaitez tracer un tableau numpy avec imshow
, voici ce que vous faites normalement:
import numpy as np
import matplotlib.pyplot as plt
A=np.array([[3,2,5],[8,1,2],[6,6,7],[3,5,1]]) #The array to plot
im=plt.imshow(A,Origin="upper",interpolation="nearest",cmap=plt.cm.gray_r)
plt.colorbar(im)
Ce qui nous donne cette image simple:
Dans cette image, les coordonnées x et y sont simplement extraites de la position de chaque valeur dans le tableau. Maintenant, disons que A
est un tableau de valeurs qui fait référence à certaines coordonnées spécifiques:
real_x=np.array([[15,16,17],[15,16,17],[15,16,17],[15,16,17]])
real_y=np.array([[20,21,22,23],[20,21,22,23],[20,21,22,23]])
Ces valeurs sont constituées pour faire juste mon cas. Existe-t-il un moyen de forcer imshow à assigner à chaque valeur de A la paire de coordonnées correspondante (real_x, real_y)?
PS: Je ne cherche pas à ajouter ou à soustraire quelque chose aux x et y basés sur le tableau pour les faire correspondre real_x = et real_y, mais pour quelque chose qui lit ces valeurs de real_x et real_y tableaux. Le résultat souhaité est alors une image avec les valeurs real_x sur l'axe des x et les valeurs real_y sur l'axe des y.
En supposant que vous ayez
real_x=np.array([15,16,17])
real_y=np.array([20,21,22,23])
vous définiriez l'étendue de l'image comme
dx = (real_x[1]-real_x[0])/2.
dy = (real_y[1]-real_y[0])/2.
extent = [real_x[0]-dx, real_x[-1]+dx, real_y[0]-dy, real_y[-1]+dy]
plt.imshow(data, extent=extent)
Une alternative serait de simplement changer les ticklabels
real_x=np.array([15,16,17])
real_y=np.array([20,21,22,23])
plt.imshow(data)
plt.gca().set_xticks(range(len(real_x)))
plt.gca().set_yticks(range(len(real_x)))
plt.gca().set_xticklabels(real_x)
plt.gca().set_yticklabels(real_y)
Si je comprends bien, il s'agit de produire un raster pour imshow, c'est-à-dire, étant donné les coordonnées de l'image X et les valeurs y, produire une matrice d'entrée pour imshow. Je ne connais pas de fonction standard pour cela, donc implémentée
import numpy as np
def to_raster(X, y):
"""
:param X: 2D image coordinates for values y
:param y: vector of scalar or vector values
:return: A, extent
"""
def deduce_raster_params():
"""
Computes raster dimensions based on min/max coordinates in X
sample step computed from 2nd - smallest coordinate values
"""
unique_sorted = np.vstack((np.unique(v) for v in X.T)).T
d_min = unique_sorted[0] # x min, y min
d_max = unique_sorted[-1] # x max, y max
d_step = unique_sorted[1]-unique_sorted[0] # x, y step
nsamples = (np.round((d_max - d_min) / d_step) + 1).astype(int)
return d_min, d_max, d_step, nsamples
d_min, d_max, d_step, nsamples = deduce_raster_params()
# Allocate matrix / tensor for raster. Allow y to be vector (e.g. RGB triplets)
A = np.full((*nsamples, 1 if y.ndim==1 else y.shape[-1]), np.NaN)
# Compute index for each point in X
ind = np.round((X - d_min) / d_step).T.astype(int)
# Scalar/vector values assigned over outer dimension
A[list(ind)] = y # cell id
# Prepare extent in imshow format
extent = np.vstack((d_min, d_max)).T.ravel()
return A, extent
Cela peut ensuite être utilisé avec imshow comme:
import matplotlib.pyplot as plt
A, extent = to_raster(X, y)
plt.imshow(A, extent=extent)
Notez que deduce_raster_params () fonctionne dans O (n * log (n)) au lieu de O(n) à cause du tri dans np.unique () - cela simplifie le code et ne devrait probablement pas '' t être un problème avec les choses envoyées à imshow