Surface plot not displaying full data range

42 views (last 30 days)
I am trying to display the energy of a defect at various positions in a unit cell using a surface plot. I have data for 0.0 to 0.5 in each dimension so wish to display it as 'slices' through z with the colour displaying the energy value i.e. using surf(x,y,z,c) where c is the energy data.
For example, here are the energy values for z = 0
NaN NaN NaN 3.28 1.63 1.04
NaN NaN 10.26 3.02 1.95 1.63
NaN 10.26 3.81 3.50 3.02 3.28
3.28 3.02 3.50 3.81 10.26 NaN
1.63 1.95 3.02 10.26 1.63 NaN
1.04 1.63 3.28 NaN NaN NaN
The data is somewhat symetrical however when I plot the surface without using 'interp' it does not reflect this: here is the surface plot using 'interp'
Here is the plot without:
I would like to plot it without 'interp' as this would better represent my data (I do not know if it is a smooth transition in energy as indicated by the gradients)
As you can see for the first plot the full range of data is displayed - I dont understand why the plots are so different or how to solve this
Is it possible for the colour squares to be centred on the vertices? So that my full range of data is shown, i.e. (0.5,0.5,0) should be white due to NaN but in above plot is green.
I have tried simply extending the axis of my graph but that does not help, it just displays no data for the additional area.
My script is:
Thank you!!
figure
colormap hsv
mesh(X,Y,Z,K)
%shading interp
colorbar
caxis([-0.5 10.5])
xlabel('x'); ylabel('x'); zlabel('z')
xlim([0.0,0.5])
ylim([0.0,0.5])
zlim([0.0,0.5])

Accepted Answer

Cris LaPierre
Cris LaPierre on 17 Nov 2020
Edited: Cris LaPierre on 17 Nov 2020
I think there are a couple factors here.
  1. The mesh lines represent your data. The colored squares represent the space between your measurements.
  2. Because of the courseness of the grid, 'interp' is better able to show the symmetry.
I have two ideas. First, consider adding an extra row and column of NaNs to create the symmetry you want.
e=[NaN NaN NaN 3.28 1.63 1.04
NaN NaN 10.26 3.02 1.95 1.63
NaN 10.26 3.81 3.50 3.02 3.28
3.28 3.02 3.50 3.81 10.26 NaN
1.63 1.95 3.02 10.26 1.63 NaN
1.04 1.63 3.28 NaN NaN NaN];
% pad with NaNs
e2=e;
e2(:,7)=NaN;
e2(7,:)=NaN
e2 = 7×7
NaN NaN NaN 3.2800 1.6300 1.0400 NaN NaN NaN 10.2600 3.0200 1.9500 1.6300 NaN NaN 10.2600 3.8100 3.5000 3.0200 3.2800 NaN 3.2800 3.0200 3.5000 3.8100 10.2600 NaN NaN 1.6300 1.9500 3.0200 10.2600 1.6300 NaN NaN 1.0400 1.6300 3.2800 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
x=linspace(0,0.6,7);
y=x;
figure
surf(x,y,zeros(size(e2)),e2,"FaceColor","flat")
colorbar
xlim([0,0.6])
ylim([0,0.6])
zlim([0,0.5])
My other idea is to use a different techinique to visualize the data. There is one less square per number of data points in X and Y, so essentially your data for x=0.5 and y=0.5 is not being shown. In order to visualize your data without resorting to padding your matrix, consider using heatmap, imagesc, or similar method.
figure
heatmap(e)
colormap jet
figure
imagesc(e)
One comment - Since you have numeric values at both the top and bottom of your scale, I would avoid using the hsv colormap. It has very similar colors at the top and bottom (red), which could cause confusion. This was particularly noticeable in these last 2 figures.
  1 Comment
RoseM
RoseM on 17 Nov 2020
Thank you so much adding the extra row and column works perfectly! Thank you for taking the time to explain it all to me thats excellent!
I think I'll use heatmap as well for the plots of particular interest, thank you for the suggestion.
Great shout about hsv I hadn't noticed that
A million thanks your way!! :)

Sign in to comment.

More Answers (2)

Bjorn Gustavsson
Bjorn Gustavsson on 17 Nov 2020
Once uppon a time...
...I was very annoyed with this behaviour of matlab's surf and pcolor functions - it treats the values and coordinates as the values and coordinates at the vertices, while for my data, as for yours, it was/is much more natural to view them as the values at the centre of a "pixel-region". Using shading flat or shading faceted the last row and column vanishes from the plot. My quick-and-dirty workaround was to add copies of the last row and column to the data-matrix and shift the coordinates "half a step" in the other direction, it worked "reasonably OK" for cases where the grid was not overly curved. Something like this:
function h = bcolor2(x,y,c)
% BCOLOR Pseudocolor (checkerboard) plot.
% BCOLOR(C) is a pseudocolor or "checkerboard" plot of matrix C.
% The values of the elements of C specify the color in each
% cell of the plot. Each cell has a constant color and all cells
% of C used.
% The smallest and largest elements of C are assigned the first
% and last colors given in the color table; colors for the
% remainder of the elements in C are determined by table-lookup
% within the remainder of the color table.
c = [c,c(:,end)];
c = [c;c(end,:)];
c = c;
dx = gradient(x);
dy = gradient(y);
x_new(1) = x(1)-dx(1)/2; % x(1)-dx(1)/2+cumsum(dx)];
x_new = [x_new;x(1)-dx(1)/2+cumsum(dx(:))];
y_new(1) = y(1)-dy(1)/2; % y(1)-dy(1)/2+cumsum(dy')'];
y_new = [y_new;y(1)-dy(1)/2+cumsum(dy(:))];
hh = pcolor(x_new,y_new,c);shading flat
if nargout
h = hh;
end
Another way to plot your data would be to use scatter (or scatter3).
HTH

Bruno Luong
Bruno Luong on 21 Nov 2020
Cross answer

Categories

Find more on Data Distribution Plots in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!