Showing the graph boundaries in Matlab ezsurf - matlab

I am using this simple Matlab code to plot a 3d function. What is the best way to highlight the boundaries of the plot? (say by drawing a yellow line in the boundaries)
clc;
clear all;
syms x y;
func = x^2 + 4*y^2 - 2*x^2*y+4;
ezsurf(func, [-5,5]);
grid on;
box on;

It is possible just using the hold on/off:
1.Using plot3
clc; clear all;
syms x y;
func = x^2 + 4*y^2 - 2*x^2*y+4;
figure;
ezsurf(func, [-5,5]);
grid on;
box on;
hold on;
y1 = -5:0.1:5; x1 = 5.*ones(size(y1)); z1 = x1.^2 + 4*y1.^2 - 2*x1.^2.*y1+4;
y2 = -5:0.1:5; x2 = -5.*ones(size(y2)); z2 = x2.^2 + 4*y2.^2 - 2*x2.^2.*y2+4;
x3 = -5:0.1:5; y3 = 5.*ones(size(x3)); z3 = x3.^2 + 4*y3.^2 - 2*x3.^2.*y3+4;
x4 = -5:0.1:5; y4 = -5.*ones(size(x4)); z4 = x4.^2 + 4*y4.^2 - 2*x4.^2.*y4+4;
plot3(x1, y1, z1, 'y', x2, y2, z2, 'y', x3, y3, z3, 'y', x4, y4, z4, 'y');
hold off;
You can play with the LineWidth propriety to make this lines bigger.
Result:
2.Using ezplot3 (parametric curves)
clear x y;
hold on;
x = {'5'; '(-5)'; 't'; 't'};
y = {'t'; 't'; '5'; '(-5)'};
for i = 1:size(x,1)
funz = [char(x(i)),'^2 + 4*',char(y(i)),'^2 - 2*',char(x(i)),'^2*',char(y(i)),'+4'];
h = ezplot3( char(x(i)), char(y(i)), funz, [-5, 5]);
set(h, 'Color', 'y', 'LineWidth', 2);
end
hold off;
Result:

Related

How to Plot a unit vector in matlab

I am trying to create 2 random points that have vectors that pass them in a random direction. Example shown below
I tried creating 2 random points and 2 random unit vectors and using the function quiver to create the graph,
c = rand(1,2);
d = rand(1,2);
A = rand(2,1)-0.5;
B = rand(2,1)-0.5;
u = A/norm(A);
v = B/norm(B);
figure(3)
scatter(c,d)
quiver(c,d,u,v)
The quiver function doesnt really help and all I get is 2 points on a graph.
Any help is appreciated.
You also need to retain the scatter plot before adding the vector plots.
theta = rand( 1, 2) * 2 * pi;
x1 = c(1) + 0.5 * [-1, 1] * cos( theta( 1));
y1 = c(2) + 0.5 * [-1, 1] * sin( theta( 1));
x2 = d(1) + 0.5 * [-1, 1] * cos( theta( 2));
y2 = d(2) + 0.5 * [-1, 1] * sin( theta( 2));
figure;
hold on;
plot( x1, y1, 'r')
plot( x2, y2, 'b')
plot( c(1), c(2), 'ro', 'MarkerFaceColor', 'r');
plot( d(1), d(2), 'bo', 'MarkerFaceColor', 'b');
xlim = get( gca, 'XLim');
ylim = get( gca, 'YLim');
lo = min( [xlim(1), ylim(1)]);
hi = max( [xlim(2), ylim(2)]);
axis equal
set( gca, 'XLim', [lo, hi], 'YLim', [lo, hi]);

Change the legend of a Matlab figure

I would like to change the legend style of the following picture generated in Matlab:
x1=-5;
x2=5;
y1=-5;
y2=5;
x = [x1, x2, x2, x1, x1];
y = [y1, y1, y2, y2, y1];
fill(x,y,'b')
legend('A')
As you can see the legend displays a blue rectangle. What I would like is a filled blue circle in place of the rectangle as if the picture was generated as a scatter plot. How can I obtain that?
I would suggest to add a fictive value with hold on; p = plot(NaN, NaN, 'b.', 'MarkerSize', 15); then legend this specific "fake" plot with: legend(p, 'A');
x1=-5;
x2=5;
y1=-5;
y2=5;
x = [x1, x2, x2, x1, x1];
y = [y1, y1, y2, y2, y1];
fill(x,y,'b');
hold on; p = plot(NaN, NaN, 'b.', 'MarkerSize', 15);
legend(p, 'A')
#Bebs has a nice solution.
Another suggest is to change directly the legend icon:
[a,b] = legend('A');
b(2).Xdata = sin(-pi:0.1:pi)/10+0.4; % you can play with numbers to set size and location of circle
b(2).Ydata = cos(-pi:0.1:pi)/5+0.5;
Now you can set some other properties:
b(2).LineWidth = 1; % thicker line
b(2).FaceColor = [1 1 1]; % white fill
b(2).EdgeColor = [0 0 1]; % blue edge

4D plot (3D+color) from 4 row vectors

I have 4 row vectors x, y, z and s, all of them have equal sizes 1*size. x, y, z should be the three Cartesian corodinate axes and s should be represented by colors (I want figure like below image). The statement Surf does not accept row vectors. I have read several stackoverflow post, but I could not find the answer. How can I plot such a figure?
I really appreciate any help you can provide.
I can't test it because you didn't provide any data, but you could try:
trisurf(x,y,z,s)
If that doesn't work then try:
DT = delaunayTriangulation(x,y,z);
tetramesh(DT,s);
You can try with this example of a 3D cube for a 3D meshgrid and it plots the "temperature".
L = 1;
dx = 0.25;
dy = dx;
dz = dy;
Nx = L/dx; Ny = Nx; Nz = Ny;
x = dx/2:dx:L-dx/2;
y = x; z = y;
[xx, yy, zz] = meshgrid(x,y,z);
theta = NaN(size(zz));
for jj=1:4;
for ii=1:4
for kk=1:4
theta(jj,ii,kk) = 273.15 + 5.*random('normal', 0, 1)
end
end
end
clf
isosurface(xx, yy, zz, theta)
colorbar
colormap jet
[fe, ve, ce] = isocaps(x, y, z, theta, 10);
p2 = patch('Faces', fe, 'Vertices', ve, 'FaceVertexCData', ce);
p2.FaceColor = 'interp';
p2.EdgeColor = 'none' ;
grid on
xlabel('X (m)');
ylabel('Y (m)');
zlabel('Z (m)');
title('Temperatures');
set(gca, 'clim', [273.15 273.15+5])
set(get(colorbar, 'title'), 'string', 'K', 'FontW', 'bold', 'fontname', 'Times New Roman', 'fontsize', 14);
view(3)

fix axes for animation

I'm working on a small simulation in matlab. For this purposes I want to create an animation of the simulated object (inverted pendulum). Unfortunatly the axes keep rescaling.
I tried everything. There are similar questions, but I just can't get it to work. The best i got is the code below. Where I get both axes at the same time, the scaled from -5 to 5 and those scaled by matlab.
%init visualisation
visualisation = figure();
axis([-5 5 -5 5]);
xlim([-5 5]);
ylim([-5 5]);
ax_hand = axes;
for i = 1:N
k1 = h * feval ( 'RHS', t0, x0, u );
k2 = h * feval ( 'RHS', t0 + (h/2), x0 + (k1/2), u);
k3 = h * feval ( 'RHS', t0 + h/2, x0 + k2/2, u);
k4 = h * feval ( 'RHS', t0 + h, x0 + k3, u);
x0 = x0 + ( k1 + 2*k2 + 2*k3 + k4 ) / 6;
t0 = t0 + h;
% model output
wi(1:neqn,i+1) = x0';
% model visualisation
%plotting cart
figure(visualisation);
plot(x0(3), 0, 'ro', 'LineWidth', 3);
%plotting pendulum
l = 2;
%plot(sin(x0(1))*l, cos(x0(1))*l, 'b*' , 'LineWidth', 2);
% regulator
end;
Here's one approach:
Do the first plot (possibly empty, doesn't matter). Get a handle to it, say h.
Set axis limits and include the statement axis manual fo freeze them.
Update plot (in a loop) via the 'XData' and 'YData' poperties of h.
Example:
h = plot(NaN, NaN, 'o'); %// empty plot
axis([0 10 0 5])
axis manual %// this line freezes the axes
for n = 1:10
x = 1:n;
y = sqrt(x);
set(h, 'XData', x, 'YData', y)
pause(.2)
end
Example with two plots:
h1 = plot(NaN, NaN, 'bo'); %// empty plot
hold on
h2 = plot(NaN, NaN, 'r*'); %// empty plot
axis([0 10 0 5])
axis manual %// this line freezes the axes
for n = 1:10
x1 = 1:n;
y1 = sqrt(x1);
set(h1, 'XData', x1, 'YData', y1)
x2 = 4.5;
y2 = n/2-.5;
set(h2, 'XData', x2, 'YData', y2)
pause(.2)
end

plottnig lines on a 3d surface matlab

I need to plot lines on a 3d surface in matlab. I wrote two scripts one to plot the surface and one to plot the lines on the surface.
script1
function figHandle = plotFunction(funchandle, a , b)
x_vec = -a:.1:a;
y_vec = -b:.1:b;
figHandle = figure();
[X,Y] = meshgrid(x_vec, y_vec);
Z = [];
z_temp = [];
for i = x_vec
for j = y_vec
z_temp =[z_temp; funchandle([i; j])];
end;
Z = [Z, z_temp];
z_temp = [];
end;
h = surf(X,Y,Z);
set(h, 'edgecolor', 'none');
%colormap gray;
colorbar;
view(0,90);
end
script2
function plotStep(figHandle,funcHandle, P1, P2)
figure(figHandle);
hold on;
plot3(P1(1), P1(2), funcHandle([P1(1);P1(2)]), 'r*');
if ~isequal(P1,P2)
Z = [];
X = [];
Y = [];
d = [P2(1)-P1(1), P2(2) - P1(2)];
if (P1(1) < P2(1))
X = P1(1):0.0001:P2(1);
if (P1(2) ~= P2(2))
Y = X.*(d(2)/d(1))+(P1(2)-(d(2)/d(1))*P1(1));
else
for i = X
Y = [Y, P1(2)];
end
end
elseif P1(1) > P2(1)
X = P1(1):-0.0001:P2(1);
if (P1(2) ~= P2(2))
Y = X.*(d(2)/d(1))+(P1(2)-(d(2)/d(1))*P1(1));
else
for i = X
Y = [Y, P1(2)];
end
end
else
if P1(2) < P2(2)
Y = P1(2):0.0001:P2(2);
for i = Y
X = [X, P1(1)];
end
else
Y = P1(2):-0.0001:P2(2);
for i = Y
X = [X, P1(1)];
end
end
end
for i = 1:length(X)
Z = [Z;funcHandle([X(i);Y(i)])];
end
plot3(X, Y, Z, 'r', 'LineWidth', 2);
end
My problem is no matter how close too each other I make the points which form the line after zooming in on the line it does not seem to be continuous.
The simplest way to fix this is to raise the line a little bit off the surface,
plot3(X, Y, Z+1, 'r', 'LineWidth', 2);
but you may have to experiment with the offset. It can sometimes help to make the line a little wider, and to try the different renderers as well.