Show code
from __future__ import annotations
import pandas as pd
from eu_trade_network import config, data_loader, db, graph, vizBuilds the bilateral edge list for config.YEAR from the raw BACI files, turns it into the directed weighted graph that every later notebook rebuilds, stores nodes and edges in DuckDB, and draws the flow map.
The source, node set, and modelling decisions are on the Data & method page.
Build the bilateral edge list for config.YEAR, construct the directed weighted graph, and print a headline summary.
node_meta = (
pd.DataFrame([{"iso3": n, **attrs} for n, attrs in G.nodes(data=True)])
.sort_values("iso3")
.reset_index(drop=True)
)
node_meta["out_strength"] = [float(G.out_degree(n, weight="weight")) for n in node_meta["iso3"]]
node_meta["in_strength"] = [float(G.in_degree(n, weight="weight")) for n in node_meta["iso3"]]
node_meta["degree"] = [int(G.degree(n)) for n in node_meta["iso3"]]
edges_db = edgelist.copy()
edges_db["year"] = config.YEAR
con = db.connect()
db.init_schema(con)
db.write_table(
con,
"nodes",
node_meta[["iso3", "name", "grp", "out_strength", "in_strength", "degree"]],
)
db.write_table(con, "edges", edges_db[["exporter_iso3", "importer_iso3", "value_kusd", "year"]])
print(f"Wrote {len(node_meta)} nodes and {len(edges_db)} edges → {config.DB_PATH}")
con.close()# Cartesian lon/lat map is kaleido-safe (no Plotly topojson CDN) and matches
# the dark Quarto theme used for headline PNGs.
fig = viz.plot_lonlat_flows(
edgelist,
node_meta,
top_n=150,
title=f"European merchandise trade flows {config.YEAR} (top 150 edges)",
)
out = viz.save_fig(fig, "01_flow_map.png", headline=True)
print(f"Saved {out}")
fig.show()