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

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

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.

댓글을 달려면 로그인하십시오.

 채택된 답변

Adam Danz
Adam Danz 2019년 5월 19일
편집: Adam Danz 2019년 5월 20일
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

Dear Adam
Thanks a lot for providing me a feedback. Your approach seems very promising and interesting but why am I receiving this graph (see attached image .png) and it doesn't look like the one you have posted with the intervals visible
Whereas when I put a small interval value such as 2 for instance, I get the error
Error using regexp
The 'STRING' input must be either a char row vector, a cell array of char row vectors, or a string array.
Error in strsplit (line 125)
[c, matches] = regexp(str, aDelim, 'split', 'match');
Error in sheet7 (line 116)
text(edges+binWidth/2, ones(size(edges)), strsplit(num2str(round(binMean*10)/10,.1)), ...
Hi Stelios, please take a few minutes to understand what I've done in my code, it's only 4-5 lines and then another 2-3 lines to understand the plot.
I generated fake data. Then I defined edges for each bin based on the range of x values. Using histcounts(), I determined which points were in which bins. Then using splitapply() I took the mean of y for each bin.
My plot just shows my fake data, the vertical lines show the bin edges, and the numbers on top show the means.
This approach should be generalizable to any set of (x,y) coordinates.
I don't know where your plot comes from or what it representes. Is that the (x,y) data you're binning? Have you tried to apply my code to your data?
I can help you more if you show me the relevant sections of your code where you applied my analysis.
Actually, the only things I changed was to apply x as my x axis data and y as my y data which is a polynomial function.
The rest of your code remained the same. My x axis data begins from 0 up until 37. That's why when I put a big number e.g. 100 it won't show anything, but when I put a small number e.g. 2 it will show me the vertical lines, like your plot but I also get the error
Error using regexp
The 'STRING' input must be either a char row vector, a cell array of char row vectors, or a string array.
Error in strsplit (line 125)
[c, matches] = regexp(str, aDelim, 'split', 'match');
Error in sheet7 (line 116)
text(edges+binWidth/2, ones(size(edges)), strsplit(num2str(round(binMean*10)/10,.1)), ...
I see your updated comment now. Your error is coming from this line
[c, matches] = regexp(str, aDelim, 'split', 'match');
I don't have that line in my code.
What is the value of str ?
If I don't reply tonight (8pm my time) I can tomorrow AM.
Actually no. The basis of the error comes from this line
text(edges+binWidth/2, ones(size(edges)), strsplit(num2str(round(binMean*10)/10,.1)), ...
Last line of your code, because of the strsplit function. I guess my input should be a char row vector, cell array or string array.
Is it referring to my X, Y data? My x data are numbers and my y data is a polynomial function. Do I need to convert both to string array?
Actually, as I understand, binMean comes as double and I need to convert it to either char vector, cell array or string array. Num2str after the strsplit doesn't seem to work.
ANy idea ?
Ah, I see the source of the error in your message now.
It would be easier if I had the input values you were using in that line of code for the text() function.
That line can actually be simplifed, I just realized.
text(edges+binWidth/2, ones(size(edges)), strsplit(num2str(binMean,.1)), ...
'VerticalAlignment', 'Bottom', 'HorizontalAlignment', 'Center')
"binMean" is a row vector with 'n' elements where n is one less than the number of edges (remember, there will always be +1 edges than bins). num2str() converts that vector to one long sting like this:
binMean =
0.47372 0.49419 0.52058 0.49538 0.49438 0.50074 0.50679 0.53782 0.4761 0.50468
num2str(binMean,.1)
ans =
'0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5'
Note that it's one long string.
strsplit then separates that string into single numbers.
strsplit(num2str(binMean,.1))
ans =
1×10 cell array
{'0.5'} {'0.5'} {'0.5'} {'0.5'} {'0.5'} {'0.5'} {'0.5'} {'0.5'} {'0.5'} {'0.5'}
If that doesn't help, please share the inputs you are using.
@Adam
Unfortunately, same error
Error using regexp
The 'STRING' input must be either a char row vector, a cell array of char row vectors, or a string array.
Error in strsplit (line 125)
[c, matches] = regexp(str, aDelim, 'split', 'match');
Error in sheet7 (line 120)
text(edges+binWidth/2, ones(size(edges)), strsplit(num2str(binMean,.1)), ...
I attach my inputs
Adam Danz
Adam Danz 2019년 5월 20일
편집: Adam Danz 2019년 5월 20일
I don't know what this is (see screenshot below).
Rather than making me read in data from a file, could you just copy-paste a small sample of values for
  • edges
  • binWidth
  • binMean
I append samples of what you asked me
binMean
-0.121451211827104
-0.177183817955014
-0.00685535745892493
0.151211113432096
0.204176787674413
0.152122136758402
0.0418768402726248
-0.0669371848658577
edges
0.0430000000000000 2.04300000000000 4.04300000000000 6.04300000000000 8.04300000000000 10.0430000000000 12.0430000000000 14.
binWidth = 2
I hope that helps
I found the error. If you look at my comment above, I showed examples of what binMean should be. In my example, binMean is a row vector. In your data it's a column vector so it wasn't properly converted to strings. You just need to transpose the vector.
text(edges+binWidth/2, ones(size(edges)), strsplit(num2str(binMean.',.1)), ...
% ^^ transpose there
'VerticalAlignment', 'Bottom', 'HorizontalAlignment', 'Center')
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.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by