私はPythonが初めてです。
私は範囲が0-996の値を持つ42x42の次元のでこぼこの行列を持っています。このデータを使用して2Dヒストグラムを作成します。私はチュートリアルを見てきましたが、それらはすべて、乱雑な行列ではなくランダムなデータから2Dヒストグラムを作成する方法を示しているようです。
これまでのところ、私はインポートしました:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
これらが正しいインポートであるかどうかはわかりませんが、表示されているチュートリアルから何ができるかをピックアップしようとしています。
(上記のように)numpy行列M
にすべての値が含まれています。最後に、私はそれを次のように見せたいです:
明らかに、私のデータは異なるため、私のプロットは異なるように見えるはずです。誰か私に手を貸してくれませんか?
編集:私の目的のために、以下のフックの例は、matshowを使用して、まさに私が探しているものです。
カウントからの生データがある場合は、plt.hexbin
プロットを作成するには(IMHOこれは正方格子より優れています): hexbin
の例から改作:
import numpy as np
import matplotlib.pyplot as plt
n = 100000
x = np.random.standard_normal(n)
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
plt.hexbin(x,y)
plt.show()
既に述べたように行列にZ値が既にある場合は、plt.imshow
またはplt.matshow
:
XB = np.linspace(-1,1,20)
YB = np.linspace(-1,1,20)
X,Y = np.meshgrid(XB,YB)
Z = np.exp(-(X**2+Y**2))
plt.imshow(Z,interpolation='none')
2Dヒストグラムマトリックスだけでなく、基礎となる(x, y)
データもある場合、(x, y)
ポイントの散布図を作成し、2Dヒストグラムのビニングカウント値に従って各ポイントに色を付けることができます。マトリックス:
import numpy as np
import matplotlib.pyplot as plt
n = 10000
x = np.random.standard_normal(n)
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
xedges, yedges = np.linspace(-4, 4, 42), np.linspace(-25, 25, 42)
hist, xedges, yedges = np.histogram2d(x, y, (xedges, yedges))
xidx = np.clip(np.digitize(x, xedges), 0, hist.shape[0]-1)
yidx = np.clip(np.digitize(y, yedges), 0, hist.shape[1]-1)
c = hist[xidx, yidx]
plt.scatter(x, y, c=c)
plt.show()
@ unutbuの回答 には誤りがあります:xidx
とyidx
は間違った方法で計算されます(少なくとも私のデータサンプルでは)。正しい方法は次のとおりです。
xidx = np.clip(np.digitize(x, xedges) - 1, 0, hist.shape[0] - 1)
yidx = np.clip(np.digitize(y, yedges) - 1, 0, hist.shape[1] - 1)
関心があるnp.digitize
の戻りディメンションは1
とlen(xedges) - 1
の間にありますが、c = hist[xidx, yidx]
は0
とhist.shape - 1
の間にインデックスが必要です。
以下は結果の比較です。ご覧のように、結果は似ていますが同じではありません。
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
n = 10000
x = np.random.standard_normal(n)
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
xedges, yedges = np.linspace(-4, 4, 42), np.linspace(-25, 25, 42)
hist, xedges, yedges = np.histogram2d(x, y, (xedges, yedges))
xidx = np.clip(np.digitize(x, xedges), 0, hist.shape[0] - 1)
yidx = np.clip(np.digitize(y, yedges), 0, hist.shape[1] - 1)
c = hist[xidx, yidx]
old = ax1.scatter(x, y, c=c, cmap='jet')
xidx = np.clip(np.digitize(x, xedges) - 1, 0, hist.shape[0] - 1)
yidx = np.clip(np.digitize(y, yedges) - 1, 0, hist.shape[1] - 1)
c = hist[xidx, yidx]
new = ax2.scatter(x, y, c=c, cmap='jet')
plt.show()
私は「散布ヒストグラム」の大ファンですが、他のソリューションがそれらを完全に行うとは思いません。 これは関数です それらを実装します。他のソリューションと比較したこの関数の主な利点は、履歴データでポイントをソートすることです(mode
引数を参照)。これは、結果が従来のヒストグラムのように見えることを意味します(つまり、異なるビン内のマーカーの無秩序な重なりが得られません)。
この図のMCVE( my function を使用):
import numpy as np
import matplotlib.pyplot as plt
from hist_scatter import scatter_hist2d
fig = plt.figure(figsize=[5, 4])
ax = plt.gca()
x = randgen.randn(npoint)
y = 2 + 3 * x + 4 * randgen.randn(npoint)
scat = scatter_hist2d(x, y,
bins=[np.linspace(-4, 4, 42),
np.linspace(-25, 25, 42)],
s=5,
cmap=plt.get_cmap('viridis'))
ax.axhline(0, color='k', linestyle='--', zorder=3, linewidth=0.5)
ax.axvline(0, color='k', linestyle='--', zorder=3, linewidth=0.5)
plt.colorbar(scat)
このアプローチの主な欠点は、最も密度の高いエリアのポイントが、より密度の低いエリアのポイントと重なるため、各ビンのエリアの表現が多少不正確になることです。私はこれを解決するために2つのアプローチを調査するのにかなりの時間を費やしました:
1)高密度のビンに小さいマーカーを使用する
2)各ビンに「クリッピング」マスクを適用する
最初のもの 結果を与える それはあまりにもクレイジーです。 2番目のものは見栄えがよく、特に20ポイント以上のビンのみをクリップする場合は特に-非常に遅い( この図 について一分)。
それで、最終的に私はマーカーサイズとビンサイズ(s
とbins
)を慎重に選択することで決定しました。 、視覚的に楽しい結果を得ることができ、データの不正確な表現に関してそれほど悪くはありません。結局のところ、これらの2Dヒストグラムは通常、厳密に定量的な表現ではなく、基礎となるデータを視覚的に支援することを目的としています。したがって、このアプローチは「従来の2Dヒストグラム」よりもはるかに優れていると思います(例:plt.hist2d
またはplt.hexbin
)、そして私がこのページを見つけたなら、あなたも伝統的な(単色の)散布図のファンではないと思います。
私が科学の王なら、私はすべての2Dヒストグラムがこのようなことを他の永遠に行うことを確認します。