How to fit an uniform distribution to a histogram?
I have a set of data that is generated from an uniform distribution. Now I want to fit the corresponding histogram to an uniform distribution, such that there is a 'ㄇ' shape of line plotted on that histogram. I tried to fit it by using the MATLAB built-in function histfit
, but there is no such an option of uniform distribution for histfit. How can I do it?
data = unifrnd(-100,100,1000,1);
%% MATLAB built-in function: 'histfit'
figure(1);
hh = histfit(data); % No options for 'histfit' to fit data to an uniform distribution
%% Manually fitting a histogram to an uniform distribution
figure(2);
numBars = length(hh(1).XData);
histogram(data, numBars);
% TODO: How to do next to plot a line that fits the data to an uniform distribution?
Since a uniform distribution is just 1/(b-a) for a region [a, b), you can define a function that calculates this
x = -200:200;
y = unifdist(x, -100, 100);
figure;
plot(x, y)
function ret = unifdist(x, a, b)
ret = ones(length(x), 1)/(b-a);
ret(x < a | x >= b) = 0;
end
There's probably a much simpler and faster way to do this, but it works.
min(data)
and max(data)
give an estimate of the two parameters of the uniform distribution, assuming data
is uniformly distributed.
Note that this is a biased estimator, see here for a correction to remove the bias (one of the answers considers the case where the lower bound is not 0). [Link thanks to @flawr.]
As an alternative to @CrisLuengo's answer, you could use the Method of Moments to estimate the parameters a,b
of the uniform distribution U[a,b]
. Following equations are sufficient to solve for the parameters. The MoM just tells us to equate the (sample-) mean and variance to the distribution mean and variance:
mean(samples) = (a+b)/2, variance(samples) = (b-a)^2/12
This results in a, b = mean(samples) +- sqrt(3 * variance(samples))
. In MATLAB you can compute this as follows:
m = mean(data);
v = var(data);
a = m - sqrt(3*v);
b = m + sqrt(3*v);
To plot this you can just define vector
x = linspace(-lower_limit, upper_limit, number_of_points);
y = (a < x) .* (x < b) ./ (b - a);
plot(x, y, '-r');