2016-08-05 4 views
1

私はサイズが500×28000のマトリックスを持っていますが、その間には多くのゼロが入っています。しかし、私たちが行列Aでの作業の例を考えてみましょう:Python:ゼロを無視して2D行列のヒートマップをプロットする方法はありますか?

A = [[0, 0, 0, 1, 0], 
    [1, 0, 0, 2, 3], 
    [5, 3, 0, 0, 0], 
    [5, 0, 1, 0, 3], 
    [6, 0, 0, 9, 0]] 

私は上記の行列のヒートマップをプロットしたいと思いますが、それはゼロを多く含んでいるために見られるように、ヒートマップは、ほとんど空白が含まれています下の図をご覧ください。

マトリックス内のゼロを無視してヒートマップをプロットするにはどうすればよいですか?

im = plt.matshow(A, cmap=pl.cm.hot, norm=LogNorm(vmin=0.01, vmax=64), aspect='auto') # pl is pylab imported a pl 
plt.colorbar(im) 
plt.show() 

生成します:

enter image description here

あなたはそれが原因で空白が表示され、ゼロである見ることができるよう

は、ここで私が試した最小限の実施例です。

私の元のマトリックスサイズ500X280000にはゼロがたくさん含まれているので、カラーマップがほぼ白くなります!あなたがLogNormを削除した場合

+1

私は、視覚化が明確でないという理由だけでデータを削除することを納得させるわけではありません。データをグループ化したり、別の種類のプロットを探していましたか?あなたが作業しているデータの性質についてもっと詳しく教えてください。 –

+0

私は、私のデータを視覚的に表現するためのカラープロット以外のものは考えられませんでした。それを表現する他の方法がある場合は、私に知らせてください。 – Rangooski

+0

ヒートマップをプロットする前に、階層的クラスタリングを使用することができます。 – GWW

答えて

1

この回答はルイス答えの '編集2' セクションと同じ方向にあります。実際、これは単純化されたバージョンです。私はコメントの中で誤解を招く言葉を修正するためにこれを投稿しています。私は、コメント領域で議論すべきではないという警告を見たので、この回答領域を使用しています。

とにかく、まず私のコードを投稿させてください。サンプル行列Aではなく、スクリプト内でランダムに生成された大きな行列を使用しました。

#!/usr/bin/python 
# 
# This script was written by norio 2016-8-5. 

import os, re, sys, random 
import numpy as np 

#from matplotlib.patches import Ellipse 
import matplotlib as mpl 
import matplotlib.pyplot as plt 
import matplotlib.image as img 

mpl.rcParams['lines.linewidth'] = 2 
mpl.rcParams['lines.markeredgewidth'] = 1.0 
mpl.rcParams['axes.formatter.limits'] = (-4,4) 
#mpl.rcParams['axes.formatter.limits'] = (-2,2) 
mpl.rcParams['axes.labelsize'] = 'large' 
mpl.rcParams['xtick.labelsize'] = 'large' 
mpl.rcParams['ytick.labelsize'] = 'large' 
mpl.rcParams['xtick.direction'] = 'out' 
mpl.rcParams['ytick.direction'] = 'out' 


############################################ 
#numrow=500 
#numcol=280000 
numrow=50 
numcol=28000 
# .. for testing 
numelm=numrow*numcol 
eps=1.0e-9 
# 
#numnz=int(1.0e-7*numelm) 
numnz=int(1.0e-5*numelm) 
# .. for testing 
vmin=1.0e-6 
vmax=1.0 
outfigname='stackoverflow38790536.png' 
############################################ 

### data matrix 
# I am generating a data matrix here artificially. 
print 'generating pseudo-data..' 
random.seed('20160805') 
matA=np.zeros((numrow, numcol)) 
for je in range(numnz): 
    jr = random.uniform(0,numrow) 
    jc = random.uniform(0,numcol) 
    matA[jr,jc] = random.uniform(vmin,vmax) 


### Actual processing for a given data will start from here 
print 'processing..' 

idxrow=[] 
idxcol=[] 
val=[] 
for ii in range(numrow): 
    for jj in range(numcol): 
     if np.abs(matA[ii,jj])>eps: 
      idxrow.append(ii) 
      idxcol.append(jj) 
      val.append(np.abs(matA[ii,jj])) 

print 'len(idxrow)=', len(idxrow)  
print 'len(idxcol)=', len(idxcol)  
print 'len(val)=', len(val)  


############################################ 
# canvas setting for line plots 
############################################ 

f_size = (8,5) 

a1_left = 0.15 
a1_bottom = 0.15 
a1_width = 0.65 
a1_height = 0.80 
# 
hspace=0.02 
# 
ac_left = a1_left+a1_width+hspace 
ac_bottom = a1_bottom 
ac_width = 0.03 
ac_height = a1_height 

############################################ 
# plot 
############################################ 
print 'plotting..' 

fig1=plt.figure(figsize=f_size) 
ax1 =plt.axes([a1_left, a1_bottom, a1_width, a1_height], axisbg='w') 

pc1=plt.scatter(idxcol, idxrow, s=20, c=val, cmap=mpl.cm.gist_heat_r) 
# cf. 
# http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.scatter 
plt.xlabel('Column Index', fontsize=18) 
plt.ylabel('Row Index', fontsize=18) 
ax1.set_xlim([0, numcol-1]) 
ax1.set_ylim([0, numrow-1]) 

axc =plt.axes([ac_left, ac_bottom, ac_width, ac_height], axisbg='w') 
mpl.colorbar.Colorbar(axc,pc1, ticks=np.arange(0.0, 1.5, 0.1)) 

plt.savefig(outfigname) 
plt.close() 

このスクリプトの出力、次のようになりますフィギュア、「stackoverflow38790536.png」、。 scatter plot of non-zero elements

私のコードでわかるとおり、plotの代わりにscatterを使用しました。私はplotコマンドがここのタスクに最も適していないことを認識しました。

私が訂正する必要があるもう一つの言葉は、row_indexには140,000,000(= 500 * 280000)もの要素が必要ないということです。それは、非ゼロ要素の行インデックスを持つことだけが必要です。より正確には、上のコードでscatterコマンドに入る idxrowidxcol、およびvalのリストは、非ゼロ要素の数に等しい長さを持ちます。

ルイスの答えでは、これらの点の両方が正しく処理されています。

2

、あなたが白の代わりに黒い四角を取得:

im = plt.matshow(A, cmap=plt.cm.hot, aspect='auto') # pl is pylab imported a pl 

enter image description here


編集

をカラーマップでは、常には、完全なを持っていますグリッドに値が埋め込まれています。そういうわけで実際にグリッドを作成するのです:グリッド内に正確にないすべてのポイントを考慮します(言い換えれば:補間する)。つまり、データにはが多くゼロであり、グラフには白(または黒)で正しく反映されていることを意味します。これらの値を無視することで、明確な理由がない場合は、誤解を招くグラフが作成されます。

0以外の値を入力する場合は、norio's commentなどの別の種類の図が必要です。そのためには、this answerをご覧ください。


編集2 this answer

から適合

あなたが一次元配列として値を扱い、独立にポイントをプロットする代わりに非所望の値を有するメッシュを充填することができ。

A = [[0, 0, 0, 1, 0], 
    [1, 0, 0, 2, 3], 
    [5, 3, 0, 0, 0], 
    [5, 0, 1, 0, 3], 
    [6, 0, 0, 9, 0]] 
A = np.array(A) 
lenx, leny = A.shape 

xx = np.array([ a for a in range(lenx) for a in range(leny) ]) # Convert 3D to 3*1D 
yy = np.array([ a for a in range(lenx) for b in range(leny) ]) 
zz = np.array([ A[x][y] for x,y in zip(xx,yy) ]) 
#--- 
xx = xx[zz!=0] # Drop zeroes 
yy = yy[zz!=0] 
zz = zz[zz!=0] 
#--- 
zi, yi, xi = np.histogram2d(yy, xx, bins=(10,10), weights=zz, normed=False) 
zi = np.ma.masked_equal(zi, 0) 

fig, ax = plt.subplots() 
ax.pcolormesh(xi, yi, zi, edgecolors='black') 
scat = ax.scatter(xx, yy, c=zz, s=200) 
fig.colorbar(scat) 
ax.margins(0.05) 

plt.show() 

enter image description here

+1

OPはゼロの寄与を取り除こうとしていますが、ここでもまだ黒で示しています。 – ThePredator

+0

@ルイス。はい、ここに投稿する前に試しました。それでも私のマトリックスは本当に大きいので、ヒートマップを視覚化することはできません。赤い点がほとんどない黒い図形を示しています。 – Rangooski

+0

定義によると、事実上、カラーマップには完全なグリッドがあります。ここでは、すべての**点がプロットされます。そうでない場合は、別のタイプのプロットが必要です。上のnorioのコメントを参照してください。 – Luis

0

ノリオの答えは正しいですが。

import numpy as np 
import matplotlib.pyplot as plt 
A = np.asarray(A) 
x,y = A.nonzero() #get the notzero indices 
plt.scatter(x,y,c=A[x,y],s=100,cmap='hot',marker='s') #adjust the size to your needs 
plt.colorbar() 
plt.show() 

enter image description here

注軸が反転していること:私は1つは、わずか数行のコードでポイント素早く答えに多くを与えることができると思います。また、あなたが今より多くの柔軟性を持っていることに注意してください

ax=plt.gca() 
ax.invert_xaxis() 
ax.invert_yaxis() 

  • あなたは
  • 、必要に応じてこの手順をマーカーサイズとマーカーの型とtransparancyを設定することができますされますがによってそれらを反転できより速く、ゼロはmatplotlibに解析されません。
関連する問題