Matlab - 创建热图以可视化2D点数据的密度

时间:2017-10-29 02:02:18

标签: matlab heatmap

给定一个N×N数组我想生成一个热图,以这种方式可视化数据:

enter image description here

鉴于下面的源图像,我创建了一个稀疏填充的N X N数组,其中包含下面列出的点。 1000x800阵列中的90分。

enter image description here

在网上研究如何生成这样的热图时,我偶然发现只使用色彩图来获得令人失望的结果。

colormap('hot');   % set colormap
imagesc(points);        % draw image and scale colormap to values range
colorbar;  

我得到了相当令人失望的结果。

enter image description here

我还有什么其他选择让我的图像与上面的图像相似?

2 个答案:

答案 0 :(得分:3)

有几种不同的方法可以将散乱或稀疏矩阵数据转换为热图,从而提供更好的点密度可视化。我在这里展示的示例将从分散的数据开始,因此如果您已经在2D矩阵/直方图中有数据,则可以跳过初始步骤......

直方图:

如果散乱数据相当密集,可能只需要一个简单的二维直方图。您可以创建一个覆盖散乱点的网格(以您选择的分辨率),并使用histcounts2在x和y方向上分组数据:

% Normally distributed sample points:
x = randn(1, 10000);
y = randn(1, 10000);

% Bin the data:
pts = linspace(-4, 4, 101);
N = histcounts2(y(:), x(:), pts, pts);

% Plot scattered data (for comparison):
subplot(1, 2, 1);
scatter(x, y, 'r.');
axis equal;
set(gca, 'XLim', pts([1 end]), 'YLim', pts([1 end]));

% Plot heatmap:
subplot(1, 2, 2);
imagesc(pts, pts, N);
axis equal;
set(gca, 'XLim', pts([1 end]), 'YLim', pts([1 end]), 'YDir', 'normal');

这是由此产生的情节:

enter image description here

直方图+过滤:

如果您的分散数据相当稀疏,您仍然可以像上面那样创建直方图,但是然后过滤结果以使其平滑。如果您拥有imdilate,则可以使用Image Processing Toolbox,或创建过滤器矩阵并使用conv2。以下是后者的一个例子:

% Normally distributed sample points:
x = randn(1, 100);
y = randn(1, 100);

% Bin the data:
pts = linspace(-3, 3, 101);
N = histcounts2(y(:), x(:), pts, pts);

% Create Gaussian filter matrix:
[xG, yG] = meshgrid(-5:5);
sigma = 2.5;
g = exp(-xG.^2./(2.*sigma.^2)-yG.^2./(2.*sigma.^2));
g = g./sum(g(:));

% Plot scattered data (for comparison):
subplot(1, 2, 1);
scatter(x, y, 'r.');
axis equal;
set(gca, 'XLim', pts([1 end]), 'YLim', pts([1 end]));

% Plot heatmap:
subplot(1, 2, 2);
imagesc(pts, pts, conv2(N, g, 'same'));
axis equal;
set(gca, 'XLim', pts([1 end]), 'YLim', pts([1 end]), 'YDir', 'normal');

这是由此产生的情节:

enter image description here

距离变换:

从上面的稀疏直方图开始,您可以使用bwdist中的Image Processing Toolbox来创建数据的距离变换。这将根据每个像素与最近的非零像素的距离为每个像素分配一个值。

或者,您可以避免通过覆盖散乱点的creating a grid来计算2D直方图,并使用pdist2中的Statistics Toolbox计算从每个网格点到散点之一的最小距离。这是一个例子(使用与上面相同的样本数据):

% Generate grid and compute minimum distance:
pts = linspace(-3, 3, 101);
[X, Y] = meshgrid(pts);
D = pdist2([x(:) y(:)], [X(:) Y(:)], 'euclidean', 'Smallest', 1);

% Plot scattered data:
subplot(1, 2, 1);
scatter(x, y, 'r.');
axis equal;
set(gca, 'XLim', pts([1 end]), 'YLim', pts([1 end]));

% Plot heatmap:
subplot(1, 2, 2);
imagesc(pts, pts, reshape(D, size(X)));
axis equal;
set(gca, 'XLim', pts([1 end]), 'YLim', pts([1 end]), 'YDir', 'normal');
colormap(flip(parula(), 1));

这是由此产生的情节:

enter image description here

答案 1 :(得分:1)

首先需要计算xy网格上的点密度。在这里,您只是在matlab中绘制任何散点图的“图像版本”。因此,在绘图之前,您需要处理数据并获取从您的点导出的密度图。 您可以使用ksdensity函数,它将估算网格基础上的点密度。如果你无法使用这个函数,那么fileexchage上有很多函数可以做同样的事情。

% get the x y coordinates of your points
[y,x] = find(points);
P = [x,y];

% estimate and plot the density
[Est,XY] = ksdensity(P);
imagesc(XY(:,1), XY(:,2),Est);
colormap('hot');
colorbar;