Matlab, smaller duration histogram - matlab

I have this histogram plot. It show histogram for every 100 duration. I want to show histogram in smaller duration for example every 10 .How can I do this in Matlab?Thanks.

Use
hist(data,nbins)
to specify the number of bins. Default is 10, so if you want to have it split not by 100 but by 10 use:
hist(data,100)

In addition to the answer by #slezadav, if you want to set a given bin width (10 in your example) you can use something like
hist(data,5:10:995)
Using a vector as the second argument of hist specifies bin centers.

As explained in the docs:
use the nbins argument of the hist function:
rng(0,'twister')
data = randn(1000,1);
figure
nbins = 5;
hist(data,nbins)
you can check this by changing the parameter of nbins.
See also here: http://www.mathworks.de/de/help/matlab/ref/hist.html

Related

Calculate the autocorrelation of a time series created from a normal distribution

I generate a time series from a normal distribution and then I try to plot the autocorrelation by using the following code snippet:
ts1 = normrnd(0,0.25,1,100);
autocorrelation_ts1 = xcorr(ts1);
I was expecting that the autocorrelation would show 1 for x=0 and almost 0 for the rest of values, instead I get value 6 at axis position 100.
I think the question applies both to Matlab and Octave but I am not sure.
First thing is that your second line of code is wrong. I think you meant to put
autocorrelation_ts1 = xcorr(ts1);
Other than this, I think your solution is correct. The reason the max value is at 100 and not 0 is because a temporal shift of 0 in the autocorrelation actually happens on the 100th iteration of the correlation function. In other words, the numbers on the X axis don't correspond to time.
To get time on the X axis change your code to
[autocorrelation_ts1, shifts] = xcorr(ts1);
Then
plot(shifts, autocorrelation_ts1)
With regard to the max value, matlab documentation for xcorr indicates that 1 is not the maximum output value of the function when called without the normalization argument. If you want to normalize such that all values are 1 or less, use
[autocorrelation_ts1, shifts] = xcorr(ts1, 'normalized');
Just as complementary reference to Scott's answer, this is the complete code snippet, including stem chart scaling to show up to 20 shifts/lags.
[auto_ts1, lags] = xcorr(ts1);
ts_begin = ceil(size(lags,2)/2);
ts_end = ts_begin + 20;
stem(lags(ts_begin:ts_end),auto_ts1(ts_begin:ts_end)/max(auto_ts1), 'linewidth', 4.0, 'filled')

How do I plot values in an array vs the number of times those values appear in Matlab?

I have a set of ages (over 10000 of them) and I want to plot a graph with the age from 20 to 100 on the x axis and then the number of times each of those ages appears in the data on the y axis. I have tried several ways to do this and I can't figure it out. I also have some other data which requires me to plot values vs how many times they occur so any advice on how to do this would be much appreciated.
I'm quite new to Matlab so it would be great if you could explain how things in your answer work rather than just typing out some code.
Thanks.
EDIT:
So I typed histogram(Age, 80) because as I understand that will plot the values in Age on a histogram split up into 80 bars (1 for each age). Instead I get this:
The bars aren't aligned and it's clearly not 1 per age nor has it plotted the number of times each age occurs on the y axis.
You have to use histogram(), and that's correct.
Let's see with an example.
I extract 100 ages between 20 and 100:
ages=randsample([20:100],100,true);
Now I call histogram() in this manner:
h=histogram(ages,[20:100]);
where h is an histogram object and this will also show the following plot:
However, this might look easy due to the fact that my ages vector is in range 20:100, so it will not contain any other values. If your vector, as instead, contains also ages not in range 20:100, you can specify the additional option 'BinLimits' as third input in histogram() like this:
h=histogram(ages,length([20:100]),'BinLimits',[20:100]);
and this option plots a histogram using the values in ages that fall between 20 and 100 inclusive.
Note: by inspecting h you can actually see and/or edit some proprieties of your histogram. An attribute (field) of such object you might be interested to is Values. This is a vector of length 80 (in our case, since we work with 80 bins) in which the i-th element is the number of items is the i-th bin. This will help you count the occurrences (just in case you need them to go on with your analysis).
Like Luis said in comments, hist is the way to go. You should specify bin edges, rather than the number of bins:
ages = randi([20 100], [1 10000]);
hist(ages, [20:100])
Is this what you were looking for?

Matlab - Histogram edges and cut off

I'm trying to more or less replicate the following p-values density histogram, with different data:
So I want to create a histogram with the bin ticks at the beginning/end of a bar. With 15 bars and the values ranging from 0 up to and including 1.
At the moment I'm using the histc command:
xint=1/15;
edges=(0:xint:1);
[n,bin]=histc(data,edges);
bar(edges,n,'histc');
tit='p-values histogram';
htitle=title(tit);
set(htitle,'fontname','Calibri')
xlabel('p-values');
ylabel('Frequency');
Which gives me:
However, if the data is equal to 1, the current code plots a new bar after 1. I guess I need to include the edges (to get the same as the example), but I couldn't seem to find the right command?
Also how can I make the histogram cut off at x=1, like the example? Inserting the "lambda arrow" of the example at 0.6 is preferable (but optional).
Edits 3 and 4: Since you're using Matlab R2013b, which doesn't have histogram, use the number-of-bins syntax of hist to plot:
[n, centers] = hist(data, 15)
Note that this returns centers, not edges of the bins. For the arrow, you can use annotation if R2013b supports it. Alternatively (a bit hackish):
line([0.6 0.6], [1750 1250])
plot(0.6, 1250, 'Marker, 'v')
text(0.6, 1750, '\lambda', 'HorizontalAlignment','center', 'VerticalAlignment','bottom')
Edit 2: Try
xint=1/15;
edges_in=(0:xint:1);
histogram(data,edges_in);
to plot directly, rather than using bar. This post from MathWorks says that the histc option of bar() is deprecated.
Use histcounts instead of histc:
xint=1/15;
edges_in=(0:xint:1);
[n,edges_out]=histcounts(data,edges_in); % <-- changed
size(n)
size(edges_in)
size(edges_out)
bar(edges_out(1:end-1),n,'histc'); % <-- changed - last bin edge shouldn't be included
tit='p-values histogram';
htitle=title(tit);
set(htitle,'fontname','Calibri')
xlabel('p-values');
ylabel('Frequency');
axis([0 1 0 2500]); % <-- added - but leave it off for debugging
Per the histc docs, "The last bin consists of the scalar value equal to last value in binranges." So the last bin is just 1.0. By contrast, with histcounts, "The last bin also includes the right bin edge, so that it contains X(i) if edges(end-1) ≤ X(i) ≤ edges(end)." That should do what you want.
I included an axis above to tighten up the plot, but leave that off for debugging so you can see if the last bar is still there.
Edit Per the histcounts docs, the returned vector has one fewer element than the edge vector. If that's the case (per the size printouts in the edited code), it should be removed so bar doesn't plot that bar.

MATLAB - histograms of equal size and histogram overlap

An issue I've come across multiple times is wanting to take two similar data sets and create histograms from them where the bins are identical, so as to easily calculate things like histogram overlap.
You can define the number of bins (obviously) using
[counts, bins] = hist(data,number_of_bins)
But there's not an obvious way (as far as I can see) to make the bin size equal for several different data sets. If remember when I initially looked finding various people who seem to have the same issue, but no good solutions.
The right, easy way
As pointed out by horchler, this can easily be achieved using either histc (which lets you define your bins vector), or vectorizing your histogram input into hist.
The wrong, stupid way
I'm leaving below as a reminder to others that even stupid questions can yield worthwhile answers
I've been using the following approach for a while, so figured it might be useful for others (or, someone can very quickly point out the correct way to do this!).
The general approach relies on the fact that MATLAB's hist function defines an equally spaced number of bins between the largest and smallest value in your sample. So, if you append a start (smallest) and end (largest) value to your various samples which is the min and max for all samples of interest, this forces the histogram range to be equal for all your data sets. You can then truncate the first and last values to recreate your original data.
For example, create the following data set
A = randn(1,2000)+7
B = randn(1,2000)+9
[counts_A, bins_A] = hist(A, 500);
[counts_B, bins_B] = hist(B, 500);
Here for my specific data sets I get the following results
bins_A(1) % 3.8127 (this is also min(A) )
bins_A(500) % 10.3081 (this is also max(A) )
bins_B(1) % 5.6310 (this is also min(B) )
bins_B(500) % 13.0254 (this is also max(B) )
To create equal bins you can simply first define a min and max value which is slightly smaller than both ranges;
topval = max([max(A) max(B)])+0.05;
bottomval = min([min(A) min(B)])-0.05;
The addition/subtraction of 0.05 is based on knowledge of the range of values - you don't want your extra bin to be too far or too close to the actual range. That being said, for this example by using the joint min/max values this code will work irrespective of the A and B values generated.
Now we re-create histogram counts and bins using (note the extra 2 bins are for our new largest and smallest value)
[counts_Ae, bins_Ae] = hist([bottomval, A, topval], 502);
[counts_Be, bins_Be] = hist([bottomval, B, topval], 502);
Finally, you truncate the first and last bin and value entries to recreate your original sample exactly
bins_A = bins_Ae(2:501)
bins_B = bins_Ae(2:501)
counts_A = counts_Ae(2:501)
counts_B = counts_Be(2:501)
Now
bins_A(1) % 3.7655
bins_A(500) % 13.0735
bins_B(1) % 3.7655
bins_B(500) % 13.0735
From this you can easily plot both histograms again
bar([bins_A;bins_B]', [counts_A;counts_B]')
And also plot the histogram overlap with ease
bar(bins_A,(counts_A+counts_B)-(abs(counts_A-counts_B)))

Creating image profiles in some parts of the image

I've been struggling with a problem for a while:) in Matlab.
I have an image (A.tif) in which I would like to find maxima (with defined threshold) but more specific coordinates of these maxima. My goal is to create short profiles on the image crossing these maxima (let say +- 20 pixels on both sides of the maximum)
I tried this:
[r c]=find(A==max(max(A)));
I suppose that r and c are coordinates of maximum (only one/first or every maximum?)
How can I implement these coordinates into ,for example improfile function?
I think it should be done using nested loops?
Thanks for every suggestion
Your code is working but it finds only global maximum coordinates.I would like to find multiple maxima (with defined threshold) and properly address its coordinates to create multiple profiles crossing every maximum found. I have little problem with improfile function :
improfile(IMAGE,[starting point],[ending point]) .
Lets say that I get [rows, columns] matrix with coordinates of each maximum and I'm trying to create one direction profile which starts in the same row where maximum is (about 20 pixels before max) and of course ends in the same row (also about 20 pixels from max) .
is this correct expression :improfile(IMAGE,[rows columns-20],[rows columns+20]); It plots something but it seems to only joins maxima rather than making intensity profiles
You're not giving enough information so I had to guess a few things. You should apply the max() to the vectorized image and store the index:
[~,idx] = max(I(:))
Then transform this into x and y coordinates:
[ix,iy] = ind2sub(size(I),idx)
This is your x and y of the maximum of the image. It really depends what profile section you want. Something like this is working:
I = imread('peppers.png');
Ir = I(:,:,1);
[~,idx]=max(Ir(:))
[ix,iy]=ind2sub(size(Ir),idx)
improfile(Ir,[0 ix],[iy iy])
EDIT:
If you want to instead find the k largest values and not just the maximum you can do an easy sort:
[~,idx] = sort(I(:),'descend');
idxk = idx(1:k);
[ix,iy] = ind2sub(size(I),idxk)
Please delete your "reply" and instead edit your original post where you define your problem better