How to plot a 3D surface with a circle in it? - matlab

I have a rational polynomial function. I find zeros of numerator and denominator of it. Now I want to draw this function and I do it with meshgrid and mesh command in matlab. How can I draw a circle in this shape? I add my result figure at first and second figure is an image that I want to be like that( draw red circle).

Create x and y for your circle:
r = 1;
theta = 0:0.1:2*pi;
x = r*cos(theta);
y = r*sin(theta);
Get the value of your function at the x and y's and plot a line in 3D with the values:
z = f(x,y);
plot3(x,y,z);
The final result may have some artefacts where the line crosses in and out of the surface. If you are not so concerned about the accuracy in the plot add a very small value to z to "lift" it above the surface.

Related

Creating meshgrid of scattered Cartesian data for plotting on a sphere

I have a set of n=8000 cartesian coordinates X,Y and Z as vectors and also a vector V of same size which I want to use as values to create a heatmap on a sphere.
I saw this link (visualization of scattered data over a sphere surface MATLAB), but I don't understand how I convert this set of data into a meshgrid for plotting using surf.
Almost every example I saw uses meshgrids.
Right now, I am doing by plotting a sphere and then use scatter3 to plot my points as big balls and try to smooth them later. I looks like this:
I would like to get the figure as the plotting of the example in that link, where he uses:
k = 5;
n = 2^k-1;
[x,y,z] = sphere(n);
c = hadamard(2^k);
surf(x,y,z,c);
colormap([1 1 0; 0 1 1])
axis equal
EDIT:
(Sorry for taking so long to reply, the corona crises kept away from work)
What I am actually doing is:
for i=1:numel(pop0n)
ori(i,:)=ori(i,:)/norm(ori(i,:));
end
x = ori(:,1);
y = ori(:,2);
z = ori(:,3);
%// plot
m=100;
[aa,bb,cc] = sphere(m);
surf(aa,bb,cc,ones(m+1,m+1)*min(pop0n))
hold on
colormap jet;
scatter3(x,y,z,400,pop0n/norm(pop0n),'filled');
colorbar
shading interp
The array 'ori' is 8000x3, and contains the x, y and z coordinates of the points I want to plot and pop0n is a 8000 sized vector with the intensities of each coordinate.
My main question is how do I transform my x, y, z and pop0n, that are vectors, into 2D arrays (meshgrid) to use surf?
Because I cannot simply do surf(x,y,z,pop0n) if they are vectors.
Thanks in advance
As David suggested, griddata does the job.
What I did was:
for i=1:numel(pop0n)
ori(i,:)=ori(i,:)/norm(ori(i,:));
end
x = ori(:,1);
y = ori(:,2);
z = ori(:,3);
%// plot
m=100;
[aa,bb,cc] = sphere(m);
v = griddata(x,y,z,pop0n,aa,bb,cc,'nearest');
surf(aa,bb,cc,v)
colormap jet;
colorbar
shading interp

How to create a 2d color map plot from x and y coordinates and a vector of values?

I'm trying to plot a 2 dimensional signal on a specific plane in a 3d model. I have the matrix:
xyzp (nx3)
that contains all the points which are closest to the plane (e.g. when the plane is in the z direction, all the z coordinates are fairly similar).
and I have a vector:
signal (nx1)
that contains a value for each point in xyzp.
when I use:
"surf([xyzp(:,[1,2]),signal)" or "mesh([xyzp(:,[1,2]),signal])"
The plot I get doesn't look at all like the intersection of the plane with the model from any angle (I expected "view(2)" to show the signal in the Z direction), so I assume I didn't use the plot function correctly.
Can anyone show me an example? For instance - A circle on an xy plane with some random signal indicated by color
surf and mesh can be used when the points form a rectangular grid on the xy plane.
In the general case (points are arbitrarily placed), you can use scatter3. For purposes of illustration, consider the following example xyzp and signal:
[x y] = ndgrid(-1:.01:1);
x = x+.3*y; %// example values which do not form a rectangular grid
z = x+y; %// example z as a function of x, y
xyzp = [x(:) y(:) z(:)];
signal = z(:)+x(:)-y(:); %// example values
Then
scatter3(xyzp(:,1), xyzp(:,2), xyzp(:,3), 1, signal, '.');
produces the following figure.
Since scatter3 plots each point separately, the picture is not as smooth as it would be with surf. But this seems hard to improve if the coordinates do not a have any "structure" (as surf requires) .

2D plot in 3D polar graph

I would like to plot a 3D graph, y=100-x^2, cycle around the Y axis in 360 degrees. Eventually to become like a cone. Is that possible? I have an array x=1:1:100, and an array y, size(1 100).
I tried an Z array, z=1:1:100 as the 3th axis in the base of the cone. With plot3 I done the one graph of y=100-x^2. I would like to kinda animate it and have eventually a cone, or a surface cone.
Is this what you are looking for?
r = 1:1:100;
y = 100-r.^2;
theta = 0:pi/20:2*pi;
xx = bsxfun(#times,r',cos(theta));
zz = bsxfun(#times,r',sin(theta));
yy = repmat(y',1,length(theta));
surf(xx,yy,zz)
Source: Generating a 3D plot by revolution of a curve

Why not spherical plot? How to plot 3D-polar-plot in Matlab?

[r,t] = meshgrid(linspace(0,2*pi,361),linspace(0,pi,361));
[x,y]=pol2cart(sin(t)*cos(r),sin(t)*sin(r));
%[x,y]=pol2cart(r,t);
surf(x,y);
I played with this addon but trying to find an default function to for this. How can I do the 3D-polar-plot?
I am trying to help this guy to vizualise different integrals here.
There are several problems in your code:
You are already converting spherical coordinates to cartesian coordinates with the sin(theta)*cos(phi) and sin(theta)*sin(phi) bit. Why are you calling pol2cart on this (moreover, we're not working in polar coordinates!)?
As natan points out, there is no third dimension (i.e. z) in your plot. For unity radius, r can be omitted in the spherical domain, where it is completely defined by theta and phi, but in the cartesian domain, you have all three x, y and z. The formula for z is z = cos(theta) (for unit radius).
You didn't read the documentation for surf, which says:
surf(Z,C) plots the height of Z, a single-valued function defined over a geometrically rectangular grid, and uses matrix C, assumed to be the same size as Z, to color the surface.
In other words, your surf(x,y) line merely plots the matrix x and colors it using y as a colormap.
Here's the above code with the mistakes fixed and plotted correctly:
[f,t] = meshgrid(linspace(0,2*pi,361),linspace(0,pi,361));
x = sin(t)*cos(f);
y = sin(t)*sin(f);
z = cos(t);
surf(x,y,z)

How to plot a second graph instead of color coding in matlab

i just started with my master thesis and i already am in trouble with my capability/understanding of matlab.
The thing is, i have a trajectory on a surface of a planet/moon whatever (a .mat with the time, and the coordinates. Then i have some .mat with time and the measurement at that time.
I am able to plot this as a color coded trajectory (using the measurement and the coordinates) in scatter(). This works awesomely nice.
However my problem is that i need something more sophisticated.
I now need to take the trajectory and instead of color-coding it, i am supposed to add the graph (value) of the measurement (which is given for each point) to the trajectory (which is not always a straight line). I will added a little sketch to explain what i want. The red arrow shows what i want to add to my plot and the green shows what i have.
You can always transform your data yourself: (using the same notation as #Shai)
x = 0:0.1:10;
y = x;
m = 10*sin(x);
So what you need is the vector normal to the curve at each datapoint:
dx = diff(x); % backward finite differences for 2:end points
dx = [dx(1) dx]; % forward finite difference for 1th point
dy = diff(y);
dy = [dy(1) dy];
curve_tang = [dx ; dy];
% rotate tangential vectors 90° counterclockwise
curve_norm = [-dy; dx];
% normalize the vectors:
nrm_cn = sqrt(sum(abs(curve_norm).^2,1));
curve_norm = curve_norm ./ repmat(sqrt(sum(abs(curve_norm).^2,1)),2,1);
Multiply that vector with the measurement (m), offset it with the datapoint coordinates and you're done:
mx = x + curve_norm(1,:).*m;
my = y + curve_norm(2,:).*m;
plot it with:
figure; hold on
axis equal;
scatter(x,y,[],m);
plot(mx,my)
which is imo exactly what you want. This example has just a straight line as coordinates, but this code can handle any curve just fine:
x=0:0.1:10;y=x.^2;m=sin(x);
t=0:pi/50:2*pi;x=5*cos(t);y=5*sin(t);m=sin(5*t);
If I understand your question correctly, what you need is to rotate your actual data around an origin point at a certain angle. This is pretty simple, as you only need to multiply the coordinates by a rotation matrix. You can then use hold on and plot to overlay your plot with the rotated points, as suggested in the comments.
Example
First, let's generate some data that resembles yours and create a scatter plot:
% # Generate some data
t = -20:0.1:20;
idx = (t ~= 0);
y = ones(size(t));
y(idx) = abs(sin(t(idx)) ./ t(idx)) .^ 0.25;
% # Create a scatter plot
x = 1:numel(y);
figure
scatter(x, x, 10, y, 'filled')
Now let's rotate the points (specified by the values of x and y) around (0, 0) at a 45° angle:
P = [x(:) * sqrt(2), y(:) * 100] * [1, 1; -1, 1] / sqrt(2);
and then plot them on top of the scatter plot:
hold on
axis square
plot(P(:, 1), P(:, 2))
Note the additional things have been done here for visualization purposes:
The final x-coordinates have been stretched (by sqrt(2)) to the appropriate length.
The final y-coordinates have been magnified (by 100) so that the rotated plot stands out.
The axes have been squared to avoid distortion.
This is what you should get:
It seems like you are interested in 3D plotting.
If I understand your question correctly, you have a 2D curve represented as [x(t), y(t)].
Additionally, you have some value m(t) for each point.
Thus we are looking at the plot of a 3D curve [x(t) y(t) m(t)].
you can easily achieve this using
plot3( x, y, m ); % assuming x,y, and m are sorted w.r.t t
alternatively, you can use the 3D version of scatter
scatter3( x, y, m );
pick your choice.
Nice plot BTW.
Good luck with your thesis.