Issue in mean square error plot - matlab

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.

Related

How tick labels on one of the plot's axis can be multiplied in MATLAB?

I am currently trying to make 'nice looking' axis on my plot in Matlab. The values are samples where each is taken every 20ms. So on X axis I'd like to have time in ms. My general code for plotting data is very simple:
plot(1:size( data.matrix,1), data.matrix(:,1),'b');
So far I've been able to correctly display sample numbers on this axis:
Code:
set(gca,'XTick',(1:size(data.matrix,1))*20);
Result (a):
In the given example the number of samples equals 184, that makes:
time = 184 * 20ms = 3680ms
Because changing the XTick value didn't do much of a change, I've tested XTickLabel property:
Code:
set(gca,'XTickLabel',ceil(linspace(0,size(data.matrix,1)*20,10)));
Result (b):
Code:
set(gca,'XTickLabel',0:ceil((size(data.matrix,1)*20)/10):size(data.matrix,1)*20);
Result (c):
As you may see, the results aren't the worst one. But this is not what I am trying to achieve. My goal is to have values like this:
So it simply first plot's (result a) X axis multiplied by 20.
Can someone please tell me how to achieve this?
when you use :
plot(1:size( data.matrix,1), data.matrix(:,1),'b');
The first parameter 1:size( data.matrix,1) create a vector of consecutive integers representing the indices of your data points. Two things are wrong with that:
1) You do not need to specify it. Matlab plot function called with only the Y data will create this vector automatically and use it to plot the data.
2) These indices represent the position of your data in an array, they have no physical meaning (like "time" for your case).
The solution is to create a proper 'time' vector and send it as the first parameter to the plot function. This way Matlab will take care of the tick management and you don't have to temper with the manual xtick settings.
Look at the two ways of doing it in the example below and everything will be clear:
%// build a simple index "X" vector (as you were doing)
x_index = 1:size(data.matrix,1) ;
%// build a properly scaled time vector
timeInterval = 20 ; % in milliseconds
x_time = ( 0:size(data.matrix,1)-1 ) * timeInterval ;
plot( x_index , data.matrix(:,1) ) %// this will do like in your example
plot( x_time , data.matrix(:,1) ) %// this will do what you want
Can you not just do?
set(gca,'XTickLabel',(1:size(data.matrix,1))*20*20);

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?

The appearance of a dashed line in matlab is not even

The appearance of a dashed line in matlab is not even. For example:
x = [121.2802 112.5784 115.0855 109.0412 99.1158 103.9001];
y = [-25.8392 -24.9378 -25.1976 -24.5714 -23.5433 -24.0389];
plot(x,y,'--k','linewidth',1.2)
print -r600 -dtiff test.tif
The dashes do not appear separate in some parts of the line. Is this because the points are not evenly distributed? Any suggestions? Thanks.
No the problem isn't matlab it is your variables. Matlab is conecting (x(i),y(i)) with (x(i+1),y(i+1)) with a dashed line. But your data isn't sorted.
The only thing happening here is that you draw 2 lines above each other which results in your non dashed parts. If you want only dashed line try sorting your data before plotting it.
Edit 1
z= [x' ,y'];
z= (sortrows(z))';
x2=fliplr(z(1,:));
y2=fliplr(z(2,:));
plot(x2,y2,'--k','linewidth',1.2)
Here is a way to sort your data. What i am doing is i am conecting x,y rowwise in z. Then i use sortrows to sort all rows according to the first one. Then i transpose the resulting matrix so that you have new coloumn vectors. After that i use fliplr to flip the first to last element and so on (inverting your data, since your original data went from 120 to 100and i don't know if you want to use the data later on). And then i plot it.
Hope that helps
Edit 2
As posted by Dennis:
z= [x' ,y'];
z= (sortrows(z))';
z=flipud(z);
plot(x2,y2,'--k','linewidth',1.2)

Matlab Plot Smoothing having no effect

I'm currently having some trouble with the 'smooth' command, namely that it seems to have no effect on the generated plot. I have already used the following script to generate a plot
for h=1:4
linespec = {'rx', 'gx', 'bx', 'yx'};
hold on
for b=1:365
y=mean(mean(A(b,6*(h-1)+1:6*h)));
p(h)=plot(b,y,linespec{h});
end
hold off
end
Going row by row in data set A and taking the average of the values in the first six columns, then column 7 through 12, 13 through 18 and 19 through 14; generating four plots in total.
The next step was to smooth the resultant plot by averaging the values over a span of 9. So, I tweaked the script to the following;
for h=1:4
linespec = {'rx', 'gx', 'bx', 'yx'};
hold on
for b=1:365
y=mean(mean(A(b,6*(h-1)+1:6*h)));
w = smooth(y,9,'moving');
p(h)=plot(b,w,linespec{h});
end
hold off
end
Essentially just adding the w variable and replacing y with w in the plot command. Yet this has no effect whatsoever on my plot. Matlab doesn't throw up any errors either, so there doesn't seem to be a problem with the input size. Does anyone have an idea as to what the issue might be?
In either version of the loop, you appear to be plotting individual values of y against individual values of b. I presume, then, that y is a single value. You can't smooth a point, so the smooth operation is having no effect.
From the start, you don't need to make a loop to calculate the various means; mean can take a 2D matrix and return a vector. Calculate y in one go, then smooth that vector (should have length 365, I presume - depends on the size of input A). e.g.:
b = 1:365;
y=mean(A(:,6*(h-1)+1:6*h),2);
w = smooth(y,9,'moving');
plot(b,y,'rx');
hold on
plot(b,w,'gx');

Organize Points and Draw the Line

In Matlab, I've got several points in the 3D space. Those points represent a rope and I would like to draw a line linking all those points. Here is my problem: How the oraganization of those points should be done to have a "simple" and "more or less straigth line". In other words I would like to draw a line linking all the points from the first to the last one but not "going back". Maybe with a simple image i can explain better my problem:
This is what the code should do:
This is what the code shouldn't do:
Some idea of how can I achieve the intended result? How can I organize the points? I'm working with Matlab but if you know any paper where I can read how to do this it will be fine. Thank you.
If you just don't want to go back in the upper direction, the solution that #Dan suggested should be fine. Sort them in that direction before connecting.
However, if that is not a requirement but you are actually looking for a solution without ugly crossings that is as short as possible, you may want to look into solutions for the travelling salesman problem.
If you define the distance between 1 and 9 to be zero, the solution you find to the travelling salesman problem should give you a nice and short rope.
If you want to go for the TSP approach but get a little lost, just try a 'furthest insertion' start position or '2 opt' improvements as that is likely going to give a big improvement over random path selection already with minimal effort.
OK. I've found the right answer (by Gunther Struyf): Sort Coordinates Points in Matlab
In order to visualize the final result just add to Gunther's code the following lines:
row=data(:,1);
col=data(:,2);
figure
scatter(row,col,'r');
hold on
line(row(result),col(result));
The following code shows the same algorithm but for a 3D implementation:
close all;
data = [2,2, 2; 2,3,2 ; 1,2,3 ; 1,3,3 ; 2,1,3 ; 1,1,3 ; 3,2,4 ; 3,3,4 ; 3,1,5; 5,4,6; 7,3,8; 8,9,7; 9,4,7; 6,2,5; 5,8,6; 9,3,8;6,9,2];
row=data(:,1);
col=data(:,2);
frame=data(:,3);
dist = pdist2(data,data);
N = size(data,1);
result = NaN(1,N);
result(1) = 1; % first point is first row in data matrix
for ii=2:N
dist(:,result(ii-1)) = Inf;
[~, closest_idx] = min(dist(result(ii-1),:));
result(ii) = closest_idx;
end
figure
%Ploting the points directly (without sorting)
subplot(2,1,1);
scatter3(row,col,frame,'r');
hold on;
line(row,col,frame);
%Ploting after sorting
subplot(2,1,2);
scatter3(row,col,frame,'r');
hold on
line(row(result),col(result),frame(result));