glitch in the MATrix: unable to get logical consistency between matrices with same values
1 view (last 30 days)
Show older comments
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.
0 Comments
Accepted Answer
Walter Roberson
on 10 Jun 2023
Edited: Walter Roberson
on 10 Jun 2023
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
pi - 3.141
format long
pi
pi - 3.141592653589793
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
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)
4 Comments
Benjamin Kraus
on 12 Jun 2023
Edited: Benjamin Kraus
on 12 Jun 2023
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.
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
on 12 Jun 2023
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])
More Answers (0)
See Also
Categories
Find more on Annotations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!