How can I use histfit function?
8 views (last 30 days)
Show older comments
Hello all.
I have an array called "AVG_Diameter" including the measured diameters of the porous structure of soil. I also have another array called "Rounded_N" in which the existing numbers correspondig to the diameters in the fromer array are stored. In other words, the latter array would be a frequency array for the diameters stored in the "AVG_Diameter". I tried to use histfit function in order to fit a histogram on the data formed by these two arrays, but I got an an error massage expressing "Requested array exceeds the maximum possible variable size." Would you please guide me where I am doing wrong and how I can fix it? Here is my code.
clc
clear
close all
load("AVG_Diameter.mat");
load("Rounded_N.mat")
AVG_Diameter=flip(AVG_Diameter)';
Rounded_N=flip(Rounded_N)';
% Create a data array with repeated values based on frequencies
data = repelem(AVG_Diameter, Rounded_N);
% Use histfit to fit a distribution
histfit(data, max(AVG_Diameter), 'lognormal');
title('Histogram with Fitted Distribution');
xlabel('Diameter of Pores');
ylabel('Frequency');
% Add a legend
legend('Histogram', 'Fitted Distribution');
0 Comments
Answers (1)
Star Strider
on 13 Nov 2023
Your data are frequency data (probably the result of performing a histogram on an original data set), not actual histogram data. Rather than attempting to re-create the histogram, likely the best option is to fit the data as they exist. (I don’t understand the reason for flipping the vectors.)
The distribution that you choose must have positive support, since the diameters are by definition all greater than zero. I chose lognpdf here, however there is likely a better choice, since it does not appear to fit the data. Choose the distribution that best describes your data.
load("AVG_Diameter.mat")
load("Rounded_N.mat")
format shortE
Data = [AVG_Diameter Rounded_N]
figure
semilogx(Rounded_N, AVG_Diameter)
grid
xlabel('Rounded_N')
ylabel('AVG_Diameter')
lognpdf_fcn = @(b,x) lognpdf(x,b(1),b(2));
[b,fv] = fminsearch(@(b) norm(AVG_Diameter - lognpdf_fcn(b,Rounded_N)), rand(2,1)*100)
mdl = fitnlm(Rounded_N, AVG_Diameter, lognpdf_fcn, b)
R_N_v = linspace(1E-4, max(Rounded_N), 150).';
[y,yci] = predict(mdl, R_N_v);
[y1,y2] = bounds(y)
figure
hp{1} = semilogx(Rounded_N, AVG_Diameter, 'sb', 'DisplayName','Data');
hold on
hp{2} = plot(R_N_v, y, '-r', 'DisplayName','Regression');
hp{3} = plot(R_N_v, yci, '--r', 'DisplayName','95% Confidence Limits');
hold off
grid
legend([hp{1} hp{2} hp{3}(1)], 'Location','best')
xlabel('Rounded_N')
ylabel('AVG_Diameter')
.
2 Comments
Star Strider
on 13 Nov 2023
I obviously read it incorrectly.
Reversing them from my previous code —
load("AVG_Diameter.mat")
load("Rounded_N.mat")
format shortE
Data = [AVG_Diameter Rounded_N]
figure
semilogx(AVG_Diameter, Rounded_N, '.-')
grid
xlabel('Rounded\_N')
ylabel('AVG\_Diameter')
lognpdf_fcn = @(b,x) lognpdf(x,b(1),b(2));
[b,fv] = fminsearch(@(b) norm(Rounded_N - lognpdf_fcn(b,AVG_Diameter)), rand(2,1)*1E+3)
mdl = fitnlm(AVG_Diameter, Rounded_N, lognpdf_fcn, b)
A_D_v = linspace(min(AVG_Diameter), max(AVG_Diameter), 150).';
[y,yci] = predict(mdl, A_D_v);
[y1,y2] = bounds(y)
figure
hp{1} = semilogx(AVG_Diameter, Rounded_N, 'sb', 'DisplayName','Data');
hold on
hp{2} = plot(A_D_v, y, '-r', 'DisplayName','Regression');
hp{3} = plot(A_D_v, yci, '--r', 'DisplayName','95% Confidence Limits');
hold off
grid
legend([hp{1} hp{2} hp{3}(1)], 'Location','best')
xlabel('AVG\_Diameter')
ylabel('Rounded\_N')
I still cannot get it to fit, however this should provide a starting point for your explorations. Again, choose a distribution with positive support, depending on whatever process underlies your data. (I thought a lognormal distribution would work, however it does not appear to be the correct choice.)
If you wnat to use histfit, give the function the original data — not previously-binned data — and see what it comes up with.
.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!