I would like to show several spheres in my 3D spaces, each with a different center location and radius. So I followed the tutorial by Matlab and I get the following result. The only problem is that I might have hundreds of spheres to plot so it won't be possible to write down hundreds of lines. Is there a way to use the surf() function with a matrix input? Maybe surf(x,y,z) with x,y and z matrix? Thanks!
hold on;
[x,y,z] = sphere;
r = 50;
s1 = surf(x*r,y*r,z*r,'FaceAlpha',0.1);
s2 = surf((x+3)*r,(y-2)*r,z*r,'FaceAlpha',0.1); % centered at (3,-2,0)
s3 = surf(x*r,(y+1)*r,(z-3)*r,'FaceAlpha',0.1); % centered at (0,1,-3)
s1.EdgeColor = 'none';
s2.EdgeColor = 'none';
s3.EdgeColor = 'none';
Write it in generic form.... You are almost there:
s = surf((x-cx)*r,(y-cy)*r,(z-cz)*r,'FaceAlpha',0.1);
Now just change cx,cy,cz with loops
Related
I am trying to plot two different ellipses in Matlab with the same foci. Essentially I am plotting the elliptical orbit before and after an impulse maneuver.
The first (before maneuver) ellipse will always be in-line with the x-axis, whereas the second ellipse (after maneuver) will be at an angle above/below the x-axis (The second one will have a different major/minor axis and eccentricity as well).
In order to save space, the code for plotting one ellipse will be the same as the second ellipse, so I'll only show my code here for plotting one ellipse.
The problem is that it plots from the center of the grid, and not the foci.
Re = 6378.136; %km
e = .65;
x1 = -4.4*Re; %-a
x2 = 4.4*Re; % a
y1 = 0;
y2 = 0;
a = 1/2*sqrt((x2-x1)^2+(y2-y1)^2);
b = a*sqrt(1-e^2);
t = linspace(0,2*pi);
X = a*cos(t);
Y = b*sin(t);
w = atan2(y2-y1,x2-x1);
x = (x1+x2)/2 + X*cos(w) - Y*sin(w);
y = (y1+y2)/2 + X*sin(w) + Y*cos(w);
plot(x,y,'b')
axis equal
grid on
hold on
I'm sure it's something simple but I can't seem to figure it out.
Any help is much appreciated. Thanks.
Edit: David helped solve this issue, thank you.
I've found this answer, but I can't complete my work. I wanted to plot more precisely the functions I am studying, without overcoloring my function with black ink... meaning reducing the number of mesh lines. I precise that the functions are complex.
I tried to add to my already existing code the work written at the link above.
This is what I've done:
r = (0:0.35:15)'; % create a matrix of complex inputs
theta = pi*(-2:0.04:2);
z = r*exp(1i*theta);
w = z.^2;
figure('Name','Graphique complexe','units','normalized','outerposition',[0.08 0.1 0.8 0.55]);
s = surf(real(z),imag(z),imag(w),real(w)); % visualize the complex function using surf
s.EdgeColor = 'none';
x=s.XData;
y=s.YData;
z=s.ZData;
x=x(1,:);
y=y(:,1);
% Divide the lengths by the number of lines needed
xnumlines = 10; % 10 lines
ynumlines = 10; % 10 partitions
xspacing = round(length(x)/xnumlines);
yspacing = round(length(y)/ynumlines);
hold on
for i = 1:yspacing:length(y)
Y1 = y(i)*ones(size(x)); % a constant vector
Z1 = z(i,:);
plot3(x,Y1,Z1,'-k');
end
% Plotting lines in the Y-Z plane
for i = 1:xspacing:length(x)
X2 = x(i)*ones(size(y)); % a constant vector
Z2 = z(:,i);
plot3(X2,y,Z2,'-k');
end
hold off
But the problem is that the mesh is still invisible. How to fix this? Where is the problem?
And maybe, instead of drawing a grid, perhaps it is possible to draw circles and radiuses like originally on the graph?
I found an old script of mine where I did more or less what you're looking for. I adapted it to the radial plot you have here.
There are two tricks in this script:
The surface plot contains all the data, but because there is no mesh drawn, it is hard to see the details in this surface (your data is quite smooth, this is particularly true for a more bumpy surface, so I added some noise to the data to show this off). To improve the visibility, we use interpolation for the color, and add a light source.
The mesh drawn is a subsampled version of the original data. Because the original data is radial, the XData and YData properties are not a rectangular grid, and therefore one cannot just take the first row and column of these arrays. Instead, we use the full matrices, but subsample rows for drawing the circles and subsample columns for drawing the radii.
% create a matrix of complex inputs
% (similar to OP, but with more data points)
r = linspace(0,15,101).';
theta = linspace(-pi,pi,101);
z = r * exp(1i*theta);
w = z.^2;
figure, hold on
% visualize the complex function using surf
% (similar to OP, but with a little bit of noise added to Z)
s = surf(real(z),imag(z),imag(w)+5*rand(size(w)),real(w));
s.EdgeColor = 'none';
s.FaceColor = 'interp';
% get data back from figure
x = s.XData;
y = s.YData;
z = s.ZData;
% draw circles -- loop written to make sure the outer circle is drawn
for ii=size(x,1):-10:1
plot3(x(ii,:),y(ii,:),z(ii,:),'k-');
end
% draw radii
for ii=1:5:size(x,2)
plot3(x(:,ii),y(:,ii),z(:,ii),'k-');
end
% set axis properties for better 3D viewing of data
set(gca,'box','on','projection','perspective')
set(gca,'DataAspectRatio',[1,1,40])
view(-10,26)
% add lighting
h = camlight('left');
lighting gouraud
material dull
How about this approach?
[X,Y,Z] = peaks(500) ;
surf(X,Y,Z) ;
shading interp ;
colorbar
hold on
miss = 10 ; % enter the number of lines you want to miss
plot3(X(1:miss:end,1:miss:end),Y(1:miss:end,1:miss:end),Z(1:miss:end,1:miss:end),'k') ;
plot3(X(1:miss:end,1:miss:end)',Y(1:miss:end,1:miss:end)',Z(1:miss:end,1:miss:end)','k') ;
I want to plot smooth contour plot from X Y Z matrix.
sf = fit([X Y] Z, 'poly23');
plot(sf);
I have not enought smooth curve..
What I need?
You can use the functions such as griddata and csaps. Together they will lead you to the result as smooth as you wish. The first function adds additional points to your data matrix set. The second one makes the result smoother. The example of the code is below. In the example smoothing is done first in X direction and then in Y direction. Try to play around with the resolution and smoothing_parameter (the current set of these parameters should be OK though).
x = min_x:step_x:max_x;
y = min_y:step_y:max_y;
resolution = 10;
xg = min_x:(step_x/resolution):max_x;
yg = min_y:(step_y/resolution):max_y;
[X,Y] = meshgrid(x,y);
[XG,YG] = meshgrid(xg,yg);
smoothing_parameter = 0.02;
fitted = griddata(X,Y,Z,XG,YG,'cubic');
fitted_smoothed_x = csaps(xg,fitted,smoothing_parameter,xg);
fitted_smoothed_xy = csaps(yg,fitted_smoothed_x',smoothing_parameter,yg);
surf(XG,YG,fitted_smoothed_xy');
EDIT: If you want to get just a contour plot, you can do, for example, as presented below. As I don't have the real data, I will use build-in function peaks to generate some.
[X,Y,Z] = peaks(30);
figure
surfc(X,Y,Z)
view([0 90])
zlim([-10 -8])
Here you just look at your contour plot from above being below the surface.
i have four points with that i made a polygon using matlab
x = [2271 -3645 -2267 3645];
y = [-3635 -2259 3639 2254];
figure;
plot([x x(1)],[y y(1)],'r-');
i got a polygon, i need to generate the grid above the rectangle with 50*50 interval
i made a try with zgrid function , but its not giving the result.
i need a 2D grid on that polygon, i need to take the grid points into a file.
please help me to solve this
thanks in advance
To generate a point grid confined to the interior of your polygon you can do the following:
[X,Y]=meshgrid(linspace(min(x),max(x),round((max(x)-min(x))/50)),linspace(min(y),max(y),round((max(y)-min(y))/50)));
isin=inpolygon(X(:),Y(:),[x x(1)],[y y(1)]);
Xin = X(isin);
Yin = Y(isin);
Here [Xin, Yin] contains the coordinates of the grid vertices.
You can compute a grid with the meshgrid matlab's built-in function, and draw it with mesh for example. The mesh coordinates are stored in X and Y.
Here the polygon you defined is plotted on the top of the grid. The following code
x = [2271 -3645 -2267 3645];
y = [-3635 -2259 3639 2254];
outside = 100;
grid_val = 50;
figure('Color','w');
[X,Y] = meshgrid(min(x)-outside:grid_val:max(x)+outside, min(y)-outside:grid_val:max(y)+outside);
hold on;
hm = mesh(X,Y,X*0);
hp = plot([x x(1)],[y y(1)],'r-');
set(hm,'EdgeColor','k')
set(hp,'LineWidth',2)
set(gca,'Visible','off');
gives the following grid (full and zoom)
I have a 3-dimensional data to be plotted in matlab. The data set are built by stacking 10 exponential curves with different parameters along y directions such as
x = 0:0.01:15;
x0 = 0.5;
y = [beta1, beta2, beta3, beta4, beta5, beta6, beta7, beta8, beta9, beta10];
Z(1, :) = A*exp(-(x-x0).^2/beta1);
Z(2, :) = A*exp(-(x-x0).^2/beta2);
Z(3, :) = A*exp(-(x-x0).^2/beta3);
Z(4, :) = A*exp(-(x-x0).^2/beta4);
...
Z(10, :) = A*exp(-(x-x0).^2/beta10);
% here A could be change based on beta too (no code shown here)
I am trying to plot Z with waterfall except for I don't want the height (i.e. the vertical line) appears on the edge. I don't know if there is any other way to plot the data as waterfall-like curves but without those vertical lines. Thanks
"it is plotted with lines instead of patch with surface".
In other words, you want the boundary lines to be invisible. Well that's no trivial feat as the boundary lines are separate from any color scheme you can directly include. What you need to do is get the data after it drawn then modify it accordingly:
e.g.
[X,Y,Z] = peaks(30);
h = waterfall (X,Y,Z);
CD = get (h, 'CData');
CD(1,:) = nan;
CD(end-2:end,:) = nan;
set (h, 'CData', CD)
note that CD(1,:) is for the "rising" boundary, while CD(end-2:end-1,:) is for the falling boundary, and CD(end,:) is for the bottom.
i know this is an old post, but the below will make the region under the curve transparent:
figure;
[X,Y,Z] = peaks(10);
handle_figure = waterfall( X, Y, Z );
set( handle_figure, 'FaceColor', 'none' );