web-dev-qa-db-ja.com

Matplotlib:imshowに他のnumpy配列からx、y座標を読み取らせるには?

Numpy配列をimshowでプロットする場合、これは通常行うことです。

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)

これは私たちにこの単純なイメージを与えます: enter image description here

この画像では、配列内の各値の位置からxおよびy座標が単純に抽出されています。ここで、Aが特定の座標を参照する値の配列であるとしましょう。

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

これらの値は、単に私の主張をするために構成されています。 imshowにAの各値を対応する座標のペア(real_x、real_y)に割り当てる方法はありますか?

PS:配列ベースのxおよびyに何かを加算または減算して、それらを一致させるreal_xおよびreal_y、ただしreadsreal_xおよびreal_y配列からのこれらの値。次に、意図した結果は、x軸にreal_x値、y軸にreal_y値を持つ画像です。

8
FaCoffee

範囲の設定

あなたが持っていると仮定

real_x=np.array([15,16,17])
real_y=np.array([20,21,22,23])

画像の範囲を次のように設定します

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)

目盛りラベルの変更

別の方法は目盛りラベルを変更することです

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)

私が正しく理解していれば、これはimshowのラスターを生成することです。つまり、X-画像座標とy-値を指定すると、imshowの入力行列が生成されます。そのための標準機能は知らないので実装しました

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

これは、imshowで次のように使用できます。

import matplotlib.pyplot as plt 
A, extent = to_raster(X, y)
plt.imshow(A, extent=extent) 

Np.unique()での並べ替えのため、deduce_raster_params()はO(n)ではなくO(n * log(n))で機能することに注意してください。これによりコードが簡素化され、おそらくimshowに送信されたものに問題がある

2
Yuri Feldman