I am having problem with converting Shape file which is a border of Germany with their X,Y coordinates to raster matrix format of same shape. I simply don't know which method to use for this case. I would be thankful if somebody help me to find the right way of thinking for this application.
It can be very much with ease obtained in MATLAB. YOu need to use function inpolygon. This function gives you indices of the points lying inside and putside the given polygon. Once you know the indices, you can get what you want. YOu may check the below demo:
x = [1 2 3 4 3 2]';
y = [4 5 5 4 3 3]';
k = boundary(x,y);
x0 = min(x) ; x1 = max(x) ;
y0 = min(y) ; y1 = max(y) ;
[X,Y] = meshgrid(linspace(x0,x1),linspace(y0,y1)) ;
idx = inpolygon(X(:),Y(:),x(k),y(k)) ;
X(~idx) = NaN ;
Y(~idx) = NaN ;
plot(x,y,'.r')
hold on
patch(x(k),y(k),'k') ;
plot(X(idx),Y(idx),'.r')
Just replace (x,y) above with your shape file coordinates, you will get what you want.
Related
I have got a data that are in a matrix of size N rows by 3 columns, each column corresponds to particular point in x, y and z axis. The data in that matrix have already been pre generated so my task is to plot it in a mesh as this is faster than creating the same plot with scatter function requiring 1M data points just to look similar.
The z will determine the corresponding color intensity as well as the valley and hills of the mesh.
Consider the example below:
A = [1 2 3; 1 3 2; 1 5 8; 1 2 6; 6 1 2];
mesh(A(:,1),A(:,2),A(:,3));
The attempt was nice, as I have already supplied appropriate x, y, and z for mesh function. However, I just get empty plot when I tested it. So, I am looking for help on how to plot mesh (with intensity profile on z) Nx3 matrix in Octave/Matlab?
Read about delaunay triangulation. YOu can make an unstructured mesh from your (x,y,z) data and then plot the mesh.
A = [1 2 3; 1 3 2; 1 5 8; 1 2 6; 6 1 2];
% mesh(A(:,1),A(:,2),A(:,3));
x = A(:,1) ;
y = A(:,2) ;
z = A(:,3) ;
dt = delaunayTriangulation(x,y) ;
triplot(dt) ;
I need to generate a curve between scatter points then identify the unit normal of the curve at each point. Here is an example of a point cloud
figure
x = [1 2 0 0 1 1 2 3 4 2];
y = [4 6 9 1 1 2 4 9 2 3];
scatter(x,y)
hold on
line(x,y)
xlim([0 4])
ylim([0 10])
NOTE: the 2 points along the y-axis are connected
Instead of a line between the points, I'd like to create a smooth curve. I'm not sure how to do this when points in x and y repeat. An attempt using spline fails. After I know the curve, I need to find the unit normals at each point. How do I go about this?
EDIT:
Basically I want to do what is show here for polyfit in the matlab docs. Assuming that x was unique in my case, this wouldn't be an issue. I could identify the polynomial and then, I believe, determine the unit normals from the polynomial function evaluated at that point. But in my case, the x and y data repeat so a straight forward application doesn't work.
One way to get a smooth path is to treat this as a parametric function and interpolate x and y separately.
x = [1 2 0 0 1 1 2 3 4 2];
y = [4 6 9 1 1 2 4 9 2 3];
t = 1:numel(x);
tq = 1:0.1:t(end);
xq = interp1(t,x,tq,'v5cubic');
yq = interp1(t,y,tq,'v5cubic');
plot(x,y,' ob',xq,yq,'-r');
To estimate the normals you can take the average normal of the two line segments around the sample points. This code is a bit ugly but it gets the job done.
n = zeros(2,numel(x));
for tidx = 1:numel(t)
tt = t(tidx);
idx1 = find(tq <= tt,1,'last');
idx0 = idx1 - 1;
idx2 = idx1 + 1;
if idx0 > 0
n1 = [yq(idx1) - yq(idx0); xq(idx0) - xq(idx1)];
n(:,tidx) = n(:,tidx) + n1/norm(n1);
end
if idx2 <= numel(tq)
n2 = [yq(idx2) - yq(idx1); xq(idx1) - xq(idx2)];
n(:,tidx) = n(:,tidx) + n2/norm(n2);
end
n(:,tidx) = n(:,tidx) / norm(n(:,tidx));
end
plot(x,y,' ob',xq,yq,'-r',[x.' x.'+n(1,:).'].', [y.' y.'+n(2,:).'].',' -k');
axis equal;
If you use pchip instead of v5cubic for the interpolation method then you get more symmetry around the sample points. However, it appears that any sharp turns (90 degrees or greater) are not smoothed.
I have coordinates in an matrix (an image) that I want to change, I have the coordinates in the form of a x coordinates vector and a y coordinates vector. How do I change the values of only those coordinates.
I've tried to use the notation I(x,y) but it gives me all the possible combinations:
I = zeros(10,10);
x = [4 6 8];
y = [7 3 1];
I(x,y) = 1;
imshow(I);
gives me: while what I want to get is:
using sub2ind function like the following:
I(sub2ind(size(I),x,y)) = 1
I have a range of data represented in the vector C
and have the data classes represented by the vector R
C = [1.71974522292994
1.91974522292994
2.03821656050955
2.13375796178344
2.16560509554140
2.22929936305733
2.35668789808917
2.38853503184713
2.54777070063694
2.61146496815287
2.70700636942675
2.73885350318471
2.83439490445860
2.96178343949045
3.02547770700637
3.31210191082803]
R = [1.71974522292994
2.03821104580359
2.35667686867724
2.67514269155088
2.99360851442453
3.31207433729818
3.63054016017183]
I need to do a histogram and a curve to overlap Standard Normal
z = histc(C,R); bar(R,z);
but the vector z that represents the frequency is not correct.
z = [2 4 4 4 1 1]'
on excell is so, and represents well the histogram
z = [1 1 4 4 4 1 1]'
you could suggest a solution using these two vectors?
Tnks
That's because Matlab's definition of histc:
n(k) counts the value x(i) if edges(k) <= x(i) < edges(k+1)
whereas Excel probably uses the more standard
edges(k) < x(i) <= edges(k+1)
So essentially you need to move the equal sign from below to above. You can get that either
By the trick of changing signs to both vectors and flipping the second (to keep it sorted):
>> z = histc(-C,-R(end:-1:1))
z =
1
1
4
4
4
1
1
Using the very powerful bsxfun function to directly compute the histogram with the equal sign above:
z = diff(sum(bsxfun(#le, C(:), [-inf R(:).'])));
I found it helpful to use this
z = histc(-C,-R);
the loop that I used for inside includes matrices with vectors of different length. I then filled the matrix with NaN
C and classe = [30x14] created by vectors with different lengths + NaN
[nr,nc] = size(C);
Freq = NaN*ones(nr,nc);
R = NaN*ones(nr,nc);
CC = NaN*ones(nr,nc);
I do not find a way in order to create the correct number of figures with the correct subplot.
In each figure there must be 4 subplot.
for k = 1:4
for j= 1 : nc;
R = classe(:,j);
CC = C(:,j);
FF = Freq(:,j);
R = R(~isnan(B)); % toglie i valori NaN
CC = CC(~isnan(CC));
R = sort(R,'descend');
CC = sort(C,'descend');
the line of Plot
FF = histc(-C,-R); % Calculate the J-th absolute frequencies
figure(k); <===?????
subplot(2,2,k) <=== ????????
bar(B,FF);
reassemble the matrices
if length(B)<nr
R(length(R)+1:nr)=NaN; % riempie la parte di colonna vuota
if length(CC)< nr;
C(length(CC)+1:nr)=NaN;
if length(FF)< nr;
FF(length(FF)+1:nr)=NaN;
end
end
end
classe(:,j)=R(:); % matrice classe
C(:,j)=CC(:) % matrice Elementi;
Freq(:,j)=FF(:); %Matrice Frequenze Assolute
end
the next steps concerns the in plotting of 3 figures. Each figure contains 4 subplot
I would also be able to superimpose on each histogram a standard normal curve ...
a tip?
tnks
I'm new to Matlab but I know a bit about programming.
For class, we have been asked to generate a matrix that gives the vertices of a two dimensional n-sided shape where n>=4. Then, generate the vectors to connect the vertices. We were also given a hint: a vector for each segment can be found by adding the vectors drawn from the origin to each of two adjacent vertices.
I know how to create a matrix using A = [1 1; 1 2; 2 2; 2 1] but I'm not sure how to draw the vectors given this or any other matrix.
The plot() function looks promising, but I'm unsure how to use it with the matrix.
Thank you for any suggestions.
Btw, I'm using Matlab 2011a
I'm not exactly sure how your matrix represents your shape but you might for example let the x-coordinates of the shape be the first column of your array, then let the y-coordinates be the 2nd column, like:
A = [1 1; 1 2; 2 2; 2 1];
x = A(:,1);
y = A(:,2);
fill(x,y,'g');
axis([0 3 0 3]);
axis square;
Which in your case plots a square from the matrix A:
Or construct something a little more complicated like a pentagon:
theta = [0:pi/2.5:2*pi];
x = sin(theta);
y = cos(theta);
% your matrix is then:
B(:,1) = x;
B(:,2) = y;
B
figure;fill(x,y,'g');
axis square;
Which gives:
If you just want to plot the outline with plot (not fill the interior with fill), just remember you have to repeat the initial point at the end so that the polygonal line is closed:
A = [1 1; 1 2; 2 2; 2 1];
B = [A; A(1,:) ]; %// repeat first row at the end
plot(B(:,1),B(:,2))
axis equal %// same scale on both axes
axis([min(x)-.5 max(x)+.5 min(y)-.5 max(y)+.5]) %// larger axes for better display