私はmatplotlibの散布図で約30,000点を表現する必要があります。これらのポイントは2つの異なるクラスに属しているので、それらを異なる色で表現したいと思います。
私はそうすることに成功しましたが、問題があります。ポイントは多くの地域で重なり、最後に描いたクラスは他のクラスの上に視覚化され、非表示になります。さらに、散布図では、各領域にあるポイントの数を示すことはできません。また、histogram2dとimshowを使用して2dヒストグラムを作成しようとしましたが、両方のクラスに属するポイントを明確に示すことは困難です。
クラスの分布とポイントの集中の両方を明確にする方法を提案できますか?
編集:より明確にするために、これは link で、 "x、y、class"という形式のデータファイルです。
1つのアプローチは、データを低アルファの散布図としてプロットすることです。これにより、個々の点と密度の大まかな尺度を確認できます。 (これの欠点は、アプローチが示すことができるオーバーラップの範囲が限られていることです-つまり、約1/alphaの最大密度です)。
次に例を示します。
ご想像のとおり、表現できるオーバーラップの範囲は限られているため、個々のポイントの可視性とオーバーラップの量の表現(およびマーカー、プロットなどのサイズ)の間にはトレードオフがあります。
import numpy as np
import matplotlib.pyplot as plt
N = 10000
mean = [0, 0]
cov = [[2, 2], [0, 2]]
x,y = np.random.multivariate_normal(mean, cov, N).T
plt.scatter(x, y, s=70, alpha=0.03)
plt.ylim((-5, 5))
plt.xlim((-5, 5))
plt.show()
(ここでは、30e6ではなく30e3ポイントを意味していると想定しています。30e6の場合、何らかのタイプの平均密度プロットが必要になると思います。)
最初に散布図の分布のカーネル密度推定を計算し、密度値を使用して散布図の各ポイントの色を指定することにより、ポイントに色を付けることもできます。前の例のコードを変更するには:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde as kde
from matplotlib.colors import Normalize
from matplotlib import cm
N = 10000
mean = [0,0]
cov = [[2,2],[0,2]]
samples = np.random.multivariate_normal(mean,cov,N).T
densObj = kde( samples )
def makeColours( vals ):
colours = np.zeros( (len(vals),3) )
norm = Normalize( vmin=vals.min(), vmax=vals.max() )
#Can put any colormap you like here.
colours = [cm.ScalarMappable( norm=norm, cmap='jet').to_rgba( val ) for val in vals]
return colours
colours = makeColours( densObj.evaluate( samples ) )
plt.scatter( samples[0], samples[1], color=colours )
plt.show()
散布関数のドキュメントに気付いたとき、私は少し前にこのトリックを学びました-
c : color or sequence of color, optional, default : 'b'
c
は、単一のカラーフォーマット文字列、長さN
の一連のカラー仕様、またはkwargsを介して指定されたN
およびcmap
を使用して色にマッピングされるnorm
番号のシーケンスにすることができます(以下を参照)。c
は、単一の数値RGBまたはRGBAシーケンスであってはならないことに注意してください。これは、カラーマップされる値の配列と区別がつかないためです。c
は、行がRGBまたはRGBAである2次元配列にすることができますが、すべてのポイントに同じ色を指定する単一の行の場合も含まれます。