使用 matplotlib 在散点图中绘制斑点下的热图
Plotting heatmaps under blobs in a scatter plot with matplotlib
我有一个 Nx2 矩阵 X
和一个 N 维标签向量 y
。例如:
from sklearn.datasets.samples_generator import make_blobs
import matplotlib.pyplot as plt
X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=2)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolor='k')
plt.show()
在这个图的背景中,我想绘制两个热图,其中一个颜色图在高点密度区域具有点的颜色,这样图像看起来就像有紫色和黄色的云,每个都居中在紫色和黄色的斑点处。
这对我来说很有挑战性。我尝试为每个 blob 创建一个 2D 直方图,如 this 答案所示,并且还创建了一个自定义颜色图,以便绘图的低密度区域为白色,高密度区域用 blob 的颜色着色:
import numpy as np
import seaborn as sns
from matplotlib.colors import ListedColormap
palette_colors = sns.color_palette("deep")
palette = sns.light_palette(palette_colors[0], input="husl", n_colors=100)
my_cmap = ListedColormap(sns.color_palette(palette).as_hex())
whr1 = np.where(y==0)
whr2 = np.where(y==1)
x1 = X[whr1][:, 0]
y1 = X[whr1][:, 1]
x2 = X[whr2][:, 0]
y2 = X[whr2][:, 1]
heatmap1, xedges1, yedges1 = np.histogram2d(x1, y1, bins=50)
extent1 = [xedges1[0], xedges1[-1], yedges1[0], yedges1[-1]]
heatmap2, xedges2, yedges2 = np.histogram2d(x2, y2, bins=50)
extent2 = [xedges2[0], xedges2[-1], yedges2[0], yedges2[-1]]
但现在我不知道如何使用 imshow 绘制这些热图。我还想确保如果斑点重叠,热图也会重叠,这样一个热图就不会覆盖另一个热图,而是在重叠区域有热图颜色和强度的组合。
非常感谢您的帮助!
您可以使用 seaborn's kdeplot
x1,y1 = np.random.normal(loc=0.0, scale=1.0, size=(100,)), np.random.normal(loc=2.0, scale=1.0, size=(100,))
x2,y2 = np.random.normal(loc=2., scale=1.0, size=(100,)), np.random.normal(loc=0.0, scale=1.0, size=(100,))
fig, ax = plt.subplots()
sns.kdeplot(x1,y1, shade=True, shade_lowest=False, alpha=0.5, cbar=False, ax=ax, cmap="Blues")
sns.kdeplot(x2,y2, shade=True, shade_lowest=False, alpha=0.5, cbar=False, ax=ax, cmap="Oranges")
ax.scatter(x1,y1, color="C0")
ax.scatter(x2,y2, color="C1")
我有一个 Nx2 矩阵 X
和一个 N 维标签向量 y
。例如:
from sklearn.datasets.samples_generator import make_blobs
import matplotlib.pyplot as plt
X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=2)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolor='k')
plt.show()
在这个图的背景中,我想绘制两个热图,其中一个颜色图在高点密度区域具有点的颜色,这样图像看起来就像有紫色和黄色的云,每个都居中在紫色和黄色的斑点处。
这对我来说很有挑战性。我尝试为每个 blob 创建一个 2D 直方图,如 this 答案所示,并且还创建了一个自定义颜色图,以便绘图的低密度区域为白色,高密度区域用 blob 的颜色着色:
import numpy as np
import seaborn as sns
from matplotlib.colors import ListedColormap
palette_colors = sns.color_palette("deep")
palette = sns.light_palette(palette_colors[0], input="husl", n_colors=100)
my_cmap = ListedColormap(sns.color_palette(palette).as_hex())
whr1 = np.where(y==0)
whr2 = np.where(y==1)
x1 = X[whr1][:, 0]
y1 = X[whr1][:, 1]
x2 = X[whr2][:, 0]
y2 = X[whr2][:, 1]
heatmap1, xedges1, yedges1 = np.histogram2d(x1, y1, bins=50)
extent1 = [xedges1[0], xedges1[-1], yedges1[0], yedges1[-1]]
heatmap2, xedges2, yedges2 = np.histogram2d(x2, y2, bins=50)
extent2 = [xedges2[0], xedges2[-1], yedges2[0], yedges2[-1]]
但现在我不知道如何使用 imshow 绘制这些热图。我还想确保如果斑点重叠,热图也会重叠,这样一个热图就不会覆盖另一个热图,而是在重叠区域有热图颜色和强度的组合。
非常感谢您的帮助!
您可以使用 seaborn's kdeplot
x1,y1 = np.random.normal(loc=0.0, scale=1.0, size=(100,)), np.random.normal(loc=2.0, scale=1.0, size=(100,))
x2,y2 = np.random.normal(loc=2., scale=1.0, size=(100,)), np.random.normal(loc=0.0, scale=1.0, size=(100,))
fig, ax = plt.subplots()
sns.kdeplot(x1,y1, shade=True, shade_lowest=False, alpha=0.5, cbar=False, ax=ax, cmap="Blues")
sns.kdeplot(x2,y2, shade=True, shade_lowest=False, alpha=0.5, cbar=False, ax=ax, cmap="Oranges")
ax.scatter(x1,y1, color="C0")
ax.scatter(x2,y2, color="C1")