Plotting a 2D array of values as discrete squares without interpolation
10 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
I believe my question is very similar to this one that never got answered:
I have a set of data that were measured by a 24 x 24 array of pressure sensors. The sensors measure pressure in the X, Y, and Z directions. Each sensor makes a discrete measurement of the average value of pressure over its surface. I want to plot these values as discrete colored squares.
The code below uses Surf:
load("StressData.mat");
figure;
subplot(1, 3, 1);
surf(z, "edgecolor", "none", "facecolor", "interp", "facealpha", 1);
title("Contact Pressure"); xlabel("X"); ylabel("Y");
axis equal; xlim([1, 24]); ylim([1, 24]); view([90, -90]);
colormap("Jet"); shading("interp");
subplot(1, 3, 2);
surf(x, "edgecolor", "none", "facecolor", "interp", "facealpha", 1);
title("X pressure"); xlabel("X"); ylabel("Y");
axis equal; xlim([1, 24]); ylim([1, 24]); view([90, -90]);
colormap("Jet"); shading("interp");
subplot(1, 3, 3);
surf(y, "edgecolor", "none", "facecolor", "interp", "facealpha", 1);
title("Y pressure"); xlabel("X"); ylabel("Y");
axis equal; xlim([1, 24]); ylim([1, 24]); view([90, -90]);
colormap("Jet"); shading("interp");
This interpolates between the values. I want to display each value discretely without interpolating. Note that the X and Y data have both positive and negative values. So when you change the viewpoint, the image looks like this:

An alternative is to use bar3. This plots the values as squares, but it has its own set of problems:
%% Plot data as individual pixels
figure;
subplot(1, 3, 1);
b = bar3(z, 1);
title("Contact Pressure"); xlabel("X"); ylabel("Y"); colormap("jet"); view([270, 90]);
for k = 1 : length(b)
b(k).FaceColor = 'flat';
b(k).CData(:, :) = repmat(b(k).ZData(:, 2), 1, 4);
end
subplot(1, 3, 2);
b = bar3(x, 1);
title("X pressure"); xlabel("X"); ylabel("Y"); colormap("jet"); view([270, 90]);
for k = 1 : length(b)
b(k).FaceColor = 'flat';
b(k).CData(:, :) = repmat(b(k).ZData(:, 2), 1, 4);
end
subplot(1, 3, 3);
b = bar3(y, 1);
title("Y pressure"); xlabel("X"); ylabel("Y"); colormap("jet"); view([270, 90]);
for k = 1 : length(b)
b(k).FaceColor = 'flat';
b(k).CData(:, :) = repmat(b(k).ZData(:, 2), 1, 4);
end
The main problem is that the bars have tops, sides, and bottoms and while I've figured out how to color the tops and the sides, I haven't been able to figure out how to color the bottoms, so the negative values get hidden. This is particularly apparent in the X and Y pressures (see below).

Am I on the right track? How do I color the bottoms of the bars?
4 Commenti
dpb
il 5 Set 2025
Modificato: dpb
il 5 Set 2025
My bad on the latter above; I forgot to delete the clean-up code...got interrupted and forgot where was when got back.
Probably, except they then would still be there, just with the colors instead of default black/near black; I guess on reflection they aren't anything except the bar outlines for the low-height bars. (<Doh!!>)
Unfortunately, I think those are handles only by the bar object and not settable in finer detail.
load StressData y
y(1:5,:);
isZ=(abs(y)<1); nnz(isZ);
h=bar3(y);
size(h);
for i=1:numel(h)
for j=1:size(y,1);
if abs(y(j,i))<1
h(i).CData((j-1)*6+[1:6],:)=nan;
end
end
h(i).EdgeColor=0.9*[1 1 1];
end
hAx=gca;
hF=figure;
copyobj(hAx,hF)
m=[h.CData]; [min(m,[],'all') max(m,[],'all')]
c=colormap;
maxH=max(m,[],'all');
ix=round(linspace(1,height(c),maxH))
for i=1:maxH
h(i).EdgeColor=c(ix(i),:);
end
matches the bar color so the edges disappear but, of course, puts the mesh back in darker so still can't really see the negative data.
Being unable to set the edges on a per individual bar basis pretty-much means this is a dead end and there's no 'none' property value for the edges.
dpb
il 6 Set 2025
Modificato: dpb
il 6 Set 2025
load StressData y
subplot(1,2,1);
hb = bar3(y);
title("P Y Top View"); xlabel("X"); ylabel("Y"); colormap("jet"); view([270, 90]);
for k=1:numel(hb)
hb(k).CData(:, :) = repmat(hb(k).ZData(:, 2), 1, 4);
end
ylim([1 inf])
subplot(1,2,2);
hb = bar3(y);
title("P Y Bottom View"); xlabel("X"); ylabel("Y"); colormap("jet");
for k=1:numel(hb)
hb(k).CData(:, :) = repmat(hb(k).ZData(:, 2), 1, 4);
end
hAx=gca;
view([270, -90]);
hAx.XDir='reverse';
ylim([1 inf])
figure
hb = bar3(y);
title("P Y 3D View"); xlabel("X"); ylabel("Y"); colormap("jet");
for k=1:numel(hb)
hb(k).CData(:, :) = repmat(hb(k).ZData(:, 2), 1, 4);
end
set(hb,{'FaceAlpha'},{0.5});
view(-37.5,15)
I was intrigued by the question about coloring the bottoms of the bars -- the bottoms are colored the same as the lowest bar sides as the bottom view above shows. The confusing factor here alone seems to be that there is no mechanism to not have a bar drawn for every element of the array whereas it appears what would really be desired would be to be able to draw only bars with values greater than some threshold? In my experiments above about setting the "zero" plane to transparent, it looks like almost all of those are abs(P)<1 and then there is a very sizable jump to the next smallest values.
I haven't experimented, but I think one would have to draw each bar individually as a totally separate object to be able to do that. MATLAB graphics functions, like array operations require regular grids with very few exceptions.
Risposta accettata
Più risposte (2)
dpb
il 7 Set 2025
Modificato: dpb
il 7 Set 2025
OK, I finally went and looked at File Exchange because I figured somebody else had already gotten fed up with bar3 issues and it turns out there was a very good start in <scatterbar3> of a 3D bar plot that puts individual bars at any location wanted.
It didn't have a way to deal with NaN data, but it didn't take much to make at least a first pass to treat it as do other MATLAB graphics functions...
function scatterbar3(X,Y,Z,width)
%SCATTERBAR3 3-D scatter bar graph.
% SCATTERBAR3(X,Y,Z,WIDTH) draws 3-D bars of height Z at locations X and Y with width WIDTH.
%
% X, Y and Z must be of equal size. If they are vectors, than bars are placed
% in the same fashion as the SCATTER3 or PLOT3 functions.
%
% If they are matrices, then bars are placed in the same fashion as the SURF
% and MESH functions.
%
% The colors of each bar read from the figure's colormap according to the bar's height.
% By Mickey Stahl - 2/25/02, Engineering Development Group
% Revised Duane Bozarth - 09/07/25, DB Technical Services
[r,c]=size(Z);
for j=1:r
for k=1:c
if isfinite(Z(j,k))
drawbar(X(j,k),Y(j,k),Z(j,k),width/2)
end
end
end
view(3) % dpb set default 3D perspective
grid on % dpb to add grid by default, too
minZ=min(Z,[],'all','omitnan'); maxZ=max(Z,[],'all','omitnan'); % dpb to handle NaN (gracefully?)
zlim=[minZ maxZ];
if zlim(1)>0,zlim(1)=0;end
if zlim(2)<0,zlim(2)=0;end
minX=min(X,[],'all','omitnan'); maxX=max(X,[],'all','omitnan'); % original didn't handle nan -- dpb
minY=min(Y,[],'all','omitnan'); maxY=max(Y,[],'all','omitnan');
% add if hold on to set additional points but don't make axis range smaller from existing -- dpb
if ishold(gca)
lim=axis();
minX=min(minX,lim(1)); maxX=max(maxX,lim(2));
minY=min(minY,lim(3)); maxY=max(maxY,lim(4));
zlim=[min(minX,lim(5)) max(maxZ,lim(6))];
axis([minX maxX minY maxY zlim])
caxis(zlim)
else
axis([minX-width maxX+width minY-width maxY+width zlim])
caxis([minZ maxZ])
end
function drawbar(x,y,z,width)
h(1)=patch([-width -width width width]+x,[-width width width -width]+y,[0 0 0 0],'b');
h(2)=patch(width.*[-1 -1 1 1]+x,width.*[-1 -1 -1 -1]+y,z.*[0 1 1 0],'b');
h(3)=patch(width.*[-1 -1 -1 -1]+x,width.*[-1 -1 1 1]+y,z.*[0 1 1 0],'b');
h(4)=patch([-width -width width width]+x,[-width width width -width]+y,[z z z z],'b');
h(5)=patch(width.*[-1 -1 1 1]+x,width.*[1 1 1 1]+y,z.*[0 1 1 0],'b');
h(6)=patch(width.*[1 1 1 1]+x,width.*[-1 -1 1 1]+y,z.*[0 1 1 0],'b');
set(h,'facecolor','flat','FaceVertexCData',z)
end
end
load StressData y
z=y; % rename height variable
[x,y]=meshgrid(1:height(y),1:width(y)); % doesn't implement the Z only input option
colormap(jet)
%subplot(1,2,1)
scatterbar3(x,y,z,1)
title('Include all data -- looks like bar3')
%subplot(1,2,2)
figure
z(abs(z)<=1)=nan; % remove the very small (relatively speaking) "baseline" data
scatterbar3(x,y,z,1)
colormap(jet)
colormap(jet)
title('Exclude baseline data -- no baseline mesh occlusion')
I think this is more like what you were hoping to be able to produce? There is another that also has high marks that says the individual bars are addressable, but I didn't look at it. The big disadvantage of this one is that each bar consists of six patch objects and the author didn't make any attempt to organize and save them but reuses the handles. This means it isn't convenient to get to any specific bar to make any other changes as is. But, it wouldn't take too much to save the handles in their groups of six and then by bar location which would make it possible to address each bar face.
I attached the updated version; the pasted copy has the additional help text expunged to shorten it...I'm not sure what the protocol is on FEX about putting up the derivative; it's unfortunate there's no way to make make contributions to existing posts.
0 Commenti
Steven Lord
il 29 Lug 2025
load('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1838126/StressData.mat')
whos
If I understand what you're trying to do, you want to use the Z data for both the elevation and the color of the face?
surf(z, z);
colormap('jet')
colorbar
Let's look at it from above.
figure
surf(z, z);
colormap('jet')
colorbar
view(2)
What if your data included both positive and negative values? I'll also move the "outer ring" so that some of the values in your data are above that ring and some are below.
figure
zm = z - 150;
zm(z < 10) = -50; % move the "bottom" up so the outer ring is not on the floor
surf(zm, zm);
colormap('jet')
colorbar
And if you were to view it from below?
figure
surf(zm, zm);
colormap('jet')
colorbar
view([0 0 -1])
If that's not what you're looking for, please provide more details (in word rather than in code or pictures) of what you'd like to see to help me better understand your goal.
1 Commento
Vedere anche
Categorie
Scopri di più su Data Distribution Plots in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!














