Drawing a mesh of a triangular matrix in Matlab - matlab

I have been trying to figure out how to "hide" the useless part of the triangular matrix from my 3d plot in Matlab.
I have tried drawing a mesh just above that part of the graph with
'EdgeAlpha', 1, 'FaceAlpha', 1,'FaceColor','w','EdgeColor','none'
but it does not help. How should I do it instead?
The only method the semi-worked is using the color scale, but it did not work all the way, plus I need the black and white eps's, which will show the color as black even if it looks white originally...
This is my last hope ;)
Barbara

Short answer: replace "useless" data with the value nan because MATLAB does not plot data values that are nan.
Inserting nan values into the other half of the matrix should do the trick. See the example below - it's clunky, but should give the idea. I chose to multiply by nan, which I attained as shown, but there are half a dozen other things that came to mind.
% Create random data for illustration
data = tril(rand(50));
% I chose to divide by a lower triangular ones matrix (zeros above the
% diagonal) to get nan above the diagonal and ones below
nan_above_diag_ones_below = 1./tril(ones(50,50));
% Plot data with and without hiding the "useless part"
figure,
subplot(1,2,1), mesh(data), title('"useless" part shown')
subplot(1,2,2), mesh(data.*nan_above_diag_ones_below),
title('"useless" part hidden')

Related

Is it possible to change the 'colormap' scale in Matlab?

I have 2 matrices. Matrix A contains values between 0 and 1 and matrix B contains values between 0 and 90. I would like to display an image with a different color for the numbers in each matrix.
When I use the colormap function with:
figure; colormap(jet); imshow(A);
The image displayed has several levels of gray, when I am supposed to have several colors (because I am using jet).
When I use the colormap function with:
figure; colormap(jet); imshow(B);
The image displayed is completely white, probably because my values are higher than 64 (which is the max of jet).
How can I solve these two problems? I read a lot of tutorials in several forums but I can't find the answer...
Thank you very much for answering my problem!
Just normalize the matrix by its max value if the values are more than 1. So for your B matrix try:
imshow(B/max(B(:)))
You can specify the colormap scaling and the number of actual colors within the colormap like so:
figure; imshow( A, [0 1], 'Colormap', jet(100) );
figure; imshow( B, [0 100], 'Colormap', jet(100) );
The jet(100) indicates 100 unique colors within the colormap to be used.
You are using the wrong function for the task in hand.
imshow expects an N by M by 3 array input, of the RGB channels of an image. When you use a 2D matrix the function assumes it's a grayscale image (it's like replicating it to 3 identical matrices to create these three channels - if all the channels in RGB have the same values you get grayscale colors). You can use this function together with a colormap to get a colored matrix, but there are much more convenient alternatives.
One simple function for getting a colored representation of a matrix is imagesc or (image if you want to scale the values by yourself). This function takes the values in your matrix, and assign them a color from the colormap you choose:
A = rand(10);
figure; colormap(jet); imagesc(A);
Another option is pcolor, which works a little different but give a similar result. pcolor attach the values to the vertices of the cells (in oppose to the center, as imagesc does), and interpolate the color in each cell from its' vertices. The resulted colored matrix is always smaller in one row and one column because it takes n+1 points (values in the original matrix) to define n gaps (the cells in the colored matrix). Here is an example:
A = rand(10);
figure; colormap(jet); pcolor(A);
shading flat

Color Code MatLab Histogram Based on a Condition of a 2x2 Matrix

if I have a 2x2 Matrix such as
1 2
4 7
And I want to plot a histogram based on the condition that the diagonals should be the color green, and everything else except the diagonals should be red, how do I do that in Matlab.
I have tried separating the 2x2 matrix into two different vectors representing the diagonal and the others (except diagonals), but when I do:
hist(diagonals)
hist(others)
It doesn't really work and seems to just randomly color code things into one histogram (I do want just the one histogram though.) How do I do this correctly?
Found a solution to my problem, using hold on fixes this issue
histogram(diagonals, 'FaceColor', 'g')
hold on
histogram(others, 'FaceColor', 'r')
hold on

matlab - plot square matrix by row

Plot uses columns to plot a square matrix, but I need it by rows.
plot(matrix(1:end,1:end), 1:columns)
works great when matrix is rectangular (plots each line of matrix with a different color), but when matrix is square is plots by column (as the documentation clearly states)
I don't want to break the command to a loop because then I will have to specify the color for each line plot.
Is there a way to change the plot defaults to prefer row in square matrices?
You can use a trick and add a line of NaN at the end of the array:
matrix(end+1,:) = NaN;
And now matrix is rectangular, but the NaN won't be displayed during plot.
Best,

Improve surface plot visualisation of scatter points

I want to visualize 4 vectors of scattered data with a surface plot. 3 vectors should be the coordinates. In addition the 4th vector should represent a surface color.
My first approach was to plot this data (xk,yk,zk,ck) using
scatHand = scatter3(xk,yk,zk,'*');
set(scatHand, 'CData', ck);
caxis([min(ck), max(ck)])
As a result I get scattered points of different color. As these points lie on the surface of a hemisphere it ist possible to get colored faces instead of just points. I replace the scattered points by a surface using griddata to first build an approximation
xk2=sort(unique(xk));
yk2=sort(unique(yk));
[xxk, yyk]=meshgrid(xk2, yk2);
zzk=griddata(xk,yk,zk,xxk,yyk,'cubic');
cck=griddata(xk,yk,clr,xxk,yyk,'cubic');
surf(xxk,yyk,zzk,cck);
shading flat;
This is already nearly what I want except that the bottom of the hemisphere is ragged. Of course if I increase the interpolation point numbers it gets better but than the handling of the plot gets also slow. So I wonder if there is an easy way to force the interpolation function to do a clear break. In addition it seems that the ragged border is because the value of zzk gets 'NaN' outside the circle the hemisphere shares with the z=0-plane.
The red points at the top are the first several entries of the original scattered data.
You can set the ZLim option to slice the plotted values within a certain range.
set(gca, 'Zlim', [min_value max_value])

Matlab 3d plot of indexed data

I am trying to plot a 3d view of a very large CT dataset. My data is in a 3d matrix of 2000x2000x1000 dimension. The object is surrounded by air, which is set to NaN in my matrix.
I would like to be able to see the greyscale value of the surface of the object (no isosurface) but I cannot quite work out how to do that in Matlab. Can anyone help me please?
Given that I a dealing with a huge matrix and I am only interested in the surface of the object, does anyone know a good trick how to reduce the size of my dataset?
The function surf(X,Y,Z) allows you to plot 3d data, where (X,Y) gives the coordinates in the x-y-plane while Z gives the z-coordinate and the surface color.
By default the function does not plot anything for the NaN entries, so you should be good to go with the surf function.
To set the surf-function to use a grayscale plotting use:
surf(matrix3d);
colormap(gray);
This plots the matrix in a surface plot and sets the colormap to grayscale.
In addition, as I understand your data, you might be able to eliminate entire plane-segments in your matrix. If for instance the plane A(1,1:2000,1:1000) is NaN in all entries you could eliminate all those entries (thus the entire Y,Z-plane in entry X=1). This will however require some heavy for loops, which might be over the top. This depends on how many data matrices you have compared to how many different plot you want for each matrix.
I will try to give you some ideas. I assume lack of a direct 3D "surface detector".
Since you have a 3D matrix where XY-planes are CT scan slices and each slice is an image, I would try to find edges of each slice say with edge. This would require some preprocessing like first thresholding each slice image. Then I can either use scatter3 to display the edge data as a 3D point cloud or delaunay3 to display the edge data as a surface.
I hope this will help you achieve what you are asking for.
I managed to get it working:
function [X,Y,Z,C] = extract_surface(file_name,slice_number,voxel_size)
LT = imread(file_name);%..READ THE 2D MAP
BW = im2bw(LT,1);%..THRESHOLD TO BINARY
B = bwboundaries(BW,8,'noholes');%..FIND THE OUTLINE OF THE IMAGE
X = B{1}(:,1);%..EXTRACT X AND Y COORDINATES
Y = B{1}(:,2);
indices = sub2ind(size(LT),X,Y);%..FIND THE CORRESPONDING LINEAR INDICES
C = LT(indices);%..NOW READ THE VALUES AT THE OUTLINE POSITION
Z = ones(size(X))*slice_number;
I can then plot this with
figure
scatter3(X,Y,Z,2,C)
Now the only thing I could improve is to have all these points in the scatter plot connected with a surface. #upperBound you suggested delaunay3 for this purpose - I cannot quite figure out how to do this. Do you have a tip?