I do not understand why patch does not follow the lines in this image:
In fact, in the code I used, the lines and the patch share the same input variables X and Y:
clearvars
close all
clc
figure(1)
z=peaks(50);
% Create x,y coordinates of the data
[x,y]=meshgrid(1:50);
% Plot Data and the slicing curve
surf(z);
hold on
X=[1 21 35 47 29 25 8];
Y=[5 19 24 26 14 39 47];
plot3(X,Y,-10*ones(1,numel(X)),'r','linewidth',3);
plot3(X,Y,10*ones(1,numel(X)),'r','linewidth',3);
patch([X fliplr(X)],[Y fliplr(Y)],[-10*ones(1,numel(X)) 10*ones(1,numel(X))],...
'r','FaceAlpha',0.21)
axis([0 50 0 50])
What am I messing up?
You pass the wrong arguments to patch. The Matlab documentation says that
If XData is a matrix, then each column represents the x-coordinates of a single face of the patch.
Thus, the patch data should look like this:
XData= [
X(1) X(2) ... and so on
X(2) X(3)
X(2) X(3)
X(1) X(2)];
YData= [
Y(1) Y(2) ...
Y(2) Y(3)
Y(2) Y(3)
Y(1) Y(2)];
ZData= [
-10 -10 ...
-10 -10
10 10
10 10];
You can use patch this way:
patch([X(1:end-1);X(2:end);X(2:end);X(1:end-1)],[Y(1:end-1);Y(2:end);Y(2:end);Y(1:end-1)],...
[-10*ones(1,numel(X)-1);-10*ones(1,numel(X)-1);10*ones(1,numel(X)-1);10*ones(1,numel(X)-1)],...
'r','FaceAlpha',0.21)
or you can use surf:
surf([X;X],[Y;Y],[-10*ones(1,numel(X)) ;10*ones(1,numel(X))],'FaceAlpha',0.21);
Related
As far as I understand the way to 3-d plot/ surface plot is "meshgrid".
But the data I have has a specific format:
X
Y
Z
1
0.1
10
1
0.2
12
1
0.3
13
2
0.1
11
2
0.2
12
2
0.3
14
3
0.1
11
3
0.2
12
3
0.3
15
The first and second column (X and Y) repeat themselves in that fashion, and I need to plot Z(X,Y).
How Do I do it?
X = 1:1:3 % grid can be set by beginning:step:end
Y = 0.1:0.1:0.3
[x,y] = meshgrid(X,Y); % then make 2d domain
% z values have to be done manually or can automate if you read your data from txt file
z = [10 12 13; 11 12 14; 11 12 15];
% and finally
surf(x,y,z)
I have a discrete signal x of length N traced in MATLAB using the command
stem(abs(x)); axis([0 N+6 0 4]);
The resulted figure is shown below:
My question I need only some values corresponding for example to index [7 10 11 12 15 18 48 50 52 60] to be colored with different color , let's say with red.
How can I do that into my figure ?
Using Multiple Plots by hold on and Matrix Indexing
You could possibly and alternatively place a plot on top of plot by using hold on. This does require an adjustment where you need a vector in this case Sample and Indices which specify the sample number/data point index. You can also use matrix indexing to get the amplitude/data points corresponding to the key point, Indicies.
%Vector relating to the sample/data point number%
Sample = linspace(1,70,70);
%Random test data%
X = randi([0,2],1,70);
stem(Sample,X);
hold on
%Key indices to change colour%
Key_Indices = [7 10 11 12 15 18 48 50 52 60];
%Matrix indexing to get values/amplitudes corresponding to key indices%
X_Prime = X(Key_Indices);
stem(Key_Indices,X_Prime,'r');
axis([0 70 0 3]);
hold off
Ran using MATLAB R2019b
This code makes just the circles red and not the stems
plot with selected red circles
%Vector relating to the sample/data point number
Sample = linspace(1,70,70);
%Random test data
X = randi([0,2],1,70);
stem(Sample,X);
%Key indices to change color
Key_Indices = [7 10 11 12 15 18 48 50 52 60];
line(Sample(Key_Indices), X(Key_Indices), 'linestyle', 'none', 'marker', 'o', 'color', 'r')
axis([0 70 0 3])
grid on
I'm trying to minimize a non-linear objective function (my actual function is much more complicated than that, but I found that even this simple function illustrates the point), where I know that minimum is obtained at the initial point x0:
fun = #(x) x(1)^2+x(2)^2;
x0 = [0 0];
lb1 = [0 0];
lb2 = [-1 -1];
[xc1 fvalc1] = fmincon(fun, x0, [],[],[],[], lb1, [Inf Inf])
Which outputs:
>> xc1 = 1.0e-03 * [0.6457 0.6457]
>> fvalc1 = 8.3378e-07
However, both using a different lower bound or using fminsearch instead work correctly:
[xc2 fvalc2] = fmincon(fun, x0, [],[],[],[], lb2, [Inf Inf])
>> xc2 = [0 0]
>> fvalc2 = 0
[xs fvals] = fminsearch(fun, x0)
>> xs = [0 0]
>> fvals = 0
What goes wrong in the first fmincon call?
We can diagnose this using the output output argument as specified in the docs
[xc1, fvalc1, ~, output] = fmincon(fun, x0, [],[],[],[], lb1, [Inf Inf])
The value output.stepsize is the final step size taken in the iterative solving process. In this case:
output.stepsize
>> ans = 6.586e-4
The estimated minima was at x = [6.457e-4, 6.457e-4] and the lower bounds you've permitted are [0 0], so the solver is not permitted to take another step! Another step would give x = [-1.29e-5, -1.29e-5] which is outside of the boundaries.
When you allow the lower bounds to be [-1, -1] the solver can over-shoot the minimum and approach it from all directions.
Moreover, we can use the options input to get even better insight!
options.Display = 'iter';
[xc1, fvalc1, ~, output] = fmincon(fun, x0, [],[],[],[], lb1, [Inf Inf], [], options);
Printed to the command window we see this:
Your initial point x0 is not between bounds lb and ub; FMINCON
shifted x0 to strictly satisfy the bounds.
First-order Norm of
Iter F-count f(x) Feasibility optimality step
0 3 1.960200e+00 0.000e+00 9.900e-01
1 6 1.220345e-02 0.000e+00 8.437e-01 1.290e+00
2 9 4.489374e-02 0.000e+00 4.489e-02 1.014e-01
3 12 1.172900e-02 0.000e+00 1.173e-02 1.036e-01
4 15 3.453565e-03 0.000e+00 3.454e-03 4.953e-02
5 18 1.435780e-03 0.000e+00 1.436e-03 2.088e-02
6 21 4.659097e-04 0.000e+00 4.659e-04 1.631e-02
7 24 2.379407e-04 0.000e+00 2.379e-04 6.160e-03
8 27 6.048934e-05 0.000e+00 6.049e-05 7.648e-03
9 30 1.613884e-05 0.000e+00 1.614e-05 3.760e-03
10 33 5.096660e-06 0.000e+00 5.097e-06 1.760e-03
11 36 2.470360e-06 0.000e+00 2.470e-06 6.858e-04
12 39 8.337765e-07 0.000e+00 8.338e-07 6.586e-04
So your x0 is invalid! This is why the solver doesn't return the result with 1 iteration and lower bounds of [0 0].
fminsearch also works for the same reason - you've not imposed a lower bound on which the solution sits.
I have the following picture:
and I want to create a continuous transition. The blue line (-20deg-start) goes until become like (22deg - original), and then goes until become like (60deg-stop).
the code to generate this lines is:
>> clear all
>> x=[0 11 20 34];
>> y=[2 8 17 32];
>> z=[9 20 29 43];
>> v=[16 23 32 43];
>> w=[15 26 35 49];
>> t=[30 40 47 55];
>> figure
>> hold on
>> plot(t,x, t,y, t,z, t,v, t,w)
Is it possible with the help of Matlab?
Thanks!
The following example shows how to do a linear transition between two curves, provided they are both defined on the same set of x values.
x = linspace(0,1,200); %// x values
y1 = log(1+x); %// y values of line 1
y2 = 1-x.^2; %// y values of line 2
c1 = [1 0 0]; %// red
c2 = [0 0 1]; %// blue
plot(x, y1, ':', 'color', c1); %// plot first line
hold on
plot(x, y2, ':', 'color', c2); %// plot second line
tt = linspace(0,1,100); %// define time axis, between 0 and 1. Adjust "100" for smoothness
h = plot(x, y1, '-', 'color', c2); %// moving line. Initially coincides with line 1
for t = tt
y = y1*(1-t) + y2*t;
c = c1*(1-t) + c2*t;
set(h, 'YData', y, 'Color', c); %// update y values and color of moving line
pause(.02) %// adjust ".02" as needed
end
Yes you can (well from what I understand you wish to achieve). You can put all your data into 1 big array and loop through each row and display it, with a small pause between each set of data.
Example:
clear
clc
close all
clear all
x=[0 11 20 34];
y=[2 8 17 32];
z=[9 20 29 43];
v=[16 23 32 43];
w=[15 26 35 49];
t=[30 40 47 55];
%// Put everything in single array
AllArrays = [x;y;z;v;w];
figure
hold all
%// Loop through each rows
for k = 1:size(AllArrays,1)
plot(t,AllArrays(k,:))
%// Make a pause to see output
pause(.5)
end
Output:
Is this what you meant? Or maybe a smoother transition?
I am using polyfit in matlab to plot a straight line of best fit through points. However, the best fit line is not as I would expect - the line does not look like it fits the data very well... does it? Here's my code, any help with improving this would be great. (Note, the axis limits I have set are important).
x = [0 1 10 5 1 1.5];
y = [-14 -18 -22 -26 -30 -34];
scatter(x,y)
hold on
p = polyfit(x,y,1);
f = polyval(p,x);
plot(x,f,'-r','linewidth',1.2)
ylim([-35 -10])
xlim([-30 30])
Your fit looks proper to me, but this might be what you're looking for instead
x = [0 1 10 5 1 1.5];
y = [-14 -18 -22 -26 -30 -34];
scatter(x,y)
hold on
p = polyfit(y,x,1);
f = polyval(p,y);
plot(f,y,'-r','linewidth',1.2)
ylim([-35 -10])
xlim([-30 30])
Here's a total least squares solution
data=[x(:), y(:)];
c=mean(data);
data=bsxfun(#minus,data,c);
[~,~,v]=svd(data);
d=v(:,end);
k=dot(d,c);
ezplot(#(x,y) x*d(1)+ y*d(2)-k, [-30 30 -35 -10])