Smooth 2D colormap based on non-evenly distributed data

24 views (last 30 days)
Hello eveyone
I am trying to find an optimal way to represent, in a smooth 2D colormap, the data that I am attaching in this post. In said file, in each row you can find the (x,y) coordinates (first and second columns, respectively) that correspond to a field value (third column). The first way I have tried to represent this data is through scatter, but the color map is not particularly smooth, plus if I do set my xlim([0 100]) and ylim([0 100]) (which is what I want), the points end up completely hiding the plot box (the x- and y-th axes). On the other hand, I have thought about reordering this data in such a way that it is compatible with imagesc (or with the uimagesc function, https://es.mathworks.com/matlabcentral/fileexchange/11368-uimage-uimagesc, which it is suitable for non-evenly distributed reference positions). For this, as far as I know, I need to rearrange my data. My approach (probably not the most efficient one, and even less in this case) would usually be:
data=load('Data.txt');
space_x=unique(data(:,1));
space_y=unique(data(:,2));
field=NaN(length(space_x),length(space_y));
for i=1:length(data(:,1))
ix_space_x=find(space_x==data(i,1));
ix_space_y=find(space_y==data(i,2));
field(ix_space_x,ix_space_y)=data(i,3);
end
field_extended=inpaintn(field);
where inpaints would be given by https://es.mathworks.com/matlabcentral/fileexchange/27994-inpaint-over-missing-data-in-1-d-2-d-3-d-nd-arrays?s_tid=srchtitle. After I would just do uimagesc(space_x,space_y,field'). But for this particular data set, it seems that there are not enough close non-NaN neighbouring data points to fill the field_extended data properly.
Could someone point to me a suitable route to display my data set in a smooth and not very time consuming way?

Accepted Answer

Star Strider
Star Strider on 4 Dec 2023
Edited: Star Strider on 4 Dec 2023
I am not certain that I understand what result you want.
Try this —
data = readmatrix('Data.txt');
figure
scatter3(data(:,1), data(:,2), data(:,3), 10, data(:,3), '.')
colormap(turbo)
Spacefcn = scatteredInterpolant(data(:,1), data(:,2), data(:,3));
xv = linspace(min(data(:,1)), max(data(:,1)), 250);
yv = linspace(min(data(:,2)), max(data(:,2)), 250);
[X,Y] = meshgrid(xv, yv);
Z = Spacefcn(X, Y);
figure
surfc(X, Y, Z, 'EdgeColor','interp')
grid
colormap(turbo)
xlabel('X')
ylabel('Y')
zlabel('Z')
figure
surf(X, Y, Z, 'EdgeColor','interp')
grid
colormap(turbo)
xlabel('X')
ylabel('Y')
zlabel('Z')
view(0,90)
figure
surf(X, Y, Z, 'EdgeColor','interp', 'FaceColor','interp')
grid
colormap(turbo)
xlabel('X')
ylabel('Y')
zlabel('Z')
view(0,90)
% return
%
% % data=load('Data.txt');
% space_x=unique(data(:,1));
% space_y=unique(data(:,2));
% field=NaN(length(space_x),length(space_y));
% for i=1:length(data(:,1))
% ix_space_x=find(space_x==data(i,1));
% ix_space_y=find(space_y==data(i,2));
% field(ix_space_x,ix_space_y)=data(i,3);
% end
% field_extended=inpaintn(field);
EDIT — (4 Dec 2023 at 15:00)
Increased ‘xv’ and ‘yv’ resolution from 100 to 250, added third plot using both 'EdgeColor','interp', and 'FaceColor','interp'. Code otherwise unchanged.
There is some sort of central ‘spike in the interpolated data at (50,50) in the matrix. That can be eliminated with a filloutliers call —
[maxZ,idx] = max(Z(:));
[r,c] = ind2sub(size(Z), idx);
ofst = -50:50;
Z(r+ofst,c+ofst) = filloutliers(Z(r+ofst,c+ofst), 'nearest');
figure
surfc(X, Y, Z, 'EdgeColor','interp', 'FaceColor','interp')
grid
colormap(turbo)
xlabel('X')
ylabel('Y')
zlabel('Z')
.

More Answers (1)

Mathieu NOE
Mathieu NOE on 4 Dec 2023
Edited: Mathieu NOE on 4 Dec 2023
hello
why not simply this ?
see Fex submission :
data=load('Data.txt');
x = data(:,1);
y = data(:,2);
z = data(:,3);
% This demonstrates the basic usage of RegularizeData3D.
% FEX : https://fr.mathworks.com/matlabcentral/fileexchange/46223-regularizedata3d
% Set the smoothness. See the documentation for details about the smoothness setting.
Smoothness = 1e-4;
xx = linspace(min(x),max(x),200);
yy = linspace(min(y),max(y),200);
zz = RegularizeData3D(x, y, z, xx, yy, 'interp', 'bicubic', 'smoothness', Smoothness);
% Plot this figure on the left.
subplot1 = subplot(1, 1, 1, 'Parent', figure);
set(gcf, 'color', 'white');
view(subplot1,[-74.5, 14]);
grid(subplot1, 'on');
hold(subplot1, 'all');
% View the surface.
surf(xx, yy, zz, 'facealpha', 0.5);
% Add the input points to see how well the surface matches them.
% The smoothness value is the only thing that controls this property of the surface.
scatter3(x, y, z, 5, 'r', 'fill');
xlabel('x');
ylabel('y');
zlabel('z');
title({'Regularized output surface'; 'Original, scattered input points in blue'});
set(get(gca,'XLabel'),'FontSize', 12)
set(get(gca,'YLabel'),'FontSize', 12)
set(get(gca, 'Title'), 'FontSize', 14)
  1 Comment
Mathieu NOE
Mathieu NOE on 4 Dec 2023
of course you can add an imagesc plot from there
% new plot
figure
imagesc(xx, yy, zz);
colorbar('vert')

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!