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

Use*_*job 6 matlab heatmap

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

在此处输入图片说明

给定下面的源图像,我创建了一个人口稀少的NXN数组,其中包含下面列出的点。1000x800阵列中的90点。

在此处输入图片说明

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

colormap('hot');   % set colormap
imagesc(points);        % draw image and scale colormap to values range
colorbar;  
Run Code Online (Sandbox Code Playgroud)

我的结果令人失望。

在此处输入图片说明

我还需要哪些其他选择才能使自己的形象与上一幅形象相似?

gno*_*ice 5

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

直方图:

如果您分散的数据非常密集,则可能只需要一个简单的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');
Run Code Online (Sandbox Code Playgroud)

这是结果图:

在此处输入图片说明

直方图+过滤:

如果您分散的数据比较稀疏,您仍然可以如上所述创建直方图,然后过滤结果以使其平滑。imdilate如果您拥有图像处理工具箱,则可以使用它,也可以创建一个滤镜矩阵并使用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');
Run Code Online (Sandbox Code Playgroud)

这是结果图:

在此处输入图片说明

距离变换:

从上方的稀疏直方图开始,您可以bwdist从“ 图像处理工具箱”中使用它来创建数据的距离变换。这将根据每个像素与最近的非零像素的距离为其分配一个值。

或者,你可以避开计算2D直方图创建网格覆盖的散点和计算使用您的散点之一,从每个网格点的最小距离pdist2统计工具箱。这是一个示例(使用与上述相同的示例数据):

% 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));
Run Code Online (Sandbox Code Playgroud)

这是结果图:

在此处输入图片说明


bee*_*eep 1

您首先需要计算 xy 网格上点的密度。在这里,您只是在 matlab 中绘制任何散点图的“图像版本”。因此,在绘图之前,您需要处理数据并获取从您的点导出的密度图。例如,您可以使用ksdenth函数,它将估计网格基础上点的密度。如果您无法使用此功能,则 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;
Run Code Online (Sandbox Code Playgroud)