World population and a logistic fit (live) live dataOpen ↗
Code
% World population from the World Bank (live), fitted with a logistic curve
d = webread('https://api.worldbank.org/v2/country/WLD/indicator/SP.POP.TOTL?format=json&per_page=100');
rows = d{2}; yr = []; pop = [];
for k = 1:numel(rows)
if ~isempty(rows{k}.value), yr(end+1) = str2double(rows{k}.date); pop(end+1) = rows{k}.value / 1e9; end
end
[yr, idx] = sort(yr); pop = pop(idx);
% logistic model P(t) = K / (1 + exp(-r (t - t0))), fitted by least squares
model = @(p, t) p(1) ./ (1 + exp(-p(2)*(t - p(3))));
err = @(p) sum((model(p, yr) - pop).^2);
p = fminsearch(err, [11, 0.03, 1990]);
tt = 1960:2100;
plot(yr, pop, 'o', 'MarkerSize', 4), hold on
plot(tt, model(p, tt), 'LineWidth', 2), hold off
xlabel('year'), ylabel('billions')
legend('World Bank data', sprintf('logistic fit, ceiling %.1f bn', p(1)))
title(sprintf('World population: %.2f bn in %d', pop(end), yr(end)))
subtitle('A simple curve fit, not a projection: the UN uses age-structured models')