How to mark the peak with Matlab? - matlab

How can I use the plot function to mark the peak?
Example:
a = [0 1 3 23 3 9 10 28 2]
[p,locs] = findpeaks(a)
Result:
p =
23 28
locs =
4 8

You dont provide an x range so create one (you can change this to what you want).
figure
x = [1:length(a)];
plot(x,a,'k');
The above plots your original data points the following will
hold on
plot(locs,p,'ro');
plot your peaks as red circle points on top of the original series. If you need a non-integer x-range you will need to calculate the appropriate values that correspond to the indices in your locs array and use those x values instead.

Related

How to plot an n-points discrete segment between two given points in Matlab?

Given two points, what's the best way to plot - in Matlab - a n-points discrete segment that has these points as extremes?
What if I have to plot a chain of discrete segments like that?
Thank you in advance!
The following is an example of what I'm trying to achieve in the easiest possible way
Assuming your points are stored in the fashion p = [35,0; 40,0.2; 45,0], i.e.
p =
35.0000 0
40.0000 0.2000
45.0000 0
Then you can create an array for all x values by finding the mininum and maximum values of the x coordinate. Here, the x coordinate is the first column of p, i.e. p(:,1). You can use the colon operator : to create the x array by
x = min(p(:,1)) : 1 : max(p(:,1))
The 1 in the middle is the step width. For your example, this will create the array
x =
35 36 37 38 39 40 41 42 43 44 45
Now you can interpolate all y value linearly with the interp1 function. This does a linear interpolation by default. The syntax is thus
y = interp1(p(:,1), p(:,2), x)
Finally you can plot the vectors x and y using plot. If you only want to print circles, use 'o' as LineSpec specifier. To connect the circles using a line, use '-o'. There's an extensive list of options here. You can also add the color of the line / markers to this format spec. Black circles would be 'ok':
plot(x, y, 'ok')

Count occurrences and stretch array in matlab

Let
input = [0 0 0 5 5 7 8 8];
I now want to transform this vector into the form
output = [3 3 3 3 5 5 6 8];
Which basically is a stairs plot.
Explanation
The input vector is used to plot data points along the x-axis. The y-axis is thereby provided by 1:length(input). So the resulting plot shows the cumulative number of datapoints along the y-axis and the time of occurrence along the x-axis.
I now want to fit a model against my dataset. Therefor I need a vector that provides the correct value for a certain time (x-value).
The desired output vector basically is the result of a stairs plot. I am looking for an efficient way to generate the desired vector in matlab. The result of
[x, y] = stairs(input, 1:length(input));
did not bring me any closer.
It can be done with bsfxun as follows:
x = [0 0 0 5 5 7 8 8];
y = sum(bsxfun(#le, x(:), min(x):max(x)), 1);
This counts, for each element in 1:numel(x), how many elements of x are less than or equal to that.

Reconstruct 3D graph with surf in matlab?

I usually use surf function to plot 3D figures in matlab, but now the data is different, so I am using plot3 and I have the below figure. Do you have any idea how I reconstruct this figure to be more understandable even if by using different function.
To be more concise, I have X values, with each X value there is a value of Y and value of Z.
X = [ 1 ;2 ;4; 8; 16; 32; 64];
Z = [ 1; 1.8 ; 3.46 ; 6.74 ; 13.18 ; 24.34 ; 39.33]
Y = [0 ; 56.92 ; 91 ; 109.95 ; 119 ; 123.57 ; 125.51]
fig = plot3(log(X),Y,Z,'b.-');
XLABEL=[ 1 2 4 8 16 32 64];
set(gca,'XTickLabel',XLABEL);
set(gca,'XTick',log(XLABEL));
YLABEL= [ 0 30 60 90 120 150 180];
set(gca,'YTickLabel',YLABEL);
set(gca,'YTick',YLABEL);
ZLABEL= [0 5 10 15 20 25 30 35 40 45 50 55];
set(gca,'ZTickLabel',ZLABEL);
set(gca,'ZTick',(ZLABEL));
ylim([0 180]);
zlim([0,55]);
grid on
It's difficult to say, because we don't have a context. Common options are:
Plotting x/y and x/z in two separate plots. Precisely readable but difficult to get the connection between y and z. subplot
Plotyy, same as previous but in one plot. Y and Z values which correspond to the same x-value are aligned. plotyy
Use a plot3 as shown above, but connect each point to the x/z plane. (details below)
Project the line on one or multiple planes and draw it there. (Plot the line again, setting x, y or z to 7 0 or 180, which is the location of your axis)
If two axis are of major importance, use a simple 2d plot and represent the third dimension using color/dotsize/annotations etc...
Code for Option 3:
At the end of your code, add the following code:
X2=[X';X';nan(size(X'))];
X2=X2(:);
Y2=[Y';Y';nan(size(Y'))];
Y2=Y2(:);
Z2=[Z';zeros(size(Z'));nan(size(Z'))];
Z2=Z2(:);
hold on
plot3(log(X2),Y2,Z2,'--')
To understand it, you have to know that matlab skips nans while plotting. Thus the code above generates a independent line segment for each point, connecting it to the ground plane.

drow cumulative distribution function in matlab

I have two vectors of the same size. The first one can have any different numbers with any order, the second one is decreasing (but can have the same elements) and consists of only positive integers. For example:
a = [7 8 13 6];
b = [5 2 2 1];
I would like to plot them in the following way: on the x axis I have points from a vector and on the y axis I have the sum of elements from vector b before this points divided by the sum(b). Therefore I will have points:
(7; 0.5) - 0.5 = 5/(5+2+2+1)
(8; 0.7) - 0.7 = (5+2)/(5+2+2+1)
(13; 0.9) ...
(6; 1) ...
I assume that this explanation might not help, so I included the image
Because this looks to me as a cumulative distribution function, I tried to find luck with cdfplot but with no success.
I have another option is to draw the image by plotting each line segment separately, but I hope that there is a better way of doing this.
I find the values on the x axis a little confusing. Leaving that aside for the moment, I think this does what you want:
b = [5 2 2 1];
stairs(cumsum(b)/sum(b));
set(gca,'Ylim',[0 1])
And if you really need those values on the x axis, simply rename the ticks of that axis:
a = [7 8 13 6];
set(gca,'xtick',1:length(b),'xticklabel',a)
Also grid on will add grid to the plot

Resampling Matrix and restoring in one single Matrix

I am new to this forum, so please bear with me.
I have been working on this Matlab problem for a while now:
I have a digital elevation model (DEM) new_sub(x,y) in tif format. So it is a x-by-y matrix containing heights (z). I wish to resample parts of this DEM in different resolutions and restore this in another matrix. So far I have been working with for loops to change the resolution of different areas of the DEM and then wrote the results to an xyz-file:
x y z
1 1 123
1 2 233
1 3 231
2 1 235
2 2 531
2 3 452
and so forth.
Here is the code:
xmax = size(new_sub,2);
ymax = size(new_sub,1);
for k=1:200 % y
for l=1:xmax % x
fprintf(fid, '%d %d %d \n',l,xmax+1-k,new_sub(k,l));
end
end
% 1:4
for k=200/2+1:size(new_sub,1)/2
for l=1:size(new_sub,2)/2
fprintf(fid, '%d %d %d \n',l*2,ymax+2-k*2,new_sub(k*2,l*2));
end
end
This does work, but seems to be rather complicated. Moreover, it does not allow me to store the resampled areas in a single matrix within Matlab.
Is there a more efficient way of resampling certain areas of a Matrix with different resolutions, writing them into a new Matrix containg all resampled areas and then writing it to a file? I was looking into repmap, but could not think of a clever way of using it!
Your help is much appreciated!
THeo
To re-sample a matrix in Matlab:
For example matrix M:
M = [1 2 3 4 5;
6 7 8 9 10;
11 12 13 14 15;
16 17 18 19 20;
21 22 23 24 25];
If we wanted to sample on every nth pixel, it is as simple as this:
m = M(1:n:end, 1:n:end)
So for n=2
m = 1 3 5
11 13 15
21 23 25
I suggest you read up on indexing in matlab and also on using the colon operator to create vectors in matlab
Now in order to get in the "x y z" format you mentioned, first use meshgrid to generate matrices of X and Y coordinates.
[X, Y] = meshgrid(1:n:size(M,1), 1:n:size(M,2))
notice I use n to downsample X and Y. Now you just need to flatten the three matrices and combine them:
final = [X(:), Y(:), m(:)]
Finally to save as a file I suggest you type help save or help dlmwrite in the Matlab command promt and use either of those functions to save final
To me the easiest way to do looks like using imresize. You can treat your elevation map as an image I. Then you can cut sections out by indexing and rescaling as follows:
I = imread('my.tiff'); % read
section = I(1:200, :); % cut the first 200 rows and all columns
sectionResized = imresize(section, [numrows numcols]) % resample
imwrite(sectionResized, 'mynew.tiff'); % save