glitch in the MATrix: unable to get logical consistency between matrices with same values

조회 수: 1 (최근 30일)
Edit. To update perhaps a context, I am wondering if this issue of the displayed data working but not the values generated internally from the code is do to some rounding issue that is affecting the indexing.
__________________________________________
Hello!
It seems I've been running into interesting hurdles around genearating interleaved bar graphs. After following a helpful link to make interleaved bar graphs by Benjamen Krauss (https://www.mathworks.com/matlabcentral/answers/725247-how-do-i-combine-two-bar-graphs), I am able to generate the output only when I copy and past the screen print values. When I attempt to use the code-generated matrices, the first data for the bar failes to output--yet using th screen displayed values outputted by the code works.
I should mentioned that my code employs the nan padding approach that Benjamen suggested.
Investigating further, I determined that the matrices for the bincentered data (or X-values) from the matrix vs. the copy and pasted screen displayed version are not logically consistent. This makes no sense to me!
I have attached a small structure file with the data to go with the code below that you can load to run and already saved time by coding the hard screen output values as X and Y values that were copied in to compare to the matrix values internal to the code. When you run the copy-pasted values you get the output in the left figure; for the loaded values the code uses you get the figure on the right (except strangely for one ~ .175):
As you can see, the red bars are missing. Here's the code
%% %%%%%%%%%%%%%%%%%
s = load('distance_data.mat');
s.above;
s.below;
% make interleaved bar graphs
%maxLim = max(d);
% [hist_below, edges_below] = histcounts(d(bIdx), 'BinMethod', 'fd'); %, length(myBins))
% [hist_above, edges_above] = histcounts(-d(aIdx), 'BinMethod', 'fd'); %, length(myBins))
[hist_below, edges_below] = histcounts(s.below, 'BinMethod', 'fd'); %, length(myBins))
[hist_above, edges_above] = histcounts(s.above, 'BinMethod', 'fd'); %, length(myBins))
maxBins = max(length(hist_below), length(hist_above));
histCounts = nan(2,maxBins); % pad with nans to ensure dimensionality consistency among group data
histCounts(1,1:length(hist_below)) = hist_below;
histCounts(2,1:length(hist_above)) = hist_above;
maxEdges = max([length(edges_below), length(edges_above)]);
edges = nan(2,maxEdges);
edges(1,1:length(edges_below)) = edges_below;
edges(2,1:length(edges_above)) = edges_above;
de1 = diff(edges(1,:))/2; % difference btwn bin edges
de2 = diff(edges(2,:))/2; % difference btwn bin edges
wcl1 = edges(1,1:end-1) + de1; % edge-width center location
wcl2 = edges(2,1:end-1) + de2; % edge-width center location
binCenters = [wcl1; wcl2];
% % size/dimensionality checks!
% size(edges)
% size(histCounts) % 2 x 8
% size(binCenters) % 2 x 8
% edges
% histCounts'
% binCenters'
figure;
b = bar(binCenters',histCounts'); % makes no difference if renamed as
%% This works! From printing out histCounts and binCenters and copying-and-pasting to X and Y
X = [ 0.0250, 0.0750, 0.1250, 0.1750, 0.2250, 0.2750, 0.3250, 0.3750
0.0150, 0.0450, 0.0750, 0.1050, 0.1350, 0.1650, 0.1950, 0.2250];
Y = [ 21, 18, 20, 11, 2, 8, 4, 3;
18, 5, 1, 0, 2, 0, 0, 1];
figure
b=bar(X',Y',3);
%% logical inconsistency with saved values and copy-pasted values !
[X' binCenters'], (X' == binCenters') % X and binCenters not all logically 1 !!!!
The logical output comparing the two column data of the copy-pasted version with the corresponding two column data of the values generated from the code itself is:
ans =
8×2 logical array
1 1
0 1
1 1
0 1
1 1
1 0
0 1
1 0
For Y and the histCounts there is logical consistency, as there should be. But I cannot understand the logical inconsistency with the code-generated used values and the copy-and-pasted X values, the later which works in making both bar graphs. What am I not getting here?!
Again, I am suspecting this might be some strange round out error or indexing issue. But still cannot see what it is if this assumption is true--or how that would even matter for the graphical output.
Thanks for your kind patience in reading this and any assistance.

채택된 답변

Walter Roberson
Walter Roberson 2023년 6월 10일
편집: Walter Roberson 2023년 6월 10일
Your code does not explicitly set a format, so your calculated values are 15 to 16 digits but your displayed values are 4 digits.
For example,
format short
pi
ans = 3.1416
pi - 3.141
ans = 5.9265e-04
format long
pi
ans =
3.141592653589793
pi - 3.141592653589793
ans =
0
On the MATLAB command line, the display for pi is 3.14159265358979 whereas for Livescript it is 3.141592653589793 . That difference is significant
pi - 3.14159265358979
ans =
3.108624468950438e-15
At the command line, "format long g" is not quite enough digits to resolve every value uniquely, so you may want to
fprintf('%.16g\n', pi)
3.141592653589793
  댓글 수: 4
Benjamin Kraus
Benjamin Kraus 2023년 6월 12일
편집: Benjamin Kraus 2023년 6월 12일
Just to add to @Walter Roberson's answer, and provide a bit more detail about how bar works.
The bar command requires exact equality before it will treat two different values as a "group" of bars, and determines the width of each group of bars based on the minimum distance between adjacent unique x-values.
In essence, the reference bar width is determined by this algorithm:
min(diff(unique(x(:))))
In the case of the binCenters variable from your data above, that value is 1.3878e-17, so if you set the BarWidth to 1, then the width of each bar will be 1.3878e-17, which is essentially no width, so you get really thin bars that look basically like lines.
As for how to correct the issue, I would have recommended using round.
s = load('distance_data.mat');
s.above;
s.below;
[hist_below, edges_below] = histcounts(s.below, 'BinMethod', 'fd'); %, length(myBins))
[hist_above, edges_above] = histcounts(s.above, 'BinMethod', 'fd'); %, length(myBins))
maxBins = max(length(hist_below), length(hist_above));
histCounts = nan(2,maxBins); % pad with nans to ensure dimensionality consistency among group data
histCounts(1,1:length(hist_below)) = hist_below;
histCounts(2,1:length(hist_above)) = hist_above;
maxEdges = max([length(edges_below), length(edges_above)]);
edges = nan(2,maxEdges);
edges(1,1:length(edges_below)) = edges_below;
edges(2,1:length(edges_above)) = edges_above;
de1 = diff(edges(1,:))/2; % difference btwn bin edges
de2 = diff(edges(2,:))/2; % difference btwn bin edges
wcl1 = edges(1,1:end-1) + de1; % edge-width center location
wcl2 = edges(2,1:end-1) + de2; % edge-width center location
binCenters = round([wcl1; wcl2],5);
figure;
b = bar(binCenters',histCounts');
Benjamin Kraus
Benjamin Kraus 2023년 6월 12일
And, just to provide an example
x = [1 1; 2 2; 3 3];
y = x;
figure
bar(x,y)
x2 = x;
x2(2) = x2(2)+eps(2); % Intentionally make a difference of just eps
figure
bar(x2,y)
xlim([0.5 3.5])

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

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Annotations에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by