plotting sin(x) graph in Matlab - strange results - matlab

Hi I'm trying to plotting graphs in Matlab and I getting strange results:
i should do graphs of y=asin(bx+c)
when a,b,c changing from graph to graph..
but as u can see when I'm changing the 'b' value to a big one
the graph in figure app become strange.
and one of the causes that make the graphs strange is the 'N' value in the matlab function: x=linspace(x0,xt,N)
why for example when I'm changing N to 200 the graph going crazy?
what exactly 'N' doing maybe i didn't get it :(
so here is my code, the problem is in 'figure 4' (section 'c'), the graph there is not looking like sin(x)
while in figure1,2,3 it was all good.
[when offering me a solution, please consider i need the graph with 3 full cycles].
code:
%------a------%
vm1=20;
vm2=41;
vm3=79;
f=44;
w=2*pi*f;
t=linspace(0,6*pi,120); %6pi for 3 cycles
v1=vm1*sin(w*t+pi/3);
v2=vm2*sin(w*t-pi/4);
v3=vm3*sin(w*t);
plot(t,v1,t,v2,t,v3);
ylabel('v(t)[V]');
xlabel('t[sec]');
legend('v_1(t)','v_2(t)','v_3(t)');
%-----b-----%
vsum=v1+v2+v3;
figure;plot(t,vsum,'linewidth',2);
ylabel('v(t)[V]');
xlabel('t[sec]');
legend('v_s(t)');
%-----c-----%
f1=200;
w1=2*pi*f1;
f2=200*3.2;
w2=2*pi*f2;
f3=200*4.3;
w3=2*pi*f3;
v1_new=vm1*sin(w1*t+pi/3);
v2_new=vm2*sin(w2*t-pi/4);
v3_new=vm3*sin(w3*t);
figure;plot(t,v1_new,t,v2_new,t,v3_new);
ylabel('v(t)[V]');
xlabel('t[sec]');
legend('v_1new(t)','v_2new(t)','v_3new(t)');
vsum_new=v1_new+v2_new+v3_new;
figure;plot(t,vsum_new,'linewidth',2);
ylabel('v(t)[V]');
xlabel('t[sec]');
legend('v_s(t)');

In your function "y=a * sin(b*x+c)" b changes the period of the sine wave, the time it takes to go one full cycle.
The period: T = 2*pi / b
So if you want to have 3 periods you should calculate T and make sure that your t runs from 0 to 3*T.
t = linspace(0,6*pi/w1,120);

Related

How do I get lines to stop extending beyond plot border? (Matlab)

I am writing a report for a class and am having some issues with the lines of an unstable plot going beyond the boundary of the graph and overlapping the title and xlabel. This is despite specifying a ylim from -2 to 2. Is there a good way to solve this issue?
Thanks!
plot(X,u(:,v0),X,u(:,v1),X,u(:,v2),X,u(:,v3),X,u(:,v4))
titlestr = sprintf('Velocity vs. Distance of %s function using %s: C=%g, imax=%g, dx=%gm, dt=%gsec',ICFType,SDType,C,imax,dx,dt);
ttl=title(titlestr);
ylabl=ylabel("u (m/s)");
xlabl=xlabel("x (m)");
ylim([-2 2])
lgnd=legend('t=0','t=1','t=2','t=3','t=4');
ttl.FontSize=18;
ylabl.FontSize=18;
xlabl.FontSize=18;
lgnd.FontSize=18;
EDIT: Minimum reproducible example
mgc=randi([-900*10^10,900*10^10], [1000,2]);
mgc=mgc*1000000;
plot(mgc(:,1),mgc(:,2))
ylim([-1,1])
This is odd. It really looks like a Bug... partly
The reason is probably that the angle of the lines are so narrow that MATLAB runs into rounding errors when calculating the points to draw for your limits very small limits given very large numbers. (You see that you don't run into this problem when you don't scale the matrix mgc.
mgc = randi([-900*10^10,900*10^10], [1000,2]);
plot(mgc(:,1),mgc(:,2))
ylim([-1,1])
but if you scale it further, you run into this problem...
mgc = randi([-900*10^10,900*10^10], [1000,2]);
plot(mgc(:,1)*1e6,mgc(:,2)*1e6)
ylim([-1,1])
While those numbers are nowhere near the maximum number a double can represent (type realmax in the command window to see that this is a number with 308 zeros!); limiting the plot to [-1,1] on one of the axes -- note that you obtain the same phenom on the x-axis -- let MATLAB run into precision problems.
First of all, you see that it plots much less lines than before (in my case)... although, I just said to zoom on the y-axis. The thing is, that MATLAB does not recalculate the lines for the section but it really zooms into it (I guess that this may cause resolution errors with regard to pixels?)
Well, lets have a look at the data (Pro-tip, you can get the data of a line from a MATLAB figure by calling this snippet
datObj = findobj(gcf,'-property','YData','-property','XData');
X = datObj.XData;
Y = datObj.YData;
xlm = get(gca,'XLim'); % get the current x-limits
) We see that it represents the original data set, which is not surprising as you can also zoom out again.
Note that his only occurs if you have such a chaotic, jagged line. If you sort it, it does not happen.
quick fix:
Now, what happens, if we calculate the exact points for this section?
m = diff(Y)./diff(X); % slope
n = Y(1:end-1)-m.*X(1:end-1); % offset
x = [(-1-n); (1-n)]./m;
y = ones(size(x))./[-1 1].';
% plot
plot([xMinus1;xPlus1],(ones(length(xMinus1),2).*[-1 1]).')
xlim(xlm); % limit to exact same scale as before
The different colors indicate that they are now individual lines and not a single wild chaos;)
It seems Max pretty much hit the nail on the head as it pertains to the reason for this error is occurring. Per Enrico's advice I went ahead and submitted a bug report. MathWorks responded saying they were unsure it was "unexpected behavior" and would look into it more shortly. They also did suggest a temporary workaround (which, in my case, may be permanent).
This workaround is to put
set(gca,'ClippingStyle','rectangle');
directly after the plotting line.
Below is a modified version of the minimum reproducible example with this modification.
mgc=randi([-900*10^10,900*10^10], [1000,2]);
mgc=mgc*1000000;
plot(mgc(:,1),mgc(:,2))
set(gca,'ClippingStyle','rectangle');
ylim([-1,1])

Matlab State Space Model Response system

I have a following lab where i was asked to write the command matlab lines for these questions:
If initial Conditions are: x(0)=[2;0].๐‘“๐‘–๐‘›๐‘‘ ๐‘กโ„Ž๐‘’ ๐‘Ÿ๐‘’๐‘ ๐‘๐‘œ๐‘›๐‘ ๐‘’ ๐‘ฆ(๐‘ก).
Find the response y(t) due to step input with Amplitude of
Find the Transfer Function for the above state space model
Derive back the state space model from (3).
a = [0,1;0,4];
b = [0;1];
c = [0 -5];
x0=[2;0];
sys = ss(a,b,c,2);
initial(sys,x0); % to get 1
[n,d]=ss2tf(a,b,c,0);
mySys_tf=tf(n,d) % to get 3
[num den] = tfdata(mySys_tf, 'v')
tf2ss(num,den) % to get 4
I have written this code but it seems like its not giving me any results in the response graph and thus i can't also solve 2 and it get error in 4 if you can help me out to check what is wrong
I believe that the error comes from the fact that the system is unstable. If you were to plot the system's reaction to a step input using step() then you will see how it goes to infinity. I also don't know how far you are into your controls course and if you've seen the root locus yet, but you can plot the root locus of the system via rlocus(sys) and you'll see that the real portion of the root is on the right half of the plane and therefore letting you know that the system is unstable.
The response is 0 and will stay zero as x(2) = 0. It requires an input u to get x(2) off zero. So the graph is totally fine.
use step(sys) and you will see the drop to -Inf. Optionally you can define the end-time. Call step(sys,1) to see a reasonable range.
You solved 3 & 4 yourself.
To check stability you simply need to ask MATLAB isstable(sys) (isn't it continent? Well, there is a danger that people will forget the theory behind it and how it is connected...)
To check observability: rank(obsv(sys)) and make sure that it is the same as the system matrix
assert(rank(obsv(sys)) == length(sys.A), 'System is not observable!')

MATLAB - interpolating a 2D curve with multiple Y's per X

I would like to interpolate a data set, but a given X can have multiple Y's, example given below:
A(:,1:2,1)=
95.2343 70.6159
96.4501 71.5573
97.4430 72.7315
98.9743 72.8699
100.0470 71.7690
100.3872 70.2699
100.7797 68.7837
102.1478 68.0814
103.6851 68.0521
105.0307 68.7966
105.8972 70.0666
106.7177 71.3665
107.7095 72.5416
108.9175 73.4924
110.3574 74.0309
111.8943 73.9859
113.3936 73.6446
114.6645 72.7794
115.5911 71.5522
116.2426 70.1591
116.3922 68.6286
116.3503 67.0914
116.7771 65.6147
117.9045 64.5692
119.4065 64.2425
120.9432 64.2923
122.2526 65.0975
122.9486 66.4682
122.8841 68.0043
122.5492 69.5051
122.2403 71.0109
122.0819 72.5402
These are points along the body of a snake, digitized from top-down video. Their posture frequently results in 2 or more Y points per X, and because they turn (often dramatically) while I need to maintain a consistent XY framework, I can't just rotate my X and Y.
I can make a spline function using cscvn, and when plotted using fnplt it looks great! But the moment I try to get values back using ppval, it all goes to crap and I get two curves that look nothing like the snake or what's shown in fnplt.
IMAGE HERE:
http://imgur.com/aYJ0Ftj
All I want is to fit a curve to those points, and convert that curve to a series of maybe 200 XY points.
I'm assuming that there is some obscenely simple answer, some command I've just never turned up in my searching, but I cannot find it for the life of me. This is quite far outside my usual skillset (I'm more used to crawling through swamps catching anything scaly or slimy), so I'm sure I'm overlooking something totally obvious to a skilled MATLAB user.
Thanks!
Perhaps this is what you already tried, but a comment was a bit small, so here is one idea that may help you
x = [1 2 3 4 5 6 7 6 5];
y = [1 4 4 3 2 2 2 3 4];
t = 1:length(x);
figure; plot(x,y)
xx = interp1(t,x,1:.01:length(x),'pchip');
yy = interp1(t,y,1:.01:length(x),'pchip');
hold on; plot(xx,yy,'g')
I avoided the unique values restriction on interp by interpolating x and y both as a function of t.
OK, thanks to Yvon and Trogdor, I managed to crudely cludge together some code:
ht=[1:32];
tx=linspace(1,32,500);
m=ht;
m(2:3,:)=squeeze(A(:,:,i))';
m1=m(1,:);
m2=m(2,:);
m3=m(3,:);
SFX=spline(m1,m2);
pSFX=ppval(SFX,tx);
SFY=spline(m1,m3);
pSFY=ppval(SFY,tx);
AS(:,1,i)=pSFX;
AS(:,2,i)=pSFY;
plot(AS(:,1,i),AS(:,2,i),'Marker','o');
It's riddled with pointless variables, steps, and redundancies, but I'm an anatomist, so that makes me comfortable (seriously, google 'recurrent laryngeal nerve').
How do I add reputation for y'all?

Issue in mean square error plot

There are 2 column vectors A,B containing 100 data values. I intend to plot the MSE(mean square error ) using the following code but all I get is a single dot instead of a line plot. Please help how to go about it.
A=x(:,1);
B=y(:,1);
er=(double(A)-double(B)).^2;
row_er=mean(er,2); % variable changed
plot(row_er);
This script works fine.
A = randn(10, 1);
B = randn(10, 1);
er=(double(A)-double(B)).^2;
row_e=mean(er,2);
plot(row_e)
Probably you have a typo (row_er)
row_e=mean(er,2);
plot(row_er);
Please notice that the command mean returns the mean of a vector (which is one simple value). If you want to plot plot the square error then you just plot((A-B).^2).
But... If you are interested in plotting the mean square error with, say, 10 samples average, you will have a plot with only 10 points (100 / 10 because each 10 data points are averaged to give you one point).
The command would be
plot(blkproc((A-B).^2,[10,1],'mean'))
hope it helps.

MATLAB query about for loop, reading in data and plotting

I am a complete novice at using matlab and am trying to work out if there is a way of optimising my code. Essentially I have data from model outputs and I need to plot them using matlab. In addition I have reference data (with 95% confidence intervals) which I plot on the same graph to get a visual idea on how close the model outputs and reference data is.
In terms of the model outputs I have several thousand files (number sequentially) which I open in a loop and plot. The problem/question I have is whether I can preprocess the data and then plot later - to save time. The issue I seem to be having when I try this is that I have a legend which either does not appear or is inaccurate.
My code (apolgies if it not elegant):
fn= xlsread(['tbobserved' '.xls']);
time= fn(:,1);
totalreference=fn(:,4);
totalreferencelowerci=fn(:,6);
totalreferenceupperci=fn(:,7);
figure
plot(time,totalrefrence,'-', time, totalreferencelowerci,'--', time, totalreferenceupperci,'--');
xlabel('Year');
ylabel('Reference incidence per 100,000 population');
title ('Total');
clickableLegend('Observed reference data', 'Totalreferencelowerci', 'Totalreferenceupperci','Location','BestOutside');
xlim([1910 1970]);
hold on
start_sim=10000;
end_sim=10005;
h = zeros (1,1000);
for i=start_sim:end_sim %is there any way of doing this earlier to save time?
a=int2str(i);
incidenceFile =strcat('result_', 'Sim', '_', a, 'I_byCal_total.xls');
est_tot=importdata(incidenceFile, '\t', 1);
cal_tot=est_tot.data;
magnitude=1;
t1=cal_tot(:,1)+1750;
totalmodel=cal_tot(:,3)+cal_tot(:,5);
h(a)=plot(t1,totalmodel);
xlim([1910 1970]);
ylim([0 500]);
hold all
clickableLegend(h(a),a,'Location','BestOutside')
end
Essentially I was hoping to have a way of reading in the data and then plot later - ie. optimise the code.
I hope you might be able to help.
Thanks.
mp
Regarding your issue concerning
I have a legend which either does not
appear or is inaccurate.
have a look at the following extracts from your code.
...
h = zeros (1,1000);
...
a=int2str(i);
...
h(a)=plot(t1,totalmodel);
...
You are using a character array as index. Instead of h(a) you should use h(i). MATLAB seems to cast the character array a to double as shown in the following example with a = 10;.
>> double(int2str(10))
ans = 49 48
Instead of h(10) the plot handle will be assigned to h([49 48]) which is not your intention.