Unexpected rounding of numbers by matlab??? Why it is happening?

141 vues (au cours des 30 derniers jours)
Sergii Snegir
Sergii Snegir le 18 Juin 2021
Commenté : ytzhak goussha le 30 Juin 2021
Dear Community,
can anyone explain me why Matlab rounding my data during assigning of the value(s) to a variable(s)????
Description:
My code started rounding values by himself during the data analysis, nevertheless that it was working nicely for months before. During execution the code I am extracting the data y_lim and ybin:
h=binscatter(x,y,250,'FaceAlpha',1);
h.ShowEmptyBins = 'off';
ax = gca;
ax.YScale="log";
ax.XLim=([-2 20]);
y_lim=h.YLimits
ybin=h.YBinEdges
the results presented in the WORKSPACE are obviously wrong: y_lim = [0, 1.005]
if in COMMAND Window i look on h handler properties, i see the correct data:
YLimits: [1.002305238077898e-06 1.002305238077898e+00]
ok... then I tried to access to my handler h in the command window and i got a correct result:
>> h.YLimits
ans = 1.002305238077898e-06 1.002305238077898e+00
Next step made me crazy. I assign the variable y lim using the same command like i used in the code and got CORRECT value:
>> y_lim=h.YLimits
y_lim =
1.002305238077898e-06 1.002305238077898e+00
CAN anyone help me with this issue??? Is this a matlab bug or i don't understand something.
  13 commentaires
Sergii Snegir
Sergii Snegir le 18 Juin 2021
Sorry, but I can not attach 450mb of my initial data file. I was trying to save only X,y data sets before plotting them, but observed, that saved mat files contain already rounded values.... Any ideas how to deal with the file saving???
dpb
dpb le 18 Juin 2021
Modifié(e) : dpb le 18 Juin 2021
You can certainly save a small(ish) example dataset and attach the code here...it doesn't take 450MB of data to illustrate a problem.
Others have already told you what to do -- save data variables in .mat files, not as figures for ease of use and speed.
Even though it's inefficient to do so, a .fig file does still contain all the data in the X|YData variables as is also easily demonstrated -- it so happens have another dataset downloaded from a previous Q? that has variables that illustrate the similar issue of disparate magnitudes -- so will use it for illustration--
>> format long, format compact
>> [[min(data(:,1)) max(data(:,1))];[min(data(:,2)) max(data(:,2))]]
ans =
1.0e+12 *
1.587081600000000 1.587168000000000
0.000000000000762 0.000000000836381
>> format short, format compact
>> [[min(data(:,1)) max(data(:,1))];[min(data(:,2)) max(data(:,2))]]
ans =
1.0e+12 *
1.5871 1.5872
0.0000 0.0000
>> [min(data(:,2)) max(data(:,2))]
ans =
0.7615 836.3806
>> format long, format compact
>> [min(data(:,2)) max(data(:,2))]
ans =
1.0e+02 *
0.007615482200000 8.363806400000000
>>
which shows the apparent "rounding" in the displayed values at various levels depending on the display format chosen and which variables are tried to be displayed together such that MATLAB has to scale to get them shown together.
Now we'll plot one and look at figure...
>> isOK=isfinite(data(:,2)); % there happen to be a bunch of NaN; we'll skip them
>> hL=plot(data(isOK,1),data(isOK,2)); % plot
>> all(hL.YData.'==data(isOK,2)) % compare to the input data the fig copies
ans =
logical
1
>> all(hL.XData.'==data(isOK,1))
ans =
logical
1
>>
shows that all the values in the figure data properties are the same as the in-memory data to full precision; no rounding has taken place.
Now
>> savefig('Data.fig') % write out a .fig file
>> close all % close that figure completely
>> hF=openfig('Data.fig'); % load the saved figure
>> clear hL % get rid of old line handle completely, too
>> hAx=gca;hL=hAx.Children; % retrieve the line handle from loaded fig
>> all(hL.XData.'==data(isOK,1)) % and compare again to the original data array
ans =
logical
1
>> all(hL.YData.'==data(isOK,2))
ans =
logical
1
>>
MATLAB has NOT done any rounding at all...while it's an inefficient storage mechanism, nothing is lost and if one were to need to regenerate the figures anyway, then it might save some time if they had been extensively customized before saving.
>> !dir data.fig
Volume in drive C is OS
Volume Serial Number is 3260-4552
Directory of C:\Users\Duane\Documents\MATLAB\Work
06/18/2021 10:30 AM 35,193 Data.fig
1 File(s) 35,193 bytes
0 Dir(s) 803,652,620,288 bytes free
>> XY=data(isOK,1:2);
>> whos XY
Name Size Bytes Class Attributes
XY 342x2 5472 double
>> save dataXY XY
>> !dir dataXY.mat
Volume in drive C is OS
Volume Serial Number is 3260-4552
Directory of C:\Users\Duane\Documents\MATLAB\Work
06/18/2021 10:40 AM 3,643 dataXY.mat
1 File(s) 3,643 bytes
0 Dir(s) 803,652,603,904 bytes free
>>
shows about a 10X overhead in the .fig file as compared to just saving the data itself in a .mat file
The moral is -- you've done something different than you think you have done -- we can't diagnose what that might be without the full details but you'll need to attach stuff here to illustrate just what you have done to expect somebody to fully diagnose the root cause.

Connectez-vous pour commenter.

Réponses (2)

Sergii Snegir
Sergii Snegir le 21 Juin 2021
Dear dpb and all users,
enclosed are two files. MLX file is the original code that I am using for processing the data (up to the line 83). After the line 83 I plot the x, y data using the histogram function. This x, y, data you may find in another mat file (enclosed).
I need to save into mat file: x_lim=h.XLimits; y_lim=h.YLimits, counts=h.Values; xbin=h.XBinEdges; ybin=h.YBinEdges
After saving them, I have "rounded" data . Instead of YLimits: [1.0023e-06 1.0023] (i see in handler h), I have all the time exported
>> h.YLimits
ans =
0.0000 1.0023
  3 commentaires
Sergii Snegir
Sergii Snegir le 22 Juin 2021
this is the result obtained in the command window:
I have also immediately tried to place "format long" into my code... it does not improve/change the data unfortunately
h=binscatter(x,y,250,'FaceAlpha',1);
h.ShowEmptyBins = 'off';
ax = gca;
ax.YScale="log";
ax.XLim=([-2 20]);
% ax.YLim=(cond_lim);
% format short e
% format compact
x_lim=h.XLimits;
% format short e
% format compact
format longg
y_lim=h.YLimits
counts=h.Values;
xbin=h.XBinEdges;
ybin=h.YBinEdges
xy=[xbin',ybin'];
exportPath2_cont=sprintf('figures\\contours\\%s_from_2D-histo_X_Y',timestamps(1,1));
save(sprintf('%s_counts.mat',exportPath2_cont), 'xbin','ybin','x_lim','y_lim');
writematrix(xy, sprintf('%s_counts.csv',exportPath2_cont));
John D'Errico
John D'Errico le 22 Juin 2021
Please don't use an answer just to make a comment or response to other comments.

Connectez-vous pour commenter.


Walter Roberson
Walter Roberson le 22 Juin 2021
Go into Preferences -> MATLAB -> Variables -> Format
and set "long g"
Go into Preferences -> MATLAB -> Command WIndow -> Text Display -> Numeric format:
and set "long g"
Then OK to save the changes of preferences.
Now quit and re-enter MATLAB.
Once you have done this, then the Variable Browser that you are relying on will default to showing your data in "long g" format, and the command window will default to displaying in "long g" format as well. MATLAB will reset to these two "long g" preferences each time you start MATLAB.
You are being fooled by the fact that the Variable Browser is not affected by the "format" command.
  17 commentaires
dpb
dpb le 25 Juin 2021
@Sergii Snegir -- Also Nota Bene that the "g" format whether short or long will always pick the format that is "most compact" between a fixed-decimal or scientific notation format on its own volition so you can't control precisely how the data are going to be displayed; it's dependent upon the actual value.
If you want to see the full precision of the data visually as it is stored internally, then use the
format longE
form.
But again, it can't be emphasized too much that you appear to still be completely ignoring/oblivious to the difference between what is displayed on the screen and what the value of a variable in memory is -- and that one is simply a representation of the other in a particular format -- and that changing that format has no bearing at all on the actual value in memory that MATLAB uses.
ytzhak goussha
ytzhak goussha le 30 Juin 2021
if the problem is with display, try multimpling the number the appears as zero by a big number 1e10, if it is zero the result will be zero, and if it is a small number like 1e-6 it will display a non-zero result

Connectez-vous pour commenter.

Catégories

En savoir plus sur Graphics Object Properties dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by