2017-06-23 13 views
1

私はscatterplotを使って画像データをプロットしようとしています。これはばかげているかもしれませんが、3次元を表示しようとするためにこれを3次元に拡張したいと考えています。私はscatterplotを使って画像を表示

pylab.imshow(my_img, cmap=pylab.cm.gist_yarg) 

を行うと

は、私は私の画像を見て問題ありません。しかし、私が試してみるとき

ax.scatter(np.arange(my_img.shape[0]), 
      np.arange(my_img.shape[1]), 
      c=my_img, cmap=plt.cm.gist_yarg) 

私はほとんど黒いピクセルを取得します。どうしてこれなの?この仕事をする方法はありますか?

答えて

2

scatter()ファンクションは、xy引数に渡す配列の各値のペアに対して1ポイントをプロットします。あなたの例では、これらの配列の値は[0, 1, 2, ..., my_img.shape[0]-1][0, 1, 2, ..., my_img.shape[1]-1]となります。最高でも、これは対角線をプロットし、xyのサイズが同じでない場合(つまり、画像が四角形でない場合)、scatter()x and y must be the same sizeというエラーを投げます。

画像内のすべてのピクセルをプロットするには、すべてのピクセルの座標をscatter()に渡す必要があります。配列内のすべての要素の座標を取得する方法の1つはindicies()コマンドnumpyです。それぞれのピクセルに格納されているRGB値ではなく、一番外側の値のインデックスのみが必要なので、最初の2つの値を渡します。

y, x = np.indices(my_img.shape[:2]) 

xyは、2次元画像内の全ての点の座標を表す2次元配列です。

もう1つのことは、イメージの配列のサイズをNx3に変更することです(Nはイメージ内のピクセルの総数の長さです)。これは配列の.reshape()メソッドで行われます。再構築するために渡された-1

colors = my_img.reshape((-1,3)) 

は、あなたが明示的にピクセルの数を渡す必要はありませんので、自動的にその大きさを計算するreshape()に指示します。

scatter()コマンドは次のとおりです。

ax.scatter(x, y, c=colors) 
ax.invert_yaxis() #make y=0 appear at the top, similar to imshow() 

は最後に、あなたは、カラーマップを適用します。色のRGB値を渡す場合、scatter()imshow()cmapパラメータを無視します。 matplotlib Image tutorialに示すように、RGB値を単一の値に変換する必要があります。

注:この方法でプロットを描くのは遅く、大きな画像には適していません。

+1

非常に良い答えです。しかし、画像にはいくつかのカラーチャンネルがあり、散布図の色は画像の色に対応すると暗黙のうちに仮定します。その質問がカラーマップを使用しているのを見て、ここの画像は単純な2D配列であると仮定できるので、解をもっと簡単にすることができると思います。 'y、x = np.indices(my_img.shape); ax.scatter(x、y、c = my_img) '。 – ImportanceOfBeingErnest

関連する問題