MATLAB XYZ to Grid - matlab

I have a tab separated XYZ file which contains 3 columns, e.g.
586231.8 2525785.4 15.11
586215.1 2525785.8 14.6
586164.7 2525941 14.58
586199.4 2525857.8 15.22
586219.8 2525731 14.6
586242.2 2525829.2 14.41
Columns 1 and 2 are the X and Y coordinates (in UTM meters) and column 3 is the associated Z value at the point X,Y; e.g. the elevation (z) at a point is given as z(x,y)
I can read in this file using dlmread() to get 3 variables in the workspace, e.g. X = 41322x1 double, but I would like to create a surface of size (m x n) using these variables. How would I go about this?
Following from the comments below, I tried using TriScatteredInterp (see commands below). I keep getting the result shown below (it appears to be getting some of my surface though):
Any ideas what is going on to cause this result? I think the problem lies with themeshgrid command, though I'm not sure where (or why). I am currently putting in the following set of commands to calculate the above figure (my X and Y columns are in meters, and I know my grid size is 8m, hence ti/tj going up in 8s):
F = TriScatteredInterp(x,y,z,'nearest');
ti = ((min(x)):8:(max(x)));
tj = ((min(y)):8:(max(y)));
[qx,qy] = meshgrid(ti,tj);
qz = F(qx,qy);
imagesc(qz) %produces the above figure^

I think you want the griddata function. See Interpolating Scattered Data in MATLAB help.

Griddata and tirscattteredinterp are extremely slow. Use the utm2deg function on the file exchange and from there a combination of both vec2mtx to make a regular grid and then imbedm to fit the data to the grid.
I.E.
for i = 1:length(X)
[Lat,Lon ] = utm2deg(Easting ,Northing ,Zone);
end
[Grid, R] = vec2mtx(Lat, Lon, gridsize);
Grid= imbedm(Lat, Lon,z, Grid, R);

Maybe you are looking for the function "ndgrid(x,y)" or "meshgrid(x,y)"

Related

spurious lines using fimplicit on a modular function

I want to plot collections of repeating circular arcs and am having trouble with spurious lines showing up in the plots. For example, one of the plots I want is given by
a = #(x,y) ((mod(x,1) + 0.5).^2 + (mod(y,1) - 0.5).^2 - 1)
fimplicit(a,[-1,1],'MeshDensity',500)
but the output is incorrect as far as I can tell:
The implicit function is decidedly not zero on the verticle lines. I assume something funny is happening with the fimplicit algorithm and modular arithmetic. Any ideas how to get around this? Thanks!
That probably happens because your function is discontinuous at the lines x = k with k integer, as a surface plot reveals:
fsurf(a, [-2 2])
To verify that the discontinuity is the likely reason, consider the simpler example
f = #(x,y) (2*(x>=0)-1).*(2*(y>=0)-1);
This function is discontinuous at x = 0 and at y = 0. It jumps from 1 to −1 at x = 0 and at y = 0, but it never equals 0.
fsurf(f, [-2 2])
It can be seen that fimplicit is confused by the discontinuity, and thinks the function is 0 there:
fimplicit(f,[-2,2],'MeshDensity',500)
Looking at the source code of fimplicit, the actual work is seen to be done (on R2017b at least) by the class matlab.graphics.function.ImplicitFunctionLine in the second to last line. That class is a .p file, and is thus obfuscated, which means that unfortunately its source code cannot be seen.

align regression equation at correct position in matlab

let us suppose we have following code
function plot_test(x,y)
x_constucted=[ones(size(x)) x];
b = regress(y,x_constucted);
y_predicted=b(1)+b(2)*x;
scatter(x,y);
hold on
plot(x,y_predicted);
theString = sprintf('y = %.3f*x+%.3f ', b(2), b(1));
text(x(1), y_predicted(1), theString, 'FontSize', 8);
end
output of this equation is the following figure
my question is : how to align equation out of line? for instance on top left size? thanks in advance
If I understand you correctly, you want to move the printed equation out of the dots. Check out the text() function description. The first two values define the x and y position in your plot for the text.
x=1;
y=25;
To move it up, use the new variables in text(x,y,...). Hope that helps.
Some time ago I was looking for a solution for the same exact problem. As you may know, the legend command allows to specify a Location parameter and one of its many options is called best, described in the official Matlab documentation (here) as follows:
Inside axes where least conflict occurs with plot data
My workaround abuses this feature in order to find the best location to place a single text annotation inside the plot. The code below uses a build-in dataset since you didn't specify how your data looks like:
load carsmall;
x = [ones(size(Horsepower)) Horsepower];
y = MPG;
b = regress(y,x);
y_hat = b(1) + b(2) .* Horsepower;
scatter(Horsepower,y);
hold on;
plot(Horsepower,y_hat);
text_at_best(sprintf('y = %.3f*x+%.3f ',b(2),b(1)),'FontSize',12);
function h = text_at_best(txt,varargin)
l = legend(txt,[varargin{:}]);
t = annotation('textbox',varargin{:});
t.String = txt;
t.Position = l.Position;
t.LineStyle = 'None';
delete(l);
if nargout
h = t;
end
end
Here is the final result:
I don't know if this can fit your needs... but developing an algorithm for finding a non overlapping part of the plot in which to place a text looked like an overkill to me. Despite the text being quite far from the prediction line, it's still elegant, clear and comprehensible. The same goes with an even quicker workaround which consists in setting the regression equation as the plot title (blink blink).

MATLAB Plotting Inner Matrix elements must agree

So I'm just trying to plot 4 different subplots with variations of the increments. So first would be dx=5, then dx=1, dx=0.1 and dx=0.01 from 0<=x<=20.
I tried to this:
%for dx = 5
x = 0:5:20;
fx = 2*pi*x *sin(x^2)
plot(x,fx)
however I get the error inner matrix elements must agree. Then I tried to do this,
x = 0:5:20
fx = (2*pi).*x.*sin(x.^2)
plot(x,fx)
I get a figure, but I'm not entirely sure if this would be the same as what I am trying to do initially. Is this correct?
The initial error arose since two vectors with the same shape cannot be squared (x^2) nor multiplied (x * sin(x^2)). The addition of the . before the * and ^ operators is correct here since that will perform the operation on the individual elements of the vectors. So yes, this is correct.
Also, bit of a more advanced feature, you can use an anonymous function to aid in the expressions:
fx = #(x) 2*pi.*x.*sin(x.^2); % function of x
x = 0:5:20;
plot(x,fx(x));
hold('on');
x = 0:1:20;
plot(x,fx(x));
hold('off');

How can I plot data to a “best fit” cos² graph in Matlab?

I’m currently a Physics student and for several weeks have been compiling data related to ‘Quantum Entanglement’. I’ve now got to a point where I have to plot my data (which should resemble a cos² graph - and does) to a sort of “best fit” cos² graph. The lab script says the following:
A more precise determination of the visibility V (this is basically how 'clean' the data is) follows from the best fit to the measured data using the function:
f(b) = A/2[1-Vsin(b-b(center)/P)]
Granted this probably doesn’t mean much out of context, but essentially A is the amplitude, b is an angle and P is the periodicity. Hence this is also a “wave” like the experimental data I have found.
From this I understand, as previously mentioned, I am making a “best fit” curve. However, I have been told that this isn’t possible with Excel and that the best approach is Matlab.
I know intermediate JavaScript but do not know Matlab and was hoping for some direction.
Is there a tutorial I can read for this? Is it possible for someone to go through it with me? I really have no idea what it entails, so any feed back would be greatly appreciated.
Thanks a lot!
Initial steps
I guess we should begin by getting a representation in Matlab of the function that you're trying to model. A direct translation of your formula looks like this:
function y = targetfunction(A,V,P,bc,b)
y = (A/2) * (1 - V * sin((b-bc) / P));
end
Getting hold of the data
My next step is going to be to generate some data to work with (you'll use your own data, naturally). So here's a function that generates some noisy data. Notice that I've supplied some values for the parameters.
function [y b] = generateData(npoints,noise)
A = 2;
V = 1;
P = 0.7;
bc = 0;
b = 2 * pi * rand(npoints,1);
y = targetfunction(A,V,P,bc,b) + noise * randn(npoints,1);
end
The function rand generates random points on the interval [0,1], and I multiplied those by 2*pi to get points randomly on the interval [0, 2*pi]. I then applied the target function at those points, and added a bit of noise (the function randn generates normally distributed random variables).
Fitting parameters
The most complicated function is the one that fits a model to your data. For this I use the function fminunc, which does unconstrained minimization. The routine looks like this:
function [A V P bc] = bestfit(y,b)
x0(1) = 1; %# A
x0(2) = 1; %# V
x0(3) = 0.5; %# P
x0(4) = 0; %# bc
f = #(x) norm(y - targetfunction(x(1),x(2),x(3),x(4),b));
x = fminunc(f,x0);
A = x(1);
V = x(2);
P = x(3);
bc = x(4);
end
Let's go through line by line. First, I define the function f that I want to minimize. This isn't too hard. To minimize a function in Matlab, it needs to take a single vector as a parameter. Therefore we have to pack our four parameters into a vector, which I do in the first four lines. I used values that are close, but not the same, as the ones that I used to generate the data.
Then I define the function I want to minimize. It takes a single argument x, which it unpacks and feeds to the targetfunction, along with the points b in our dataset. Hopefully these are close to y. We measure how far they are from y by subtracting from y and applying the function norm, which squares every component, adds them up and takes the square root (i.e. it computes the root mean square error).
Then I call fminunc with our function to be minimized, and the initial guess for the parameters. This uses an internal routine to find the closest match for each of the parameters, and returns them in the vector x.
Finally, I unpack the parameters from the vector x.
Putting it all together
We now have all the components we need, so we just want one final function to tie them together. Here it is:
function master
%# Generate some data (you should read in your own data here)
[f b] = generateData(1000,1);
%# Find the best fitting parameters
[A V P bc] = bestfit(f,b);
%# Print them to the screen
fprintf('A = %f\n',A)
fprintf('V = %f\n',V)
fprintf('P = %f\n',P)
fprintf('bc = %f\n',bc)
%# Make plots of the data and the function we have fitted
plot(b,f,'.');
hold on
plot(sort(b),targetfunction(A,V,P,bc,sort(b)),'r','LineWidth',2)
end
If I run this function, I see this being printed to the screen:
>> master
Local minimum found.
Optimization completed because the size of the gradient is less than
the default value of the function tolerance.
A = 1.991727
V = 0.979819
P = 0.695265
bc = 0.067431
And the following plot appears:
That fit looks good enough to me. Let me know if you have any questions about anything I've done here.
I am a bit surprised as you mention f(a) and your function does not contain an a, but in general, suppose you want to plot f(x) = cos(x)^2
First determine for which values of x you want to make a plot, for example
xmin = 0;
stepsize = 1/100;
xmax = 6.5;
x = xmin:stepsize:xmax;
y = cos(x).^2;
plot(x,y)
However, note that this approach works just as well in excel, you just have to do some work to get your x values and function in the right cells.

Binning in matlab

I have been unable to find a function in matlab or octave to do what I want.
I have a matrix m of two columns (x and y values). I know that I can extract the column by doing m(:,1) or m(:,2). I want to split it into smaller matricies of [potentially] equal size and and plot the mean of these matricies. In other words, I want to put the values into bins based on the x values, then find means of the bins. I feel like the hist function should help me, but it doesn't seem to.
Does anyone know of a built-in function to do something like this?
edit
I had intended to mention that I looked at hist and couldn't get it to do what I wanted, but it must have slipped my mind.
Example: Let's say I have the following (I'm trying this in octave, but afaik it works in matlab):
x=1:20;
y=[1:10,10:1];
m=[x, y];
If I want 10 bins, I would like m to be split into:
m1=[1:2, 1:2]
...
m5=[9:10, 9:10]
m6=[10:11, 10:-1:9]
...
m10=[19:20, 2:-1:1]
and then get the mean of each bin.
Update: I have posted a follow-up question here. I would greatly appreciate responses.
I have answered this in video form on my blog:
http://blogs.mathworks.com/videos/2009/01/07/binning-data-in-matlab/
Here is the code:
m = rand(10,2); %Generate data
x = m(:,1); %split into x and y
y = m(:,2);
topEdge = 1; % define limits
botEdge = 0; % define limits
numBins = 2; % define number of bins
binEdges = linspace(botEdge, topEdge, numBins+1);
[h,whichBin] = histc(x, binEdges);
for i = 1:numBins
flagBinMembers = (whichBin == i);
binMembers = y(flagBinMembers);
binMean(i) = mean(binMembers);
end