Asked by Stelios Fanourakis
on 13 May 2019

Hi

I need a method to split my x axis into intervals and estimate the average for each one of the intervals. The plots are polynomial curves, if that helps.

Any suggestion?

Thank you

Answer by Adam Danz
on 19 May 2019

Edited by Adam Danz
on 20 May 2019 at 19:09

Accepted Answer

This is relatively straight forward with histcounts() and splitapply().

% Create fake data

x = randi(1000,1,1000); %doesn't have to be sorted

y = rand(size(x));

% Define the edges of your x data

% There's lots of ways to do this - this is just 1 example.

binWidth = 100; %how wide is each bin?

edges = min(x) : binWidth : max(x);

% determine which bin each x element is in

[~, ~, hbin] = histcounts(x,[edges,inf]);

% Get mean of y within each bin

% Here I ignore NaN values, too.

binMean = splitapply(@(x)mean(x,'omitna'),y,hbin);

To interpret the results, binMean(n) is the mean for all y values where x is greater or equal to edges(n) and less than edges(n+1).

To plot the data, the bins, and display the average values per bin above the axis:

figure

plot(x,y,'b.')

hold on

plot([edges;edges],[0,1],'k')

text(edges+binWidth/2, ones(size(edges)), strsplit(num2str(binMean,.1)), ...

'VerticalAlignment', 'Bottom', 'HorizontalAlignment', 'Center')

% * binMean must be a row vector

Stelios Fanourakis
on 20 May 2019 at 19:15

Yes indeed. You are magnificent Adam. Very good precision resolving the issue. Well done and thank you very much.

Although the plot comes a bit awkward. How should I margin it to appear properly?

Maybe I should play with axis margins, so I can make it look more like yours

Thanks once again

Adam Danz
on 20 May 2019 at 19:56

Glad I could help.

The 2nd input to text() indicates where along the y axis your labels should go. In my example I simply used y=1 for all labels because my data didn't span beyond 1. You could just do this

ylim([-0.5, 2])

text(edges+binWidth/2, ones(size(edges))*max(ylim()), ......

also, see the "rotation" text property. It might look better to rotate the labels by 90 deg.

Also, to draw the lines across your entire axis,

plot([edges;edges],[min(ylim()), max(ylim())],'k')

Stelios Fanourakis
on 20 May 2019 at 20:57

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 2 Comments

## Jan (view profile)

Direct link to this comment:https://www.mathworks.com/matlabcentral/answers/461685-how-can-i-estimate-the-average-for-each-one-of-the-intervals-in-an-x-axis#comment_706074

## Stelios Fanourakis (view profile)

Direct link to this comment:https://www.mathworks.com/matlabcentral/answers/461685-how-can-i-estimate-the-average-for-each-one-of-the-intervals-in-an-x-axis#comment_706717

Sign in to comment.