Shade area under a function curve with 2 variables - matlab

I have this function of 2 variables:
match = (2.*x-1).*y.^(.1) - 2.*x.*y;
Plot using ezplot(match, [0 1], [0 1]) yields:
I would like to shade (fill) the area under this green curve all the way to the 2 axis. I have tried to get the x and y data via get(h,'XData') and get(h,'YData'), and then use
area(x,y)
but the plot is not correct. Any suggestions?

Another option:
Assuming that you have a match() function:
function z = match(x,y)
z = (2.*x-1).*y.^(.1) - 2.*x.*y;
end
And you use ezplot():
fig = ezplot('match', [0 1], [0 1]);
The following code extract the data from the figure and plot the area:
h1 = findall(fig,'Type','hggroup');
matrix = get(h1,'ContourMatrix');
xData = matrix(1,3:end);
yData = matrix(2,3:end);
area(xData,yData)
xlim([0 1])
ylim([0 1])
The key point is that ezplot() uses a contour object, therefore it is a little more trickier to get the data.

OK, a rather inefficient solution is by using the symbolic toolbox:
syms y
match = #(x) (2.*x-1).*y.^(.1) - 2.*x.*y;
n = 100;
xs = linspace(0,1,n);
yval = zeros(n,2);
for ii=1:n
x=xs(ii);
temp = solve(match(x),'y', 'Real', true);
if length(temp)==1
yval(ii,1) = temp;
elseif length(temp)==2
yval(ii,:) = temp;
end
end
area(xs,yval(2))
Mind that the first solution is always '0'. I don't know if performance is an issue but this might be working for you!

Related

ContourPlot and inequalitie plot together

Im new to matlab and I want to plot a ContourPlot together with two inequalities but I dont know how. The function that I want to plot its ContourPlot is something like this:
Z = (X-2).^2 + (Y-1).^2;
and here are the two inequalities:
ineq1 = X.^2 - Y <= 2;
ineq2 = X + Y <= 2;
this is what I have dodne so far:
[X,Y] = meshgrid(-4:.2:4,-4:.2:4);
Z = (X-2).^2 + (Y-1).^2;
[C,h] = contour(X,Y,Z);
clabel(C,h)
ineq1 = X.^2 - Y <= 2;
ineq2 = X + Y <= 2;
range = (-4:.2:4);
hold on
plot(range,ineq1, range, ineq2)
hold off
but this does not feel right.
What I want to do is to visualize an optimization problem. First I want to plot the ContourPlot of the function and then the possible areas in that same plot, It would be great if I could show the intersection areas too.
If you want to draw the boundaries of the inequalities onto the contour plot, you can do this with line.
[X,Y] = meshgrid(-4:.2:4,-4:.2:4);
Z = (X-2).^2 + (Y-1).^2;
[C,h] = contour(X,Y,Z);
clabel(C,h)
x_vect = (-4:.05:4);
y_ineq1 = x_vect.^2 - 2;
y_ineq2 = 2 - x_vect;
line(x_vect, y_ineq1);
line(x_vect, y_ineq2);
Coloring the intersection area is a bit more tricky, and I'm not sure if it's exactly what you want to do, but you could look into using patch, something like
% Indexes of x_vect, y_ineq1 and y_ineq2 for region where both satisfied:
region_indexes = find(y_ineq1<y_ineq2);
region_indexes_rev = region_indexes(end:-1:1);
% To plot this area need to enclose it
% (forward along y_ineq1 then back along y_ineq2)
patch([x_vect(region_indexes),x_vect(region_indexes_rev)],...
[y_ineq1(region_indexes),y_ineq2(region_indexes_rev)],...
[1 0.8 1]) % <- Color as [r g b]
% May or may not need following line depending on MATLAB version to set the yaxes
ylim([-4 4])
% Get the original plot over the top
hold on
[C,h] = contour(X,Y,Z);
clabel(C,h)
hold off

How to plot a matlab function for different parameters using hold on command

I have a matlab function that contain some constant parameter, I want to draw that function, on say same figure, using hold on (probably) while changing the value of that constant.
This my code:
close all
clear all
clc
m = 5;
x = 1:1:10;
y = m*x + 10;
h1 = figure;
plot(x,y)
m = 10;
figure(h1);
hold on
plot(x,y,': r')
When I tried using this code, I got two lines coincident on each others; and it looks matlab just used last value for the parameter m how can I make it use different values.
I found some stuff here, but doesn't fulfill my needs.
Any suggestions?
You need to recalculate y as well:
m = 5;
x = 1:1:10;
y = m*x + 10;
h1 = figure;
plot(x,y); hold on;
m = 10;
y = m*x + 10;
figure(h1);
plot(x,y,': r')
Or create an anonymous function:
x = 1:1:10;
f = #(m) m*x + 10;
%// and then:
h1 = figure;
plot(x,f(5) ); hold on;
plot(x,f(10),': r');
Currently, you're only updating m but you also have to calculate y again. This is why it plots exactly the same y (i.e. m is still 5) function when you issue the second plot.
You might want to use a simple for loop for that, like:
m = 5;
x = 1:1:10;
figure;
hold on;
for m=1:1:10
y = m*x + 10;
plot(x,y,': r')
end
In addition to the short answer - improving the plot..
%% Data Preparations
x = 1:10;
ms = 3; % number of different slopes
%% Graph Preparations
hold on;
% Prepare the string cell array
s = cell(1, ms);
% Handle storage
h = zeros(1, ms);
% Plot graphs
for m=1:ms
y = m*x + 10;
h(m)= plot(x,y,'Color',[1/m rand() rand()]);
s{m} = sprintf('Plot of y(m=%d)', m);
end
% Plot all or select the plots to include in the legend
ind = [ms:-1:1] .* ones(1,ms); % plot all
%ind = [ 1 3 4 ]; % plot selected
% Create legend for the selected plots
legend(h(ind), s{ind});
Additional advice: When working with MATLAB and you try to improve the performance of your code, you shoud try to avoid using for-loops since MATLAB is MATrix manipulation and that's what it can do best. Ones you've taken this philosophy in, you'll create the most beautiful code one-liners! ;)
This script is an adoption of Steve Lord's post.

how to add markers at limits of fplot matlab?

I want to add markers at the limits of a function in matlab. I am plotting the function using fplot this is what I tried:
user_func = '2*x-3';
user_limits = '-2,2';
user_limits = regexp(user_limits, '\,', 'split');
user_limit(1) = str2num(user_limits{1});
user_limit(2) = str2num(user_limits{2});
h = fplot(func,limits);
I am trying to add markers at the limits only (size 10 color 'r'). any idea on how to do that?
thank you
Not sure if this is exactly what you are trying to accomplish but I modified your code slightly so I could plot the function (using an anonymous function):
user_func = #(x) 2*x-3;
user_limits = '-2,2';
user_limits = regexp(user_limits, '\,', 'split')
user_limit(1) = str2num(user_limits{1})
user_limit(2) = str2num(user_limits{2})
figure;fplot(user_func,[user_limit(1) user_limit(2)]);
Next, set the ticks at your locations and change the font size to 10 pt:
set(gca,'XTick',[user_limit(1) user_limit(2)],'FontSize',10);
Change the color of your labels to red:
set(gca, 'XColor', [1 0 0]);
set(gca, 'YColor', [1 0 0]);
Just so you can see the ticks, stretch the x-range a bit:
axis([-2.1 2.1 0 1]); axis 'auto y'
EDIT: After some additional input from the OP, the red tick markers can be plotted as shown below.
First let the x-position at the first limit be given by:
x1 = user_limit(1);
The y-value for first marker is then obtained from the anonymous function like this:
y1 = user_func(x1);
y2 = y1;
We have, y2 = y1, since you want the y-value where where your function first crosses the x-axis to be the same. Now make your plot like this (with x2 = user_limit(2)):
hold on;
plot(x1, y1, 'ro', x2, y2,'ro');
hold off;
giving a plot like:

Plot function = value Matlab

I have a function f(x1,x2) = x1*x2. That is easy enough to plot using ezsurf.
Can I plot f(x1,x2) = x1*x2 = 1? I want to see what specific sets of solutions look like.
Try using contour:
z = f(x1, x2);
contour(x1, x2, z, [1 1]);

How to plot several curves in MATLAB using handles

I am plotting data in MATLAB in real time. I want to use a handle. My problem is I do not know how to plot more than one Y-Data Curve.
I found the following code
It shows how to plot one set of YData. Has anybody got an idea to transform the code into two or more Y-Datasets, e.g. sind(x) as an additional curve in the plot?
x = 1:1000;
y = cosd(x);
xi = x(1);
yi = y(1);
h = plot(xi, yi, 'YDataSource', 'yi', 'XDataSource', 'xi');
for k = 2:1000...
xi = x(1:k);
yi = y(1:k);
refreshdata(h, 'caller');
drawnow;
end;
The below code works for me, if you really want to use handles
x = 1:1000;
y = cosd(x);
y2 = sind(x);
xi = x(1);
yi = y(1);
yi2 = y2(1);
figure(1); clf;
h = plot(xi, yi, 'YDataSource', 'yi', 'XDataSource', 'xi');
hold on;
h2 = plot(xi, yi2, 'YDataSource', 'yi2', 'XDataSource', 'xi');
for k = 200:1000
xi = x(1:k);
yi = y(1:k);
yi2 = y2(1:k);
refreshdata(h);
refreshdata(h2);
drawnow;
end;
You do need a hold on.
Also, instead of refreshdata you can use set as Andrey suggested:
set(h,'Xdata',xi,'YData',yi);
set(h2,'Xdata',xi,'YData',yi2);
First of all, never use refreshdata. Use the direct set method instead.
set(h,'Xdata',xi,'YData',yi);
Secondly, you should do two plots
h1 = plot(xi, yi);
h2 = plot(xi, yi);
And update each one accordingly.
Are you maybe looking for the hold command?
plot(1 : 10, (1 : 10).^2, 'r')
hold on
plot(1 : 10, (1 : 10).^3)
EDIT:
You can use hold in combination with set to update the plot (see also Andrey's answer):
h1 = plot(1 : 10, (1 : 10).^2, 'r');
hold on;
h2 = plot(1 : 10, (1 : 10).^3);
set(h1, 'XData', 1 : 2 : 20);
set(h2, 'YData', 0.1 * (1 : 20).^3);
The axes will update automatically.
If you don't care too much about displaying the same colour for all curves, simply concatenate the x data into a single vector separated by NaN between the curve components (do a similar thing for the y data). Then the "plot" command can take in these larger x and y vectors and will display everything at once. You may get around the colour issue by doing something similar with the colordata array.