使用 python 对二维散点图进行高斯求和
Gaussian summation for 2D scatter plots using python
我想建立人们通常所说的自制 KDE - 我想。我正在尝试评估一组相当庞大的数据点的密度。特别是,有许多散点数据点,我想使用颜色渐变来指示密度(参见下面的 link)。
为了举例说明,我在下面提供了一对随机的 (x,y) 数据。真实数据将分布在不同的尺度上,因此 X 和 Y 网格点间距存在差异。
import numpy as np
from matplotlib import pyplot as plt
def homemadeKDE(x, xgrid, y, ygrid, sigmaX = 1, sigmaY = 1):
a = np.exp( -((xgrid[:,None]-x)/(2*sigmaX))**2 )
b = np.exp( -((ygrid[:,None]-y)/(2*sigmaY))**2 )
xweights = np.dot(a, x.T)/np.sum(a)
yweights = np.dot(b, y.T)/np.sum(b)
return xweights, yweights
x = np.random.rand(10000)
x.sort()
y = np.random.rand(10000)
xGrid = np.linspace(0, 500, 501)
yGrid = np.linspace(0, 10, 11)
newX, newY = homemadeKDE(x, xGrid, y, yGrid)
我坚持的是,如何将这些值投影回原始的 x 和 y 向量,以便我可以用它来绘制一个二维散点图 (x,y),z 值代表由 a 着色的密度像这样给定颜色图:
plt.scatter(x, y, c = z, cmap = "jet")
绘图和 KDE 方法实际上是受这个伟大的启发 answer
编辑 1
为了消除一些混乱,我的想法是做一个高斯 KDE,它会在一个更粗糙的网格上。 SigmaX和sigmaY分别反映了kernel在x和y方向的带宽。
我实际上 - 稍微思考 - 能够自己解决问题。也感谢帮助和有见地的评论。
import numpy as np
from matplotlib import pyplot as plt
def gaussianSum1D(gridpoints, datapoints, sigma=1):
a = np.exp( -((gridpoints[:,None]-datapoints)/sigma)**2 )
return a
#some test data
x = np.random.rand(10000)
y = np.random.rand(10000)
#create grids
gridSize = 100
xedges = np.linspace(np.min(x), np.max(x), gridSize)
yedges = np.linspace(np.min(y), np.max(y), gridSize)
#calculate weights for both dimensions seperately
a = gaussianSum1D(xedges, x, sigma=2)
b = gaussianSum1D(yedges, y, sigma=0.1)
Z = np.dot(a, b.T).T
#plot original data
fig, ax = plt.subplots()
ax.scatter(x, y, s = 1)
#overlay data with contours
ax.contour(xedges, yedges, Z, cmap = "jet")
我想建立人们通常所说的自制 KDE - 我想。我正在尝试评估一组相当庞大的数据点的密度。特别是,有许多散点数据点,我想使用颜色渐变来指示密度(参见下面的 link)。
为了举例说明,我在下面提供了一对随机的 (x,y) 数据。真实数据将分布在不同的尺度上,因此 X 和 Y 网格点间距存在差异。
import numpy as np
from matplotlib import pyplot as plt
def homemadeKDE(x, xgrid, y, ygrid, sigmaX = 1, sigmaY = 1):
a = np.exp( -((xgrid[:,None]-x)/(2*sigmaX))**2 )
b = np.exp( -((ygrid[:,None]-y)/(2*sigmaY))**2 )
xweights = np.dot(a, x.T)/np.sum(a)
yweights = np.dot(b, y.T)/np.sum(b)
return xweights, yweights
x = np.random.rand(10000)
x.sort()
y = np.random.rand(10000)
xGrid = np.linspace(0, 500, 501)
yGrid = np.linspace(0, 10, 11)
newX, newY = homemadeKDE(x, xGrid, y, yGrid)
我坚持的是,如何将这些值投影回原始的 x 和 y 向量,以便我可以用它来绘制一个二维散点图 (x,y),z 值代表由 a 着色的密度像这样给定颜色图:
plt.scatter(x, y, c = z, cmap = "jet")
绘图和 KDE 方法实际上是受这个伟大的启发 answer
编辑 1 为了消除一些混乱,我的想法是做一个高斯 KDE,它会在一个更粗糙的网格上。 SigmaX和sigmaY分别反映了kernel在x和y方向的带宽。
我实际上 - 稍微思考 - 能够自己解决问题。也感谢帮助和有见地的评论。
import numpy as np
from matplotlib import pyplot as plt
def gaussianSum1D(gridpoints, datapoints, sigma=1):
a = np.exp( -((gridpoints[:,None]-datapoints)/sigma)**2 )
return a
#some test data
x = np.random.rand(10000)
y = np.random.rand(10000)
#create grids
gridSize = 100
xedges = np.linspace(np.min(x), np.max(x), gridSize)
yedges = np.linspace(np.min(y), np.max(y), gridSize)
#calculate weights for both dimensions seperately
a = gaussianSum1D(xedges, x, sigma=2)
b = gaussianSum1D(yedges, y, sigma=0.1)
Z = np.dot(a, b.T).T
#plot original data
fig, ax = plt.subplots()
ax.scatter(x, y, s = 1)
#overlay data with contours
ax.contour(xedges, yedges, Z, cmap = "jet")