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

3 次查看(过去 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 中查找有关 Data Distribution Plots 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by