此前已经发布过博客 Matlab绘制散点密度图,其主要思路是计算每个点周围一定范围内的点个数。对于数据量较小时,该博客 Matlab绘制散点密度图 中的内容都能比较好的解决小数据量的问题,用时也在可接受的范围内;但当数据量很大时,比如有十几万个点,此时的运行效率则十分低下。
这里通过将数据进行重采样,进而绘制类似于R语言的散点密度图(输入的样本数量为 459780 个),重采样后的数据量降到 4731:
绘制的结果如下:
%%
% X 用户输入X
% Y 用户输入Y
%%
% key parameters
% 输入数据后,由于数据量很大,因此按照一定的步长进行重采样
% 目前还没办法自适应设置步长,需要用户多次尝试
step = 5;
% 绘制散点图时,点的大小
% 目前还没办法让程序根据生成图像的大小自动调节点的大小,需要用户多次尝试
ptsize = 15;
X = floor(X / step + step / 2) * step + step / 2;
Y = floor(Y / step + step / 2) * step + step / 2;
%%
XY = unique([X, Y], 'rows');
Z = zeros(size(XY, 1), 1); % 点密度的颜色即根据Z值进行绘制
for i = 1 : length(Z)
disp([i, length(Z)]);
idx = find(X == XY(i, 1) & Y == XY(i, 2));
Z(i) = length(idx);
end
%%
% 绘图
figure(1);
gc = get(gca);
set(gcf, 'position', [50, 50, 720, 600]);
backColor = [0.9 0.9 0.9];
set(gca, 'color', backColor);
set(gca, 'FontName', 'Arial', 'FontSize', 15);
xlabel('Observation', 'FontSize', 15, 'FontName', 'Arial');
ylabel('Simulation', 'FontSize', 15, 'FontName', 'Arial');
hold on;
% 如果点特别集中于某一部分而看不到差异,可以将Z改成log(Z)
% 如果分布比较均匀,则直接使用Z
s = scatter(XY(:, 1), XY(:, 2), ptsize, log(Z), 'filled', 's');
colorbar;
colormap(jet);
% set(colorbar, 'YTick', 50 : 50 : 150);
hold on;
plot([-10 ^ 8 10 ^ 8], [-10 ^ 8 10 ^ 8], 'k-', 'LineWidth', 1.25);
maxXY = max(XY(:));
minXY = min(XY(:));
xlim([minXY - 2 * step, maxXY + 2 * step]);
ylim([minXY - 2 * step, maxXY + 2 * step]);
rr = axis;
plot(rr(1:2), [rr(4), rr(4)], 'k-', [rr(2), rr(2)], rr(3:4), 'k-');
hold on;