Showing Covariance in a 3D graph - matlab

I have a 3D scatter plot and I want to visually show COVARIANCE on it. One can show COVARIANCE, for example with an ISO LINE. With this method, one generally gets an ellipse aligned with the shape of the scatter plot. Do you know how I can do this with MATLAB or any other method.
Thanks

I don't understand how would you like to display covariance on a 3D plot. I think what you are looking for is pca , it would give you the three vectors corresponding to maximum variance in your 3D scatter plot. You can then determine the variance along each of those vectors and plot an ellipsoid which represents sort of a confidence region. The final figure would something like this:
There is a little bit of Linear algebra and rotation matrices knowledge involved with this approach.

Related

finding gradient/curvature of surface defined by arbitrary, non-grid-spaced points

So I have a 3 dimensional matrix of points that (presumably) define a surface. For my purposes, X and Y can be random values but when plotted along with their Z coordinates, they will define some undulating surface. I'd like to measure the local curvatures of said surface, and in order to do that, I need to be able to find the gradient of said surface, at which point calculating the curvature is trivial.
I have not yet found an implementation of how to measure this curvature that doesn't make use of Matlab's gradient function. The problem with Matlab's gradient function is that it assumes that the points are in some sort of order, similar to diff(X). This would suffice if my points were spaced along a grid, which is not necessarily the case.
One possible solution to measuring the gradient is to give in and assign each point to a discrete coordinate in a grid in the XY plane, thus overcoming this issue. However, this solution seems somewhat inelegant and was curious to see if anyone had suggestions. Thanks!
You can use griddata to interpolate from your scattered data points to grid spaced points and then calculate the gradient.

Plot 3D surface that is not the graph of a function

I have a 3D data set of a surface that is not a function graph. The data is just a bunch of points in 3D, and the only thing I could think of was to try scatter3 in Matlab. Surf will not work since the surface is not a function graph.
Using scatter3 gave a not so ideal result since there is no perspective/shading of any sort.
Any thoughts? It does not have to be Matlab, but that is my go-to source for plotting.
To get an idea of the type of surface I have, consider the four images:
The first is a 3D contour plot, the second is a slice in a plane {z = 1.8} of the contour. My goal is to pick up all the red areas. I have a method to do this for each slice {z = k}. This is the 3rd plot, and I like what I see here a lot.
Iterating this over z give will give a surface, which is the 4th plot, which is a bit noisy (though I have ideas to reduce the noise...). If I plot just the black surface using scatter3 without the contour all I get is a black indistinguishable blob, but for every slice I get a smooth curve, and I have noticed that the curves vary pretty smoothly when I adjust z.
Some fine-tuning will give a much better 4th plot, but still, even if I get the 4th plot to have no noise at all, the result using scatter3 will be a black incomprehensible blob when plotted alone and not on top of the 3D contour. I would like to get a nice picture of the full surface that is not plotted on top of the 3D contour plot
In fact, just to compare and show how bad scatter3 is for surfaces, even if you had exact points on a sphere and used scatter3 the result would be a black blob, and wouldn't even look like a sphere
Can POV-Ray handle this? I've never used it...
If you have a triangulation of your points, you could consider using the trisurf function. I have used that before to generate closed surfaces that have no boundary (such as polyhedra and spheres). The downside is that you have to generate a triangulation of your points. This may not be ideal to your needs but it definitely an option.
EDIT: As #High Performance Mark suggests, you could try using delaunay to generate a triangulation in Matlab
just wanted to follow up on this question. A quick nice way to do this in Matlab is the following:
Consider the function d(x, y, z) defined as the minimum distance from (x, y, z) to your data set. Make sure d(x, y, z) is defined on some grid that contains the data set you're trying to plot.
Then use isosurface to plot a (some) countour(s) of d(x, y, z). For me plotting the contour 0.1 of d(x, y ,z) was enough: Matlab will plot a nice looking surface of all points within a distance 0.1 of the data set with good lighting and all.
In povray, a blob object could be used to display a very dense collection of points, if you make them centers of spheres.
http://www.povray.org/documentation/view/3.6.1/71/
If you want to be able to make slices of "space" and have them colored as per your data, then maybe the object pattern (based on a #declared blob object) might do the trick.
Povray also has a way to work with df3 files, which I've never worked with, but this user appears to have done something similar to your visualization.
http://paulbourke.net/miscellaneous/df3/

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?

Plotting 3-D Matrix *values* in MATLAB

I have a 3D Matrix M(256x256x136) and each index(i,j,k) in M has a gray level value in it. I am interested in displaying M in some sort of a 3D plot in MATLAB, but am unable to do so. I cannot use plot3 because plot3 is for plotting points, not the values.
Thanks
If I understand your question correctly, you want to plot the 3D point cloud with i,j, and k as 3D coordinates and the gray level as the point value.
I would suggest using scatter3.
Sounds like you are looking for a volume renderer. For Matlab, you could try this one: Volume Render from Matlab Central
An isosurface plot might be useful as well.

plot a set of 3D data in different angles in MATLAB

I have a formula that depends on theta and phi (spherical coordinates 0<=theta<=2*pi and 0<=phi<=pi). By inserting each engle, I obtained a quantity. Now I have a set of data for different angles and I need to plot the surface. My data is a 180*360 matrix, so I am not sure if I can use SURF or MESH or PLOT3. The figure should be a surface that include all data and the axes should be in terms of the quantity, not the quantity versus the angles. How can I plot such a surface?
I see no reason why you cannot use mesh or surf to plot such data. Another option I tend to use is that of density plots. You basically display the dependent variable (quantity) as an image and include the independent variables (angles) along the axis, much like you would with the aforementioned 3D plotting functions. This can be done with imagesc.
Typically you would want your axes to be the dependent variables. Could you elaborate more on this point?
If I understand you correctly you have calculated a function f(theta,phi) and now you want to plot the surface containing all the points with the polar coordinated (r,theta,phi) where r=f(theta,phi).
If this is what you want to do, the 2D version of such a plot is included in MATLAB under the name polar. Unfortunately, as you pointed out, polar3 on MatlabCentral is not the generalization you are looking for.
I have been able to plot a sphere with the following code, using constant r=1. You can give it a try with your function:
phi1=0:1/(3*pi):pi; %# this would be your 180 points
theta1=-pi:1/(3*pi):pi; % your 360 points
r=ones(numel(theta1),numel(phi1));
[phi,theta]=meshgrid(phi1,theta1);
x=r.*sin(theta).*cos(phi);
y=r.*sin(theta).*sin(phi);
z=r.*cos(theta);
tri=delaunay(x(:),y(:),z(:));
trisurf(tri,x,y,z);
From my tests it seems that delaunay also includes a lot of triangles which go through the volume of my sphere, so it seems this is not optimal. So maybe you can have a look at fill3 and construct the triangles it draws itself: as a first approximation, you could have the points [x(n,m) x(n+1,m) x(n,m+1)] combined into one triangle, and [x(n+1,m) x(n+1,m+1) x(n+1,m+1)] into another...?