MATLAB Answers

0

How can I estimate the average for each one of the intervals in an x axis?

Asked by Stelios Fanourakis on 13 May 2019
Latest activity Commented on by Stelios Fanourakis on 20 May 2019 at 20:57
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

  2 Comments

The question is not clear yet: It does not make sense to "split the x axis". But if you have two vectors, one containing the x and the other the y values of a curve, you can calculate a blockwise average. So please post, what your inputs are.
Exactly as you stated. Two vectors of X,Y in a 2d plot. I want to define intervals for the X values and average each interval and all together.

Sign in to comment.

1 Answer

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

  13 Comments

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
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')
Thanks once again for your additional help. Althought, I might keep labels horizontally as they appear 'cause it looks better to me, than rotating them 90 degrees and have a vertical appearance.

Sign in to comment.