Public
Edited
May 16
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {Plot} from "@observablehq/plot"
Insert cell
Insert cell
topojson = await import("https://cdn.jsdelivr.net/npm/topojson-client@3/+esm")

Insert cell
Insert cell
world = {
const res = await fetch("https://cdn.jsdelivr.net/npm/world-atlas@2.0.2/countries-110m.json");
const data = await res.json();
return topojson.feature(data, data.objects.countries).features;
}

Insert cell
Insert cell
migrant_flow_raw = FileAttachment("migrant_flow_2.csv").csv()

Insert cell
Insert cell
final_data1 = FileAttachment("final_data1.csv").csv()
Insert cell
Insert cell
Object.keys(migrant_flow_raw[0])

Insert cell
Insert cell
cleaned_data = migrant_flow_raw.map(d => ({
country: d["Country, Region"]
?.replace(/\*/g, "") // remove asterisks
?.replace(/\s+/g, " ") // normalize spaces
?.trim(), // remove leading/trailing whitespace
year: +d["year"],
immigrants: +(d["Imigrants"]?.replace(/,/g, "") ?? 0),
emigrants: +(d["Emigrants"]?.replace(/,/g, "") ?? 0)
})).filter(d => d.country && d.year)

Insert cell
Insert cell
viewof selectedYear = Inputs.range([1990, 2020], {
step: 5,
value: 1990,
label: "Select Year"
})

Insert cell
Insert cell
viewof selectedMetric = Inputs.radio(
["Immigrants", "Emigrants"],
{
label: "Filter by",
value: "Immigrants" // default
}
)

Insert cell
Insert cell
countryNameMap = new Map([
["United States", "United States of America"],
["Russian Federation", "Russia"],
["Republic of Korea", "South Korea"],
["Dem. People's Republic of Korea", "North Korea"],
["Viet Nam", "Vietnam"],
["Syrian Arab Republic", "Syria"],
["Iran (Islamic Republic of)", "Iran"],
["Lao People's Democratic Republic", "Laos"],
["Côte d'Ivoire", "Côte d'Ivoire"],
["Cape Verde", "Cabo Verde"],
["Swaziland", "eSwatini"], // now renamed
["United Republic of Tanzania", "Tanzania"],
["Bolivia (Plurinational State of)", "Bolivia"],
["Brunei Darussalam", "Brunei"],
["Czechia", "Czechia"],
["Slovak Republic", "Slovakia"],
["Micronesia (Fed.States of)", "Micronesia (Federated States of)"],
["Moldova", "Moldova"],
["Democratic Republic of the Congo", "Dem. Rep. Congo"],
["Republic of the Congo", "Congo"],
["Dominican Republic", "Dominican Rep."],
["Equatorial Guinea", "Eq. Guinea"],
["South Sudan", "S. Sudan"],
["Western Sahara", "W. Sahara"],
["Palestinian Territories", "Palestine"],
["Kosovo", "Kosovo"],
["Greenland", "Greenland"],
["Venezuela (Bolivarian Republic of)", "Venezuela"],
["Solomon Islands", "Solomon Is."],
["Central African Republic", "Central African Rep."],
["North Macedonia", "Macedonia"],
["Bosnia and Herzegovina", "Bosnia and Herz."],
])

Insert cell
Insert cell
filteredMap = new Map(
cleaned_data
.filter(d => d.year === +selectedYear)
.map(d => {
const geoName = countryNameMap.get(d.country) || d.country;
return [geoName, d[selectedMetric.toLowerCase()]];
})
)

Insert cell
Insert cell
map = Plot.plot({
width: 960,
height: 500,
projection: "equirectangular",
color: {
type: "log",
scheme: "blues",
domain: [10000, 50000000],
label: selectedMetric + " in " + selectedYear,
legend: true
}



,
marks: [
// Country fill based on data
Plot.geo(world, {
fill: d => filteredMap.get(d.properties.name),
stroke: "white", // optional if you want stroke per country too
title: d => {
const val = filteredMap.get(d.properties.name);
return `${d.properties.name}: ${val?.toLocaleString() ?? "No data"}`;
},
tip: true
}),

// Country border lines on top
Plot.geo(world, { stroke: "grey", fill: null }),

// Globe outline and graticule
Plot.sphere(),
Plot.graticule()
]

})

Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more