Matlab 3D plot on Cylindrical Axes - matlab

I've run simulations which have given me data points corresponding to X number of different radii, and Y number of angles each one was evaluated at. This means that I have X times Y data points which I need to plot.
I am currently plotting it in an non-ideal fashion: I am using the x and y axes as the r and theta axes. This means that my data appears as a sinusoidal trend which increases with radius on a Cartesian grid, not the circle which it physically represents. This is how I am currently plotting my data:
surf(r_val, th_val, v_val);
What I wish to do is plot my data on a cylindrical axis, such like that of the function polar(), but in R3 space. I would rather not download a toolbox, or modify the existing polar function; if there is no other solution then I will obviously end up doing this anyways.
Thanks for your help!
G.
Also, I am using Matlab 2012a
EDIT:
r_val = 1x8 vector containing unique radii
th_val = 1x16 vector containing unique angles
v_val = 8x16 matrix containing voltages corresponding to each position
NOTE: (after answered)
The truly ideal solution does not exist to this problem, as Matlab currently supports no true polar axes methods. Resource found here.

You should transform your coordinates to Cartesian coordinates before plotting them. MATLAB has builtin functions for perfroming coordiante transformations. See, for example pol2cart, which transforms polar or cylindrical coordinates to Cartesian coordinates. In your case you would simply use something like:
[x, y] = pol2cart(th_val, r_val);
surf(x, y, v_val);
Edit: Given that th_val and r_val are vectors of differing lengths it is necessary to first create a grid of points before calling pol2cart, along the lines of:
[R, T] = meshgrid(r_val, th_val);
[x, y] = pol2cart(T, R);
surf(x, y, v_val);

Related

How can I create a slice of a surface plot to create a line? (Matlab)

Given some function z = f(x,y), I'm interested in creating a (1D) line plot along an arbitrary cutting plane in x,y,z. How do I do this in Matlab? Slice, for example, provides a higher dimensional version (colormap of density data) but this is not what I'm looking for.
E.g.:
z = peaks(50);
surf(z);
%->plot z along some defined plane in x,y,z...
This has been asked before, e.g. here, but this is the answer given is for reducing 3D data to 2D data, and there is no obvious answer on googling. Thanks.
If the normal vector of the plane you want to slice your surface will always lay in the xy plane, then you can interpolate the data over your surface along the x,y coordinates that are in the slicing line, for example, let the plane be defined as going from the point (0,15) to the point (50,35)
% Create Data
z=peaks(50);
% Create x,y coordinates of the data
[x,y]=meshgrid(1:50);
% Plot Data and the slicing plane
surf(z);
hold on
patch([0,0,50,50],[15,15,35,35],[10,-10,-10,10],'w','FaceAlpha',0.7);
% Plot an arbitrary origin axis for the slicing plane, this will be relevant later
plot3([0,0],[15,15],[-10,10],'r','linewidth',3);
Since it is a plane, is relatively easy to obtain the x,y coordinates alogn the slicing plane with linspace, I'll get 100 points, and then interpolate those 100 points into the original data.
% Create x and y over the slicing plane
xq=linspace(0,50,100);
yq=linspace(15,35,100);
% Interpolate over the surface
zq=interp2(x,y,z,xq,yq);
Now that we have the values of z, we need against what to plot them against, that's where you need to define an arbitrary origin axis for your splicing plane, I defined mine at (0,15) for convenience sake, then calculate the distance of every x,y pair to this axis, and then we can plot the obtained z against this distance.
dq=sqrt((xq-0).^2 + (yq-15).^2);
plot(dq,zq)
axis([min(dq),max(dq),-10,10]) % to mantain a good perspective

MATLAB: Area and centre of mass of a plotted figure

I have made a function that allows a user to draw several points and interpolate those points. I want the function to calculate the centre of mass using this vector :
I think I should therefore first calculate the area of the figure (I drew this example to illustrate the function output). I want to do this using Green's theorem
However since I'm quite a beginner in MATLAB I'm stuck at how to implement this formula in order to find the centre of mass. I'm also not sure how to get the data as my output so far is only the x- and y cordinates of the points.
function draw
fig = figure();
hax = axes('Parent', fig);
axis(hax, 'manual')
[x,y] = getpts();
M = [x y]
T = cumsum(sqrt([0,diff(x')].^2 + [0,diff(y')].^2));
T_i = linspace(T(1),T(end),1000);
X_i = interp1(T,x',T_i,'cubic');
Y_i = interp1(T,y',T_i,'cubic');
plot(x,y,'b.',X_i,Y_i,'r-')
end
The Center Of Mass for a 2D coordinate system should just be the mean of the interpolated x-coordinates and y-coordinates. The Interpolation should give you evenly spaced coordinates which you can use to your advantage. So simply add to your existing function:
CenterOfMass= [mean(X_i),mean(Y_i)]
plot(x,y,'b.',X_i,Y_i,'r-')
hold on
plot(CenterOfMass(1),CenterOfMass(2),'ro')
should give you the center of mass assuming that all points are weighted equally.

Data visualization - surface with parametric colour

I have a set of points in 3D in cartesian coordinates X,Y,Z. To every such point I associate a value which is stored in a vector C. I want to be able to colour the surface given by X,Y,Z with colors given by C. Alternatively, if possible, I would like to associate to each point a color from a finite number of given colors. In Matlab this is possible with surf(X,Y,Z,C), but X,Y must be in grid form (generated by meshgrid), not in general form, like in my case.
I managed to do this in the case of the sphere, but the procedure is not pretty, and it uses heavily the parametrization of the sphere. Here's an example of what I want to do (in the case of the sphere).
Is there a way to do this type of surface coloring in Matlab? (if it helps, I can also provide a triangulation of the surfaces in addition to the points X,Y,Z)
Is there another piece of software which can do similar things and can interface in some way with Matlab?
I based this off of Matlab's Representing Data as a Surface. Does this work?
xlin = linspace(min(x),max(x),33);
ylin = linspace(min(y),max(y),33);
[X,Y] = meshgrid(xlin,ylin);
f = scatteredInterpolant(x,y,z);
Z = f(X,Y);
g = scatteredInterpolant(x,y,c);
C = g(X,Y);
surf(X, Y, Z, C)
Thanks Ander Biguri for suggesting patch. Here's what I've come up with, and it seems to work fine.
function patch_color_plot(struc)
% struc is a structure containing at least the following:
% points - the coordinate of the points in a 3xN matrix
% t - the triangulation matrix
% x_0s - the point values
fac = struc.t;
vert = struc.points;
fvc = struc.x_0s;
p = patch('Faces',fac,'Vertices',vert,'FaceVertexCData',...
fvc,'FaceColor','interp');
set(p,'EdgeColor','none')
axis equal
axis off`
Here's a sample result:
and another one with a torus:
here's another example:

Matlab - Multiple 2D plots along a 3rd dimension

I'm trying to plot many 2D plots (x,y).
But...
each 2D plot is for a constant z.
So really my data is (x,y,z) but not z(x,y), which I believe are the requirements for using the "surf" command.
Could anyone help with this?
Example,
x = velocity
y = drag
I have multiple runs of y(x) for a constant temperature, z.
I just want to plot each (x,y) along a 3rd axis, temperature z.
Ideally I'd also want some sort of contour between the (x,y) plots so I can show the peaks/troughs etc.
Any help would be great.
If the runs are not independent (there is some trend over multiple runs) then it may make sense to use surf. You then need to construct your data such you have an X,Y, and Z - in this case I'd suggest you use the drag measurements as your Z (height).
Assuming that you have all the drag/velocity data in drag and velocity which are both of size [data points x number of runs]:
% construct matrix of run numbers
runs = repmat(1:numruns, [1, datapoints]);
runs = reshape(runs, datapoints, numruns);
% plot and label
surf(runs,velocity,drag);
xlabel('runs')
ylabel('velocity')
zlabel('drag')

How do I make a surf plot in MATLAB with irregularly spaced data?

I know I can create a 3D surface plot in MATLAB by doing:
x = linspace(1,10,100);
y = linspace(10,20,100);
[X Y] = meshgrid(x,y);
Z = X * Y;
surf(X,Y,Z);
But this requires that all the nodes for the height map generated line up. I have a set of data which has arbitrary points (x,y) and a height (z). Is there a simple way to plot a graph which will generate a surface between the points in a similar fashion to surf?
Appologies, after some hunting I managed to answer my own question:
You can use the trisurf function:
tri = delaunay(x,y);
trisurf(tri,x,y,z);
If you have dense data you will want to do shading interp (or another value, check doc shading) so you don't get a black blob due to the grid.
It looks like you've found your answer by using DELAUNAY and TRISURF to generate and plot a triangulated surface.
As an alternative, you could also fit a regularly-spaced grid to your nonuniformly-spaced points in order to generate a surface that can be plotted with the SURF command. I discuss how this can be done using the TriScatteredInterp class (or the deprecated function GRIDDATA) in my answer to this other question on SO.