python - 绘制稀疏矩阵的热图

标签 python matplotlib scipy sparse-matrix heatmap

我有一个包含直方图的大型稀疏矩阵,我想将其绘制为热图。通常我会简单地绘制完整的矩阵(h),如下所示:

import matplotlib.pyplot as plt
plt.imshow(h.T, interpolation="nearest", origin="lower")
plt.colorbar()
plt.savefig("corr.eps")
然而,在这种情况下,我遇到的问题是完整矩阵的尺寸为 189,940x189,940 ,这对于我来说太大了,无法保存在内存中。我找到了有关绘制稀疏模式的帖子(例如 python matplotlib plot sparse matrix pattern ),但没有找到有关如何绘制热图而不将其转换为密集矩阵的信息。可以这样做吗? (或者是否有其他方法可以在不耗尽 RAM 的情况下绘制它?)我的稀疏矩阵当前是 lilmatrix (scipy.sparse.lil_matrix)。

最佳答案

一个想法是使用稀疏操作进行下采样。<​​/p>

 data = data.tocsc()       # sparse operations are more efficient on csc
 N, M = data.shape
 s, t = 400, 400           # decimation factors for y and x directions
 T = sparse.csc_matrix((np.ones((M,)), np.arange(M), np.r_[np.arange(0, M, t), M]), (M, (M-1) // t + 1))
 S = sparse.csr_matrix((np.ones((N,)), np.arange(N), np.r_[np.arange(0, N, s), N]), ((N-1) // s + 1, N))
 result = S @ data @ T     # downsample by binning into s x t rectangles
 result = result.todense() # ready for plotting

此代码片段实现了简单的分箱,但可以进行改进以合并更复杂的过滤器。分箱矩阵只是分箱 id 矩阵,例如 S_ij = 1 if j//s = i else 0。

更多解释。由于原始矩阵非常大,因此可以对其进行下采样,而不会在输出中出现任何视觉上明显的差异。

问题是如何在不首先创建密集表示的情况下进行下采样。一种可能的答案是用矩阵乘法来表达分箱,然后使用稀疏矩阵乘法。

因此,如果将右侧的原始数据与分箱矩阵 T 相乘,则 T 的列对应于列箱,特别是T 将确定下采样数据在 x 方向上有多少像素。 T 的每一列决定什么进入相应的 bin,什么不进入。在示例中,我将(原始矩阵的)相邻列编码为 1,其余元素设置为 0。这将这些列相加,并将总和放入结果矩阵中,换句话说,它将这些列合并在一起.

从左侧相乘的工作方式完全相同,只是它影响行,而不影响列。

如果您觉得分箱太粗糙,您可以用平滑内核替换简单的零一方案,只需确保生成的矩阵保持稀疏即可。建立这样的矩阵需要更多的努力,但并不困难。您正在为数据使用稀疏矩阵,因此我假设您熟悉如何构造稀疏矩阵。

关于python - 绘制稀疏矩阵的热图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42210594/

相关文章:

python - 如何用matplotlib绘制水平百分比条形图?

python - Matplotlib 中的 3d 条形图问题

python - Matplotlib -- libpng 错误 : Incompatible libpng version in application and library

optimization - 提取并设置 numpy 数组的粗对角线

python - scipy:没有框架,轴,只有内容的savefig

python - 在 Scipy 稀疏矩阵中寻址范围

python - 如何使用 Python 更改 Windows 默认语言环境?

python - asyncio.iscoroutinefunction 为异步生成器返回 False

python +安全

python - 仅针对有数据的时间段绘制 Pandas 日内时间序列