密度散点图(Density Scatter Plot),也称为密度点图或核密度估计散点图,是一种数据可视化技术,主要用于展示大量数据点在二维平面上的分布情况。与传统散点图相比,它使用颜色或阴影来表示数据点的密度,从而更直观地展示数据的分布情况。密度散点图能更好地揭示数据的集中趋势和分布模式,尤其是在数据量非常大时,避免了散点图中点重叠导致的可视化混乱问题。
密度散点图涉及的基础概念:
可视化原理:
为什么要用密度散点图?
总结来说,使用密度散点图在处理大规模和
或复杂数据集时提供了一种极具价值的工具。它不仅能够有效解决过度绘制问题,还能揭示出隐藏在庞大数据背后的结构和模式,同时提供优雅且功能强大的视觉展示方式。无论是在科研、工业还是商业领域,掌握并应用这种技术都将极大地增强对数据的理解和利用能力。
下面讲解一个带拟合曲线的密度散点图的绘图示例。
导入需要的依赖库:
import numpy as np
from numpy import polyfit, poly1d
import matplotlib as mpl
from matplotlib import cm
from matplotlib import ticker
from matplotlib import colors
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
from scipy.stats import gaussian_kde
绘制带拟合曲线的密度散点图的 Python 代码如下:
# 固定 numpy 的随机种子
np.random.seed(2024)
# 构造二维数据 x 和 y
x = np.random.normal(loc=0.0, scale=1.0, size=1000)
y = x + np.random.normal(loc=0.1, scale=1.0, size=1000)
# 核密度估计
x_and_y = np.vstack([x, y])
kde = gaussian_kde(x_and_y)
z = kde(x_and_y)
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]
is_cbar = True
# 创建图形和坐标轴
fig, ax = plt.subplots(figsize=(7, 4), dpi=150)
# cmap: bwr、Spectral_r、viridis_r、spring、gist_rainbow_r、RdBu_r
# 可设置的 colormaps - https://matplotlib.org/tutorials/colors/colormaps.html
my_cmap = "bwr"
# 绘制密度散点图
ax.scatter(x, y, c=z, cmap=my_cmap)
# 用 7 次多项式拟合,调用 poly1d 方法得到多项式系数。
y_fit = polyfit(x, y, 7)
y_fit_1d = np.poly1d(y_fit)
y_hat = np.polyval(y_fit, x)
# 计算相关系数和 R^2
print('Correlation coefficients:')
print(np.corrcoef(y_hat, y))
correlation = np.corrcoef(y_hat, y)[0, 1]
R_square = correlation ** 2
print("R^2:", R_square)
xtick = np.linspace(min(x), max(x), 1000)
# 拟合的多项式曲线
plt.plot(xtick, y_fit_1d(xtick), color="#FF0066", lw=2.2)
# 坐标轴刻度的数值使用 Latin Modern Math 字体
labels = ax.get_xticklabels() + ax.get_yticklabels()
[label.set_fontproperties(font_latex2) for label in labels]
[label.set_color('black') for label in labels]
# 设置坐标轴刻度
plt.tick_params(axis='x', direction='out', labelsize=13, length=4.6, width=1.15)
plt.tick_params(axis='y', direction='out', labelsize=13, length=4.6, width=1.15)
# 展示 X 和 Y 轴的子刻度
ax.xaxis.set_minor_locator(ticker.AutoMinorLocator())
ax.yaxis.set_minor_locator(ticker.AutoMinorLocator())
# 颜色条的设置:刻度、字体、字号等
if is_cbar:
norm = colors.Normalize(vmin=np.min(z), vmax=np.max(z))
cbar = plt.colorbar(cm.ScalarMappable(norm=norm, cmap=my_cmap), ax=ax)
cbar.ax.set_ylabel("Density", fontproperties=font_latex2, labelpad=12)
cbar.ax.tick_params(labelsize=12)
labels = cbar.ax.get_xticklabels() + cbar.ax.get_yticklabels()
[label.set_fontproperties(font_latex2) for label in labels]
[label.set_color('black') for label in labels]
tick_locator = ticker.MaxNLocator(nbins=8)
cbar.locator = tick_locator
cbar.update_ticks()
# 设置 X 轴和 Y 轴的刻度值范围
ax.set_xlim(left=-6, right=6.0000001)
ax.set_xticks(np.arange(-6, 6.000001, step=2.0))
ax.set_ylim(bottom=-6, top=6.0000001)
ax.set_yticks(np.arange(-6, 6.000001, step=2.0))
# 画图对象周围的框的加粗一点
lw = 1.25
ax.spines["right"].set_linewidth(lw)
ax.spines["left"].set_linewidth(lw)
ax.spines["top"].set_linewidth(lw)
ax.spines["bottom"].set_linewidth(lw)
# 设置 X 轴和 Y 轴的标签、字体、刻度和刻度标签在内的坐标轴边界框中的间距
plt.xlabel("X Label", fontproperties=font_latex1, labelpad=8)
plt.ylabel("Y Label", fontproperties=font_latex1, labelpad=8)
# 设置标题 字体 大小 以及距绘图对象的距离
plt.title("Python Matplotlib - Density Scatter Plot",
fontproperties=font_latex2, pad=12
)
# 文本的位置是根据数据坐标来确定的
ax.text(x=-5, y=4.5, s=r'$\ {R^2} = 0.522$', usetex=True,
fontsize=14, fontweight="bold"
)
# 显示网格 虚线和透明度
plt.grid(alpha=0.360, ls="--", which="major", color="#A9A9A9")
# 紧凑布局
plt.tight_layout()
plt.savefig("./Figures/密度散点图.png", dpi=300, bbox_inches="tight")
plt.show()
整体解释:这段代码首先导入了所需的库,然后生成了测试数据
和
(实际应用还可能是真实值
和预测值
)。接着,它使用核密度估计(KDE)来计算数据的密度分布。之后,它绘制了一个密度散点图,并使用多项式拟合来生成一个曲线。最后,它计算了相关系数和
值,并设置了各种图形属性,如坐标轴刻度、颜色条、网格等。最后,它将图像保存为一个 .png 文件并显示出来。
可视化结果如下所示:
📚️ 参考链接: