Matlab interp1 curve doesn't follow data - matlab

I've been using interp1 to plot curves to follow sets of datapoints, and for most of the datapoints it's been working:
But when I try it with another set of datapoints it doesn't follow them at all:
For both interpolations the code I'm using is just:
curve = interp1(x, y, 'pchip');
Where x is just a set of numbers that correspond to the x axis of each datapoint, and y is the values themselves.
I can't tell what is different about the second dataset that is causing the interp1 function to not follow the data.

So with thanks to #m.s. for providing his code, it turns out the issue is that with the second graph I was interpolating with x= -90:10:90, whereas if I interpolate with 1:19, in a similar manner to the first graph, then the problem is fixed.

Related

Draw 3D model of more than one curve in matlab with vectors

I'm doing a project that involves making a 3D model of the cornea in matlab. I have 6 plot3 in the same graph to draw one cornea
but now i want a surface plot.
Don't mind the curve orientation.
Note that all the plot3 have x, y and z that are vectors
Thanks in advance
If I were you I would use the Surf command doku surf. It is used to display [x,y,z] data. Since you have not have as many touples of data (just 6) you will have to interpolate all the other values. Therefore I would use the scattered interpolant function doku scattered interpolant.
!!!!!!!!!!!!!!Take care all this is pseudocode!!!!!!!!!!!!!!!!
F = scatteredInterpolant(x_existing,y_existing,z_existing);
generates a scattered interpolant object. You do already feed your already existing data in there. Afterwards you generate the points at which you want to interpolate:
%generates samples from -4 t0 4 in 0.05 steps
[x_sample,y_sample] = meshgrid(-4:0.05:4,-4:0.05:4);
Now you calculate the fitted z values using the scattered interpolant obj
z_interpolated=F(x_sample,y_sample) %interpolates
surf(x_sample,y_sample,z_interpolated) %plots with surf between -4 and 4
!!!!!!!!!!!!!!!From here working code!!!!!!!!!!!!!!!!!!!!!
%serialiasation of data (special for this usecase)
x_data=[h0(30:632,6);(a30(28:408,3))+0.527;(a60(276:632,3));(a90(26:575,3))+3.417;(a120(188:586,3))-0.6625;(a150(16:380,3))+1.173];
y_data=[(h0(30:632,5));((a30(28:408,2))-0.9128);(a60(276:632,2));(a90(26:575,2));(a120(188:586,2))-0.3825;((a150(16:380,2))+2.032)];
z_data=[yA0;yA30+0.162;yA60;yA90+0.837;yA120+0.135;yA150+0.135];
% cleaning the data of nan values
x_data=x_data(~isnan(z_data));
y_data=y_data(~isnan(z_data));
z_data=z_data(~isnan(z_data));%random for the looks
%interpolating
F=scatteredInterpolant(x_data,y_data,z_data);
%read yourself what this does
F.Method = 'natural';
F.ExtrapolationMethod = 'none';
%choosing sample points
[x_sample,y_sample] = meshgrid(-6:0.05:6,-6:0.05:6);
%interpolation
z_interpolated=F(x_sample,y_sample);
%plot
surf(x_sample,y_sample,z_interpolated)
I hope I was able to help you. If you try it and it works it would be very nice of you to post the working code here so that in the future here stands a working solution.

i have 100*100 matrix, how can i make plot3 graph?

I have a 100 x 100 matrix and i have to use plot3 in MATLAB environment to graph this data. I tried plot3(matrix name) but I faced this error "not enough input arguments". I think plot3 needs 3 input arguments, but I only have this matrix of data. could anyone help me to solve this problem? Is there any alternative for plot3 when we don't have enough arguments?
I need a graph like this:
I think you want to plot the values in a figure as a sort of surface element. What you can do then is:
[X,Y] = size(matrix);
figure;
surface(1:X,1:Y,matrix);
What this does is that it creates a vector for both X and Y indices, as possible in surface. The X and Y indices are obtained by setting them as integers from 1:size, so basically you assign the location of each matrix element to an index.
Note that you can strictly speaking use surface(matrix) as well, but the former approach allows you to use custom indexing, as long as the lengths of the vectors X and Y are the same as the size of your matrix.
For the waterfall use:
figure;
waterfall(matrix);
Sample code:
A=rand(100);
figure;
waterfall(1:100,1:100,A);
Gives:
where you can play around with the name-value pairs, see the documentation on that.
I think what you need is mesh or surf instead of plot3.
plot3 draws a line in 3d-space, so it will need three vectors of the same length (one for each dimension).
When you have a matrix, one reasonable way of displaying it is as a surface in 3d space, which is done by the functions mesh and surf.
Try it out! I hope i helps!

3d plot with ksdensity in matlab

I have a problem in matlab.
I used a ksdensity function on a vector of deltaX, which was my computed X minus actual X.
And I did the same on deltaY.
Then I used plot on that data. This gave me two 2d plots.
As I have two plots showing how (in)accurate was my system in computing X and Y (something like gaussian bell it was). Now I would like to have one plot but in 3d.
The code was just like that:
[f,xi] = ksdensity(deltaX);
figure;
plot(xi,f)
Ok what I'm about to show is probably not the correct way to visualize your problem, mostly because I'm not quite sure I understand what you're up to. But this will show you an example of how to make the Z matrix as discussed in the comments to your question.
Here's the code:
x = wgn(1000,1,5);%create x and y variables, just noise
y = wgn(1000,1,10);
[f,xi] = ksdensity(x);%compute the ksdensity (no idea if this makes real-world sense)
[f2,xi2] = ksdensity(y);
%create the Z matrix by adding together the densities at each x,y pair
%I doubt this makes real-world sense
for z=1:length(xi)
for zz = 1:length(xi2)
Z(z,zz) = f(z)+f2(zz);
end
end
figure(1)
mesh(xi,xi2,Z)
Here's the result:
I leave it up to you to determine the correct way to visualize your density functions in 3D, this is just how you could make the Z matrix. In short, the Z matrix contains the plot elevation at each x,y coordinate. Hope this helps a little.

matlab: cdfplot of relative error

The figure shown above is the plot of cumulative distribution function (cdf) plot for relative error (attached together the code used to generate the plot). The relative error is defined as abs(measured-predicted)/(measured). May I know the possible error/interpretation as the plot is supposed to be a smooth curve.
X = load('measured.txt');
Xhat = load('predicted.txt');
idx = find(X>0);
x = X(idx);
xhat = Xhat(idx);
relativeError = abs(x-xhat)./(x);
cdfplot(relativeError);
The input data file is a 4x4 matrix with zeros on the diagonal and some unmeasured entries (represent with 0). Appreciate for your kind help. Thanks!
The plot should be a discontinuous one because you are using discrete data. You are not plotting an analytic function which has an explicit (or implicit) function that maps, say, x to y. Instead, all you have is at most 16 points that relates x and y.
The CDF only "grows" when new samples are counted; otherwise its value remains steady, just because there isn't any satisfying sample that could increase the "frequency".
You can check the example in Mathworks' `cdfplot1 documentation to understand the concept of "empirical cdf". Again, only when you observe a sample can you increase the cdf.
If you really want to "get" a smooth curve, either 1) add more points so that the discontinuous line looks smoother, or 2) find any statistical model of whatever you are working on, and plot the analytic function instead.

How to create 3D joint density plot MATLAB?

I 'm having a problem with creating a joint density function from data. What I have is queue sizes from a stock as two vectors saved as:
X = [askQueueSize bidQueueSize];
I then use the hist3-function to create a 3D histogram. This is what I get:
http://dl.dropbox.com/u/709705/hist-plot.png
What I want is to have the Z-axis normalized so that it goes from [0 1].
How do I do that? Or do someone have a great joint density matlab function on stock?
This is similar (How to draw probability density function in MatLab?) but in 2D.
What I want is 3D with x:ask queue, y:bid queue, z:probability.
Would greatly appreciate if someone could help me with this, because I've hit a wall over here.
I couldn't see a simple way of doing this. You can get the histogram counts back from hist3 using
[N C] = hist3(X);
and the idea would be to normalise them with:
N = N / sum(N(:));
but I can't find a nice way to plot them back to a histogram afterwards (You can use bar3(N), but I think the axes labels will need to be set manually).
The solution I ended up with involves modifying the code of hist3. If you have access to this (edit hist3) then this may work for you, but I'm not really sure what the legal situation is (you need a licence for the statistics toolbox, if you copy hist3 and modify it yourself, this is probably not legal).
Anyway, I found the place where the data is being prepared for a surf plot. There are 3 matrices corresponding to x, y, and z. Just before the contents of the z matrix were calculated (line 256), I inserted:
n = n / sum(n(:));
which normalises the count matrix.
Finally once the histogram is plotted, you can set the axis limits with:
xlim([0, 1]);
if necessary.
With help from a guy at mathworks forum, this is the great solution I ended up with:
(data_x and data_y are values, which you want to calculate at hist3)
x = min_x:step:max_x; % axis x, which you want to see
y = min_y:step:max_y; % axis y, which you want to see
[X,Y] = meshgrid(x,y); *%important for "surf" - makes defined grid*
pdf = hist3([data_x , data_y],{x y}); %standard hist3 (calculated for yours axis)
pdf_normalize = (pdf'./length(data_x)); %normalization means devide it by length of
%data_x (or data_y)
figure()
surf(X,Y,pdf_normalize) % plot distribution
This gave me the joint density plot in 3D. Which can be checked by calculating the integral over the surface with:
integralOverDensityPlot = sum(trapz(pdf_normalize));
When the variable step goes to zero the variable integralOverDensityPlot goes to 1.0
Hope this help someone!
There is a fast way how to do this with hist3 function:
[bins centers] = hist3(X); % X should be matrix with two columns
c_1 = centers{1};
c_2 = centers{2};
pdf = bins / (sum(sum(bins))*(c_1(2)-c_1(1)) * (c_2(2)-c_2(1)));
If you "integrate" this you will get 1.
sum(sum(pdf * (c_1(2)-c_1(1)) * (c_2(2)-c_2(1))))