List of countries and dependencies showing population densities, populations, and areas
| Location | Density | Population | Land area (km2) |
|---|---|---|---|
| World | 55 | 8,231,613,070 | 148,940,000 |
| Macau (China) | 21,826 | 720,262 | 33 |
| Monaco | 19,428 | 38,857 | 2 |
| Singapore | 8,290 | 6,110,200 | 737 |
| Hong Kong (China) | 7,062 | 7,414,910 | 1,050 |
| Gibraltar (UK) | 5,800 | 39,329 | 6.8 |
| Vatican City | 2,205 | 882 | 0.44 |
| Bahrain | 2,034 | 1,607,049 | 790 |
| Maldives | 1,759 | 527,799 | 298 |
| Malta | 1,686 | 539,607 | 320 |
| Bangladesh | 1,333 | 173,562,364 | 130,170 |
| Sint Maarten (NL) | 1,275 | 43,351 | 34 |
| Bermuda (UK) | 1,197 | 64,637 | 54 |
| Palestine | 892 | 5,371,230 | 6,020 |
| Jersey (UK) | 891 | 103,387 | 116 |
| Guernsey (UK) | 867 | 67,642 | 78 |
| Barbados | 657 | 282,468 | 430 |
| Taiwan | 656 | 23,213,962 | 35,410 |
| Mauritius | 637 | 1,271,169 | 1,997 |
| Aruba (NL) | 600 | 108,066 | 180 |
| Nauru | 597 | 11,947 | 20 |
| Rwanda | 578 | 14,256,567 | 24,670 |
| Lebanon | 568 | 5,805,962 | 10,230 |
| Saint Barthélemy (France) | 563 | 11,258 | 20 |
| San Marino | 560 | 33,581 | 60 |
| Burundi | 547 | 14,047,786 | 25,680 |
| Netherlands | 541 | 18,080,943 | 33,670 |
| South Korea | 530 | 51,717,590 | 97,600 |
| Saint Martin (France) | 523 | 26,129 | 50 |
| Israel | 468 | 10,148,000 | 21,640 |
| Comoros | 466 | 866,628 | 1,861 |
| India | 441 | 1,450,935,791 | 3,287,263 |
| Haiti | 427 | 11,772,557 | 27,560 |
| Curaçao (NL) | 418 | 185,482 | 444 |
| Philippines | 389 | 115,843,670 | 298,170 |
| Belgium | 385 | 11,738,764 | 30,494 |
| Sri Lanka | 373 | 23,103,565 | 61,860 |
| Puerto Rico (US) | 366 | 3,242,204 | 8,870 |
| Grenada | 345 | 117,208 | 340 |
| Japan | 340 | 123,753,041 | 364,500 |
| Tuvalu | 322 | 9,646 | 30 |
| Guam (US) | 311 | 167,777 | 540 |
| Cayman Islands (UK) | 310 | 74,458 | 240 |
| Vietnam | 309 | 102,300,000 | 331,212 |
| El Salvador | 306 | 6,338,193 | 20,720 |
| Saint Lucia | 295 | 179,744 | 610 |
| Trinidad and Tobago | 294 | 1,507,782 | 5,130 |
| Pakistan | 289 | 255,300,000 | 882,363 |
| United Kingdom | 287 | 69,483,939 | 242,494 |
| Seychelles | 284 | 130,419 | 460 |
| Saint Vincent and the Grenadines | 281 | 109,296 | 389 |
| Kuwait | 277 | 4,934,508 | 17,820 |
| Gambia | 273 | 2,759,988 | 10,120 |
| Qatar | 265 | 3,048,423 | 11,490 |
| British Virgin Islands (UK) | 263 | 39,471 | 150 |
| Jamaica | 262 | 2,839,175 | 10,830 |
| Luxembourg | 261 | 673,036 | 2,575 |
| Nigeria | 255 | 232,679,478 | 910,770 |
| Tokelau (New Zealand) | 251 | 2,507 | 10 |
| Uganda | 249 | 50,015,093 | 200,520 |
| Liechtenstein | 249 | 39,870 | 160 |
| São Tomé and Príncipe | 245 | 235,537 | 960 |
| U.S. Virgin Islands (US) | 243 | 84,905 | 350 |
| Germany | 242 | 84,552,242 | 349,360 |
| Dominican Republic | 237 | 11,427,557 | 48,198 |
| American Samoa (US) | 234 | 46,765 | 200 |
| Malawi | 230 | 21,655,286 | 94,280 |
| Switzerland | 226 | 8,921,981 | 39,510 |
| North Korea | 220 | 26,498,823 | 120,410 |
| Antigua and Barbuda | 213 | 93,772 | 440 |
| Marshall Islands | 209 | 37,548 | 180 |
| Nepal | 207 | 29,651,055 | 143,350 |
| Italy | 201 | 59,342,867 | 295,720 |
| Saint Kitts and Nevis | 180 | 46,843 | 260 |
| Togo | 175 | 9,515,236 | 54,390 |
| Andorra | 174 | 81,938 | 470 |
| Guatemala | 172 | 18,406,359 | 107,160 |
| Kiribati | 170 | 138,000 | 810 |
| Bonaire (NL) | 169 | 26,552 | 288 |
| Saba (NL) | 166 | 2,158 | 13 |
| Anguilla (UK) | 162 | 14,599 | 90 |
| Federated States of Micronesia | 162 | 113,161 | 700 |
| Sint Eustatius (NL) | 156 | 3,270 | 21 |
| United Arab Emirates | 155 | 11,027,129 | 71,020 |
| Kosovo | 154 | 1,674,125 | 10,887 |
| Ghana | 151 | 34,427,414 | 227,533 |
| China | 151 | 1,419,321,278 | 9,388,210 |
| Indonesia | 150 | 283,487,931 | 1,892,555 |
| Denmark | 149 | 5,977,413 | 40,000 |
| Isle of Man (UK) | 148 | 84,161 | 570 |
| Cyprus | 147 | 1,358,282 | 9,240 |
| Northern Cyprus | 146 | 489,308 | 3,355 |
| Tonga | 145 | 104,176 | 720 |
| Thailand | 140 | 71,668,011 | 510,890 |
| Czech Republic | 139 | 10,735,860 | 77,171 |
| Syria | 133 | 24,672,760 | 185,178 |
| Cape Verde | 130 | 524,877 | 4,030 |
| Jordan | 130 | 11,552,876 | 88,794 |
| Benin | 128 | 14,462,724 | 112,760 |
| Poland | 126 | 37,600,280 | 306,090 |
| Azerbaijan | 125 | 10,336,578 | 82,650 |
| France | 122 | 66,548,531 | 547,557 |
| Sierra Leone | 120 | 8,642,023 | 72,180 |
| Egypt | 117 | 116,538,258 | 995,450 |
| Ethiopia | 117 | 132,059,768 | 1,128,571 |
| Slovakia | 115 | 5,506,760 | 48,080 |
| Portugal | 114 | 10,425,293 | 91,606 |
| Turkey | 114 | 87,473,805 | 769,630 |
| Austria | 111 | 9,120,813 | 82,520 |
| Malaysia | 108 | 35,557,674 | 328,550 |
| Iraq | 106 | 46,042,015 | 434,128 |
| Hungary | 106 | 9,676,135 | 91,260 |
| Slovenia | 105 | 2,118,697 | 20,136 |
| Armenia | 104 | 2,973,841 | 28,470 |
| Albania | 102 | 2,791,765 | 27,400 |
| Costa Rica | 100 | 5,129,910 | 51,060 |
| Ivory Coast | 100 | 31,934,230 | 318,000 |
| Cambodia | 100 | 17,638,801 | 176,520 |
| Kenya | 99 | 56,432,945 | 569,140 |
| Honduras | 97 | 10,825,704 | 111,890 |
| Northern Mariana Islands (US) | 96 | 44,278 | 460 |
| Senegal | 96 | 18,501,985 | 192,530 |
| Spain | 98 | 49,801,559 | 499,714 |
| Timor-Leste | 94 | 1,400,638 | 14,870 |
| Moldova | 92 | 3,034,961 | 32,890 |
| Cuba | 89 | 9,748,532 | 109,820 |
| Dominica | 88 | 66,205 | 750 |
| Transnistria | 88 | 367,000 | 4,163 |
| Brunei | 88 | 462,722 | 5,270 |
| Burkina Faso | 86 | 23,548,781 | 273,600 |
| Serbia | 85 | 6,567,783 | 88,499 |
| Myanmar | 84 | 54,500,091 | 652,670 |
| Romania | 83 | 19,015,088 | 230,080 |
| Uzbekistan | 83 | 36,361,859 | 440,652 |
| French Polynesia (France) | 81 | 281,807 | 3,471 |
| Wallis and Futuna (France) | 81 | 11,278 | 140 |
| Tunisia | 79 | 12,277,109 | 155,360 |
| Samoa | 78 | 218,020 | 2,780 |
| Guinea-Bissau | 78 | 2,201,352 | 28,120 |
| Greece | 78 | 10,047,817 | 128,900 |
| Tanzania | 77 | 68,560,157 | 885,800 |
| Lesotho | 77 | 2,337,423 | 30,360 |
| Yemen | 77 | 40,583,165 | 527,970 |
| Tajikistan | 76 | 10,590,928 | 138,790 |
| Ireland | 76 | 5,255,018 | 68,890 |
| Ecuador | 73 | 18,135,478 | 248,360 |
| North Macedonia | 72 | 1,823,009 | 25,220 |
| Eswatini | 72 | 1,242,822 | 17,200 |
| Akrotiri and Dhekelia (UK) | 72 | 18,195 | 254 |
| Croatia | 69 | 3,875,325 | 55,960 |
| Equatorial Guinea | 67 | 1,892,517 | 28,050 |
| Mexico | 67 | 130,861,007 | 1,943,950 |
| Afghanistan | 65 | 42,647,492 | 652,230 |
| Ukraine | 65 | 37,860,222 | 579,400 |
| Bulgaria | 62 | 6,757,689 | 108,560 |
| Bosnia and Herzegovina | 62 | 3,164,253 | 51,200 |
| Cameroon | 62 | 29,123,744 | 472,710 |
| Panama | 61 | 4,515,577 | 74,180 |
| Norfolk Island (Australia) | 61 | 2,188 | 36 |
| Guinea | 60 | 14,754,786 | 245,720 |
| Liberia | 58 | 5,612,817 | 96,320 |
| Nicaragua | 57 | 6,916,140 | 120,340 |
| Cook Islands (New Zealand) | 57 | 13,729 | 240 |
| Iran | 56 | 91,567,738 | 1,648,195 |
| Madagascar | 55 | 31,964,956 | 581,800 |
| Georgia | 55 | 3,807,670 | 69,490 |
| South Africa | 53 | 64,007,187 | 1,213,090 |
| Morocco | 53 | 38,081,173 | 710,850 |
| Fiji | 51 | 928,784 | 18,270 |
| Djibouti | 50 | 1,168,722 | 23,180 |
| Turks and Caicos Islands (UK) | 49 | 46,535 | 950 |
| DR Congo | 48 | 109,276,265 | 2,267,050 |
| Colombia | 48 | 52,886,364 | 1,109,500 |
| Montenegro | 47 | 638,479 | 13,450 |
| Lithuania | 46 | 2,859,110 | 62,604 |
| Belarus | 45 | 9,056,696 | 202,990 |
| Mozambique | 44 | 34,631,766 | 786,380 |
| Montserrat (UK) | 44 | 4,389 | 100 |
| Cocos (Keeling) Islands (Australia) | 43 | 602 | 14 |
| Zimbabwe | 43 | 16,634,373 | 386,850 |
| Faroe Islands (Denmark) | 40 | 55,400 | 1,370 |
| Bahamas | 40 | 401,283 | 10,010 |
| Palau | 38 | 17,696 | 460 |
| United States | 37 | 341,730,701 | 9,147,590 |
| Kyrgyzstan | 37 | 7,186,009 | 191,800 |
| Somaliland | 35 | 4,914,100 | 167,283 |
| Laos | 34 | 7,769,819 | 230,800 |
| Venezuela | 32 | 28,405,543 | 882,050 |
| Estonia | 32 | 1,360,546 | 42,730 |
| Angola | 30 | 37,885,850 | 1,246,700 |
| Somalia | 30 | 19,009,151 | 627,340 |
| Latvia | 30 | 1,871,872 | 62,230 |
| Solomon Islands | 29 | 819,198 | 27,990 |
| Eritrea | 29 | 3,535,603 | 121,041 |
| Zambia | 29 | 21,314,956 | 743,390 |
| Sudan | 27 | 50,448,963 | 1,868,000 |
| Vanuatu | 27 | 327,778 | 12,190 |
| Peru | 27 | 34,217,848 | 1,280,000 |
| Chile | 27 | 19,764,772 | 743,532 |
| Sweden | 26 | 10,606,999 | 407,280 |
| Brazil | 25 | 211,998,574 | 8,358,140 |
| Saint Pierre and Miquelon (France) | 24 | 5,628 | 230 |
| Papua New Guinea | 23 | 10,576,502 | 452,860 |
| Niger | 21 | 27,032,413 | 1,266,700 |
| Bhutan | 21 | 791,525 | 38,140 |
| Mali | 20 | 24,478,596 | 1,220,190 |
| New Zealand | 20 | 5,213,944 | 263,310 |
| Åland (Finland) | 20 | 30,237 | 1,583 |
| Algeria | 20 | 47,400,000 | 2,381,741 |
| Uruguay | 19 | 3,386,588 | 175,020 |
| South Sudan | 19 | 11,943,409 | 631,930 |
| Congo | 19 | 6,332,961 | 341,500 |
| Finland | 18 | 5,617,311 | 303,948 |
| Belize | 18 | 417,072 | 22,810 |
| Oman | 17 | 5,281,538 | 309,500 |
| Argentina | 17 | 45,696,159 | 2,736,690 |
| Chad | 16 | 20,299,123 | 1,259,200 |
| New Caledonia (France) | 16 | 292,640 | 18,280 |
| Turkmenistan | 16 | 7,494,499 | 469,930 |
| Saudi Arabia | 16 | 33,962,757 | 2,149,690 |
| Paraguay | 15 | 6,109,903 | 406,752 |
| Norway | 15 | 5,576,660 | 364,270 |
| South Ossetia | 14 | 56,520 | 3,900 |
| Saint Helena, Ascension and Tristan da Cunha (UK) | 13 | 5,238 | 390 |
| Christmas Island (Australia) | 13 | 1,692 | 136 |
| Bolivia | 11 | 12,413,315 | 1,083,300 |
| Gabon | 9.9 | 2,538,952 | 257,670 |
| Russia | 8.6 | 147,182,123 | 17,125,191 |
| Central African Republic | 8.6 | 5,330,690 | 622,980 |
| Kazakhstan | 7.6 | 20,592,571 | 2,699,700 |
| Niue (New Zealand) | 7.0 | 1,819 | 260 |
| Mauritania | 5.0 | 5,169,396 | 1,030,700 |
| Canada | 4.5 | 39,742,430 | 8,788,700 |
| Botswana | 4.4 | 2,521,139 | 566,730 |
| Guyana | 4.2 | 831,087 | 196,850 |
| Libya | 4.2 | 7,381,023 | 1,759,540 |
| Suriname | 4.0 | 634,431 | 160,508 |
| Iceland | 3.9 | 393,396 | 100,830 |
| Namibia | 3.7 | 3,030,131 | 823,290 |
| Australia | 3.5 | 26,713,205 | 7,692,020 |
| Mongolia | 2.2 | 3,475,540 | 1,557,507 |
| Western Sahara | 2.2 | 590,506 | 266,000 |
| Pitcairn Islands (UK) | 0.85 | 40 | 47 |
| Falkland Islands (UK) | 0.29 | 3,471 | 12,170 |
| Greenland (Denmark) | 0.026 | 55,840 | 2,166,086 |
| Antarctica | 0.009 | 1,300 (winter)5,100 (summer) | 14,200,000 |
| South Georgia and the South Sandwich Islands (UK) | 0.008 | 30 | 3,756 |
^table
// 1. Read and parse data dynamically from the table
const table = Array.from(document.querySelectorAll("table")).find(t =>
t.innerText.includes("Land area") && t.innerText.includes("Population")
);
const data = Array.from(table ? table.querySelectorAll("tbody tr") : []).map(tr => {
const cells = Array.from(tr.querySelectorAll("td")).map(td => td.innerText.trim());
return {
location: cells[0],
density: parseFloat(cells[1].replace(/,/g, "")),
population: parseFloat(cells[2].replace(/,/g, "")),
area: parseFloat(cells[3].replace(/,/g, ""))
};
}).filter(d => d.location && d.location !== "World" && !isNaN(d.population) && !isNaN(d.area) && d.area > 0 && d.population > 0);
// 2. Standard Thresholds (10M Population, 100k km² Area)
const POP_THRESHOLD = 10_000_000;
const AREA_THRESHOLD = 100_000;
// 3. Log-Log Linear Regression (Trend Line)
const n = data.length;
const lx = data.map(d => Math.log10(d.area));
const ly = data.map(d => Math.log10(d.population));
const meanX = lx.reduce((a, b) => a + b, 0) / n;
const meanY = ly.reduce((a, b) => a + b, 0) / n;
const num = lx.reduce((acc, x, i) => acc + (x - meanX) * (ly[i] - meanY), 0);
const den = lx.reduce((acc, x) => acc + Math.pow(x - meanX, 2), 0);
const slope = num / den;
const intercept = meanY - slope * meanX;
const trend = [
{ area: 0.3, population: Math.pow(10, intercept + slope * Math.log10(0.3)) },
{ area: 20_000_000, population: Math.pow(10, intercept + slope * Math.log10(20_000_000)) }
];
// 4. Render
Plot.plot({
title: "Population vs. Land Area",
subtitle: "X = Land area (km²), Y = Population, Color = Density | Blue line: Regression trend | Yellow cross: Large state thresholds (10M pop / 100k km²)",
width: 860,
height: 580,
grid: true,
inset: 24,
x: {
type: "log",
label: "Land Area (km²) →",
tickFormat: "~s"
},
y: {
type: "log",
label: "↑ Population",
tickFormat: "~s"
},
color: {
type: "log",
scheme: "turbo",
legend: true,
label: "Density (/km²)"
},
marks: [
// --- Regression Trend Line (Blue) ---
Plot.line(trend, {
x: "area",
y: "population",
stroke: "#1d63b8",
strokeWidth: 3.5
}),
// --- Threshold Crosshair (Yellow) ---
Plot.ruleX([AREA_THRESHOLD], {
stroke: "#f59e0b",
strokeWidth: 2
}),
Plot.ruleY([POP_THRESHOLD], {
stroke: "#f59e0b",
strokeWidth: 2
}),
// --- Quadrant Corner Badges (Placed out of the way) ---
Plot.text([
{ text: "↖ High Density / Small Land", frameAnchor: "top-left", dx: 10, dy: 10 },
{ text: "↗ Large States (High Pop & Land)", frameAnchor: "top-right", dx: -10, dy: 10 },
{ text: "↙ Microstates & Territories", frameAnchor: "bottom-left", dx: 10, dy: -10 },
{ text: "↘ Large Land / Low Pop", frameAnchor: "bottom-right", dx: -10, dy: -10 }
], {
frameAnchor: "frameAnchor",
text: "text",
fill: "#888",
fontSize: 10,
fontStyle: "italic",
dx: "dx",
dy: "dy"
}),
// --- Country Dots ---
Plot.dot(data, {
x: "area",
y: "population",
fill: "density",
r: 5.5,
stroke: "#222",
strokeWidth: 0.5,
tip: true,
title: d => `${d.location}\nArea: ${d.area.toLocaleString()} km²\nPopulation: ${d.population.toLocaleString()}\nDensity: ${d.density.toLocaleString()} /km²`
}),
// --- Key Country Labels (Always rendered on top with clear text) ---
Plot.text(
data.filter(d => ["China", "India", "Bangladesh", "Taiwan", "Singapore", "Monaco", "Vatican City"].includes(d.location)),
{
x: "area",
y: "population",
text: "location",
dy: -12,
fontSize: 11,
fontWeight: "bold",
fill: "#111",
stroke: "#fff",
strokeWidth: 2,
paintOrder: "stroke" // Ensures the white halo stays behind the text
}
)
]
})
Or in the native way.
const table = Array.from(document.querySelectorAll("table")).find(t =>
t.innerText.includes("Land area") && t.innerText.includes("Population")
);
const data = Array.from(table ? table.querySelectorAll("tbody tr") : []).map(tr => {
const cells = Array.from(tr.querySelectorAll("td")).map(td => td.innerText.trim());
return {
location: cells[0],
density: parseFloat(cells[1].replace(/,/g, "")),
population: parseFloat(cells[2].replace(/,/g, "")),
area: parseFloat(cells[3].replace(/,/g, ""))
};
}).filter(d => d.location && d.location !== "World" && !isNaN(d.population) && !isNaN(d.area) && d.area > 0 && d.population > 0);
const POP_THRESHOLD = 10_000_000;
const AREA_THRESHOLD = 100_000;
const lx = data.map(d => Math.log10(d.area));
const ly = data.map(d => Math.log10(d.population));
const meanX = d3.mean(lx), meanY = d3.mean(ly);
const slope = d3.sum(lx, (x, i) => (x - meanX) * (ly[i] - meanY)) / d3.sum(lx, x => (x - meanX) ** 2);
const intercept = meanY - slope * meanX;
const trend = [0.3, 20_000_000].map(area => ({
area,
population: 10 ** (intercept + slope * Math.log10(area))
}));
const cornerStyle = {fill: "#888", fontSize: 10, fontStyle: "italic"};
const plot = Plot.plot({
title: "Population vs. Land Area",
subtitle: "Color = density (/km²); blue line = log-log regression; orange lines = 10M population / 100k km² thresholds",
width: 860,
height: 580,
grid: true,
inset: 24,
x: {type: "log", label: "Land area (km²) →", tickFormat: "~s"},
y: {type: "log", label: "↑ Population", tickFormat: "~s"},
color: {type: "log", scheme: "turbo", legend: true, label: "Density (/km²)"},
marks: [
Plot.line(trend, {x: "area", y: "population", stroke: "#1d63b8", strokeWidth: 3.5}),
Plot.ruleX([AREA_THRESHOLD], {stroke: "#f59e0b", strokeWidth: 2}),
Plot.ruleY([POP_THRESHOLD], {stroke: "#f59e0b", strokeWidth: 2}),
// Quadrant Corner Labels
Plot.text(["↖ High Density / Small Land"], {frameAnchor: "top-left", dx: 10, dy: 10, ...cornerStyle}),
Plot.text(["↗ Large States (High Pop & Land)"], {frameAnchor: "top-right", dx: -10, dy: 10, ...cornerStyle}),
Plot.text(["↙ Microstates & Territories"], {frameAnchor: "bottom-left", dx: 10, dy: -10, ...cornerStyle}),
Plot.text(["↘ Large Land / Low Pop"], {frameAnchor: "bottom-right", dx: -10, dy: -10, ...cornerStyle}),
Plot.dot(data, {
x: "area", y: "population", fill: "density", r: 5.5,
stroke: "#222", strokeWidth: 0.5, tip: true,
title: d => `${d.location}\nArea: ${d.area.toLocaleString()} km²\nPopulation: ${d.population.toLocaleString()}\nDensity: ${d.density.toLocaleString()} /km²`
}),
Plot.text(
data.filter(d => ["China", "India", "Bangladesh", "Taiwan", "Singapore", "Monaco", "Vatican City"].includes(d.location)),
{x: "area", y: "population", text: "location", dy: -12, fontSize: 11, fontWeight: "bold", fill: "#111", stroke: "#fff", strokeWidth: 2, paintOrder: "stroke"}
)
]
});
Or like in the observableHQ notebook, with a display.
const table = Array.from(document.querySelectorAll("table")).find(t =>
t.innerText.includes("Land area") && t.innerText.includes("Population")
);
const data = Array.from(table ? table.querySelectorAll("tbody tr") : []).map(tr => {
const cells = Array.from(tr.querySelectorAll("td")).map(td => td.innerText.trim());
return {
location: cells[0],
density: parseFloat(cells[1].replace(/,/g, "")),
population: parseFloat(cells[2].replace(/,/g, "")),
area: parseFloat(cells[3].replace(/,/g, ""))
};
}).filter(d => d.location && d.location !== "World" && !isNaN(d.population) && !isNaN(d.area) && d.area > 0 && d.population > 0);
const POP_THRESHOLD = 10_000_000;
const AREA_THRESHOLD = 100_000;
const lx = data.map(d => Math.log10(d.area));
const ly = data.map(d => Math.log10(d.population));
const meanX = d3.mean(lx), meanY = d3.mean(ly);
const slope = d3.sum(lx, (x, i) => (x - meanX) * (ly[i] - meanY)) / d3.sum(lx, x => (x - meanX) ** 2);
const intercept = meanY - slope * meanX;
const trend = [0.3, 20_000_000].map(area => ({
area,
population: 10 ** (intercept + slope * Math.log10(area))
}));
const cornerStyle = {fill: "#888", fontSize: 10, fontStyle: "italic"};
const plot = display(Plot.plot({
title: "Population vs. Land Area",
subtitle: "Color = density (/km²); blue line = log-log regression; orange lines = 10M population / 100k km² thresholds",
width: 900,
height: 600,
grid: true,
inset: 24,
x: {type: "log", label: "Land area (km²) →", tickFormat: "~s"},
y: {type: "log", label: "↑ Population", tickFormat: "~s"},
color: {type: "log", scheme: "turbo", legend: true, label: "Density (/km²)"},
marks: [
Plot.line(trend, {x: "area", y: "population", stroke: "#1d63b8", strokeWidth: 3.5}),
Plot.ruleX([AREA_THRESHOLD], {stroke: "#f59e0b", strokeWidth: 2}),
Plot.ruleY([POP_THRESHOLD], {stroke: "#f59e0b", strokeWidth: 2}),
// Quadrant corner labels: one mark per corner (frameAnchor is a constant option)
Plot.text(["↖ High Density / Small Land"], {frameAnchor: "top-left", dx: 10, dy: 10, ...cornerStyle}),
Plot.text(["↗ Large States (High Pop & Land)"], {frameAnchor: "top-right", dx: -10, dy: 10, ...cornerStyle}),
Plot.text(["↙ Microstates & Territories"], {frameAnchor: "bottom-left", dx: 10, dy: -10, ...cornerStyle}),
Plot.text(["↘ Large Land / Low Pop"], {frameAnchor: "bottom-right", dx: -10, dy: -10, ...cornerStyle}),
Plot.dot(data, {
x: "area", y: "population", fill: "density", r: 5.5,
stroke: "#222", strokeWidth: 0.5, tip: true,
title: d => `${d.location}\nArea: ${d.area.toLocaleString()} km²\nPopulation: ${d.population.toLocaleString()}\nDensity: ${d.density.toLocaleString()} /km²`
}),
Plot.text(
data.filter(d => ["China", "India", "Bangladesh", "Taiwan", "Singapore", "Monaco", "Vatican City"].includes(d.location)),
{x: "area", y: "population", text: "location", dy: -12, fontSize: 11, fontWeight: "bold", fill: "#111", stroke: "#fff", strokeWidth: 2, paintOrder: "stroke"}
)
]
}));