Skip to content

Commit 5288e97

Browse files
authored
Merge pull request #1 from com-480-data-visualization/krish
pushing work on data analysis, first draft of screencast, and process book
2 parents cb4f2d0 + d4d713f commit 5288e97

30 files changed

Lines changed: 582 additions & 56 deletions

Milestone 1.pdf

513 KB
Binary file not shown.

data/processed/figures.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"_meta": {
3+
"generated_by": "notebooks/03_figures.py",
4+
"generated_at": "2026-05-28T14:32:03Z",
5+
"note": "Every number is derived from data/processed/*. Do not hand-edit.",
6+
"refinery_year": 2025
7+
},
8+
"processing_gain_pct": 5.9,
9+
"yields_2025": {
10+
"gasoline": 46.0,
11+
"diesel": 30.0,
12+
"jet": 11.1
13+
},
14+
"diesel_delta_pp": 8.1,
15+
"world_demand_mbd": {
16+
"2024": 102.8,
17+
"2025": 103.97,
18+
"2026": 104.16,
19+
"2027": 105.64
20+
},
21+
"counter_rate_bps": 1205,
22+
"eia_2026_delta_kbd": 190,
23+
"world_growth": {
24+
"from_year": 1965,
25+
"from_mbd": 29.0,
26+
"to_year": 2024,
27+
"to_mbd": 89.1,
28+
"multiple": 3.07
29+
}
30+
}

data/raw/eia_refinery_yield.csv

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
Back to Contents,Data 1: U.S. Refinery Yield,,,,,,,,,,,,,,,,
2-
Sourcekey,M_EPL0_YRY_NUS_PER,MGFRYUS3,MGARYUS3,MKJRYUS3,MKERYUS3,MDIRYUS3,MRERYUS3,MNFRYUS3,MOTRYUS3,MNSRYUS3,MLURYUS3,MWXRYUS3,MCKRYUS3,MAPRYUS3,MSGRYUS3,MMSRYUS3,MPGRYUS3
3-
Date,U.S. Refinery Yield of Hydrocarbon Gas Liquids (Percent),U.S. Refinery Yield of Finished Motor Gasoline (Percent),U.S. Refinery Yield of Aviation Gasoline (Percent),U.S. Refinery Yield of Kerosene-Type Jet Fuel (Percent),U.S. Refinery Yield of Kerosene (Percent),U.S. Refinery Yield of Distillate Fuel Oil (Percent),U.S. Refinery Yield of Residual Fuel Oil (Percent),U.S. Refinery Yield of Naphtha for Petrochemical Feedstock Use (Percent),U.S. Refinery Yield of Other Oils for Petrochemical Feedstock Use (Percent),U.S. Refinery Yield of Special Naphthas (Percent),U.S. Refinery Yield of Lubricants (Percent),U.S. Refinery Yield of Waxes (Percent),U.S. Refinery Yield of Petroleum Coke (Percent),U.S. Refinery Yield of Asphalt and Road Oil (Percent),U.S. Refinery Yield of Still Gas (Percent),U.S. Refinery Yield of Miscellaneous Petroleum Products (Percent),U.S. Refinery Processing Gain (Percent)
4-
1993-06-30,,46.1,0.2,9.2,0.3,21.9,5.8,1.0,2.0,0.4,1.1,0.1,4.3,3.2,4.6,0.3,-5.4
5-
1994-06-30,,45.5,0.2,9.8,0.4,22.3,5.7,1.1,1.8,0.4,1.2,0.1,4.3,3.1,4.6,0.3,-5.3
6-
1995-06-30,,46.4,0.2,9.7,0.4,21.8,5.4,1.2,1.7,0.3,1.2,0.1,4.3,3.2,4.5,0.3,-5.3
7-
1996-06-30,,45.7,0.2,10.4,0.4,22.7,5.0,1.3,1.4,0.3,1.2,0.2,4.5,3.1,4.5,0.3,-5.7
8-
1997-06-30,,45.7,0.2,10.3,0.4,22.5,4.7,1.5,1.4,0.3,1.2,0.2,4.6,3.2,4.4,0.3,-5.6
9-
1998-06-30,,46.2,0.1,9.9,0.5,22.3,5.0,1.6,1.4,0.4,1.2,0.1,4.6,3.3,4.3,0.4,-5.8
10-
1999-06-30,,46.5,0.2,10.2,0.4,22.3,4.6,1.3,1.4,0.6,1.2,0.1,4.7,3.3,4.3,0.3,-5.8
11-
2000-06-30,,46.2,0.1,10.3,0.4,23.1,4.5,1.3,1.3,0.4,1.2,0.1,4.7,3.4,4.2,0.4,-6.1
12-
2001-06-30,,46.2,0.1,9.8,0.5,23.8,4.6,1.1,1.1,0.3,1.1,0.1,4.9,3.1,4.3,0.4,-5.8
13-
2002-06-30,,47.3,0.1,9.8,0.4,23.2,3.9,1.6,1.0,0.3,1.1,0.1,5.1,3.2,4.3,0.4,-6.2
14-
2003-06-30,,46.9,0.1,9.5,0.4,23.7,4.2,1.5,1.2,0.3,1.1,0.1,5.1,3.2,4.5,0.4,-6.2
15-
2004-06-30,,46.8,0.1,9.7,0.4,23.9,4.1,1.6,1.3,0.3,1.1,0.1,5.2,3.2,4.4,0.4,-6.6
16-
2005-06-30,,46.2,0.1,9.8,0.4,25.0,4.0,1.4,1.1,0.2,1.1,0.1,5.3,3.2,4.3,0.4,-6.3
17-
2006-06-30,,45.8,0.1,9.3,0.3,25.4,4.0,1.2,1.2,0.2,1.2,0.1,5.3,3.2,4.5,0.4,-6.3
18-
2007-06-30,4.1,45.5,0.1,9.1,0.2,26.1,4.2,1.3,1.3,0.3,1.1,0.1,5.2,2.9,4.4,0.4,-6.3
19-
2008-06-30,4.1,44.2,0.1,9.7,0.1,27.8,4.0,1.0,1.2,0.3,1.1,0.1,5.3,2.7,4.3,0.5,-6.4
20-
2009-06-30,4.1,46.6,0.1,9.2,0.1,26.6,3.9,1.3,0.8,0.2,1.0,0.1,5.3,2.4,4.4,0.5,-6.4
21-
2010-06-30,4.3,46.3,0.1,9.2,0.1,27.2,3.7,1.4,0.8,0.2,1.1,0.1,5.3,2.5,4.3,0.5,-6.9
22-
2011-06-30,4.0,45.6,0.1,9.3,0.1,28.6,3.4,1.3,0.7,0.2,1.1,0.1,5.4,2.3,4.3,0.5,-6.9
23-
2012-06-30,4.0,45.7,0.1,9.4,0.1,28.7,3.1,1.3,0.6,0.3,1.0,0.1,5.4,2.2,4.3,0.5,-6.7
24-
2013-06-30,3.9,45.7,0.1,9.4,0.1,29.1,2.9,1.5,0.6,0.3,1.0,0.1,5.4,2.0,4.4,0.5,-6.8
25-
2014-06-30,4.0,45.7,0.1,9.4,0.1,29.5,2.6,1.2,0.7,0.3,1.0,0.0,5.3,1.9,4.2,0.5,-6.6
26-
2015-06-30,3.7,46.0,0.1,9.6,0.1,29.5,2.5,1.1,0.6,0.2,1.1,0.0,5.2,2.0,4.1,0.6,-6.4
27-
2016-06-30,3.8,47.0,0.1,9.8,0.1,28.4,2.5,1.1,0.6,0.2,1.0,0.0,5.4,1.9,4.2,0.5,-6.7
28-
2017-06-30,3.7,46.5,0.1,9.9,0.0,29.0,2.5,1.1,0.7,0.2,1.0,0.0,5.3,1.9,4.0,0.6,-6.5
29-
2018-06-30,3.6,46.1,0.1,10.3,0.1,29.2,2.5,1.2,0.6,0.2,1.1,0.0,5.1,1.8,4.0,0.5,-6.5
30-
2019-06-30,3.5,46.2,0.1,10.5,0.1,29.7,2.1,1.1,0.6,0.2,1.0,0.0,4.9,1.9,3.9,0.5,-6.2
31-
2020-06-30,3.7,46.9,0.1,6.9,0.1,32.0,1.3,1.2,0.7,0.2,1.0,0.0,5.2,2.2,4.2,0.6,-6.3
32-
2021-06-30,4.0,47.8,0.1,8.4,0.1,29.7,1.4,1.1,0.6,0.2,1.1,0.0,4.9,2.2,4.1,0.5,-6.2
33-
2022-06-30,3.7,46.5,0.1,9.9,0.1,30.3,1.6,0.8,0.6,0.2,1.0,0.0,4.9,2.1,4.1,0.6,-6.3
34-
2023-06-30,3.7,46.6,0.1,10.5,0.1,29.7,1.7,0.8,0.6,0.2,0.9,0.0,5.0,2.0,4.0,0.5,-6.3
35-
2024-06-30,3.5,46.0,0.1,11.0,0.1,29.7,1.9,0.8,0.5,0.2,1.0,0.0,4.8,2.1,3.9,0.5,-5.9
36-
2025-06-30,3.5,45.9,0.1,11.0,0.1,30.0,1.9,0.9,0.5,0.2,1.0,0.0,4.6,2.0,3.9,0.5,-5.9
1+
Back to Contents,Data 1: U.S. Refinery Yield,,,,,,,,,,,,,,,,
2+
Sourcekey,M_EPL0_YRY_NUS_PER,MGFRYUS3,MGARYUS3,MKJRYUS3,MKERYUS3,MDIRYUS3,MRERYUS3,MNFRYUS3,MOTRYUS3,MNSRYUS3,MLURYUS3,MWXRYUS3,MCKRYUS3,MAPRYUS3,MSGRYUS3,MMSRYUS3,MPGRYUS3
3+
Date,U.S. Refinery Yield of Hydrocarbon Gas Liquids (Percent),U.S. Refinery Yield of Finished Motor Gasoline (Percent),U.S. Refinery Yield of Aviation Gasoline (Percent),U.S. Refinery Yield of Kerosene-Type Jet Fuel (Percent),U.S. Refinery Yield of Kerosene (Percent),U.S. Refinery Yield of Distillate Fuel Oil (Percent),U.S. Refinery Yield of Residual Fuel Oil (Percent),U.S. Refinery Yield of Naphtha for Petrochemical Feedstock Use (Percent),U.S. Refinery Yield of Other Oils for Petrochemical Feedstock Use (Percent),U.S. Refinery Yield of Special Naphthas (Percent),U.S. Refinery Yield of Lubricants (Percent),U.S. Refinery Yield of Waxes (Percent),U.S. Refinery Yield of Petroleum Coke (Percent),U.S. Refinery Yield of Asphalt and Road Oil (Percent),U.S. Refinery Yield of Still Gas (Percent),U.S. Refinery Yield of Miscellaneous Petroleum Products (Percent),U.S. Refinery Processing Gain (Percent)
4+
1993-06-30,,46.1,0.2,9.2,0.3,21.9,5.8,1.0,2.0,0.4,1.1,0.1,4.3,3.2,4.6,0.3,-5.4
5+
1994-06-30,,45.5,0.2,9.8,0.4,22.3,5.7,1.1,1.8,0.4,1.2,0.1,4.3,3.1,4.6,0.3,-5.3
6+
1995-06-30,,46.4,0.2,9.7,0.4,21.8,5.4,1.2,1.7,0.3,1.2,0.1,4.3,3.2,4.5,0.3,-5.3
7+
1996-06-30,,45.7,0.2,10.4,0.4,22.7,5.0,1.3,1.4,0.3,1.2,0.2,4.5,3.1,4.5,0.3,-5.7
8+
1997-06-30,,45.7,0.2,10.3,0.4,22.5,4.7,1.5,1.4,0.3,1.2,0.2,4.6,3.2,4.4,0.3,-5.6
9+
1998-06-30,,46.2,0.1,9.9,0.5,22.3,5.0,1.6,1.4,0.4,1.2,0.1,4.6,3.3,4.3,0.4,-5.8
10+
1999-06-30,,46.5,0.2,10.2,0.4,22.3,4.6,1.3,1.4,0.6,1.2,0.1,4.7,3.3,4.3,0.3,-5.8
11+
2000-06-30,,46.2,0.1,10.3,0.4,23.1,4.5,1.3,1.3,0.4,1.2,0.1,4.7,3.4,4.2,0.4,-6.1
12+
2001-06-30,,46.2,0.1,9.8,0.5,23.8,4.6,1.1,1.1,0.3,1.1,0.1,4.9,3.1,4.3,0.4,-5.8
13+
2002-06-30,,47.3,0.1,9.8,0.4,23.2,3.9,1.6,1.0,0.3,1.1,0.1,5.1,3.2,4.3,0.4,-6.2
14+
2003-06-30,,46.9,0.1,9.5,0.4,23.7,4.2,1.5,1.2,0.3,1.1,0.1,5.1,3.2,4.5,0.4,-6.2
15+
2004-06-30,,46.8,0.1,9.7,0.4,23.9,4.1,1.6,1.3,0.3,1.1,0.1,5.2,3.2,4.4,0.4,-6.6
16+
2005-06-30,,46.2,0.1,9.8,0.4,25.0,4.0,1.4,1.1,0.2,1.1,0.1,5.3,3.2,4.3,0.4,-6.3
17+
2006-06-30,,45.8,0.1,9.3,0.3,25.4,4.0,1.2,1.2,0.2,1.2,0.1,5.3,3.2,4.5,0.4,-6.3
18+
2007-06-30,4.1,45.5,0.1,9.1,0.2,26.1,4.2,1.3,1.3,0.3,1.1,0.1,5.2,2.9,4.4,0.4,-6.3
19+
2008-06-30,4.1,44.2,0.1,9.7,0.1,27.8,4.0,1.0,1.2,0.3,1.1,0.1,5.3,2.7,4.3,0.5,-6.4
20+
2009-06-30,4.1,46.6,0.1,9.2,0.1,26.6,3.9,1.3,0.8,0.2,1.0,0.1,5.3,2.4,4.4,0.5,-6.4
21+
2010-06-30,4.3,46.3,0.1,9.2,0.1,27.2,3.7,1.4,0.8,0.2,1.1,0.1,5.3,2.5,4.3,0.5,-6.9
22+
2011-06-30,4.0,45.6,0.1,9.3,0.1,28.6,3.4,1.3,0.7,0.2,1.1,0.1,5.4,2.3,4.3,0.5,-6.9
23+
2012-06-30,4.0,45.7,0.1,9.4,0.1,28.7,3.1,1.3,0.6,0.3,1.0,0.1,5.4,2.2,4.3,0.5,-6.7
24+
2013-06-30,3.9,45.7,0.1,9.4,0.1,29.1,2.9,1.5,0.6,0.3,1.0,0.1,5.4,2.0,4.4,0.5,-6.8
25+
2014-06-30,4.0,45.7,0.1,9.4,0.1,29.5,2.6,1.2,0.7,0.3,1.0,0.0,5.3,1.9,4.2,0.5,-6.6
26+
2015-06-30,3.7,46.0,0.1,9.6,0.1,29.5,2.5,1.1,0.6,0.2,1.1,0.0,5.2,2.0,4.1,0.6,-6.4
27+
2016-06-30,3.8,47.0,0.1,9.8,0.1,28.4,2.5,1.1,0.6,0.2,1.0,0.0,5.4,1.9,4.2,0.5,-6.7
28+
2017-06-30,3.7,46.5,0.1,9.9,0.0,29.0,2.5,1.1,0.7,0.2,1.0,0.0,5.3,1.9,4.0,0.6,-6.5
29+
2018-06-30,3.6,46.1,0.1,10.3,0.1,29.2,2.5,1.2,0.6,0.2,1.1,0.0,5.1,1.8,4.0,0.5,-6.5
30+
2019-06-30,3.5,46.2,0.1,10.5,0.1,29.7,2.1,1.1,0.6,0.2,1.0,0.0,4.9,1.9,3.9,0.5,-6.2
31+
2020-06-30,3.7,46.9,0.1,6.9,0.1,32.0,1.3,1.2,0.7,0.2,1.0,0.0,5.2,2.2,4.2,0.6,-6.3
32+
2021-06-30,4.0,47.8,0.1,8.4,0.1,29.7,1.4,1.1,0.6,0.2,1.1,0.0,4.9,2.2,4.1,0.5,-6.2
33+
2022-06-30,3.7,46.5,0.1,9.9,0.1,30.3,1.6,0.8,0.6,0.2,1.0,0.0,4.9,2.1,4.1,0.6,-6.3
34+
2023-06-30,3.7,46.6,0.1,10.5,0.1,29.7,1.7,0.8,0.6,0.2,0.9,0.0,5.0,2.0,4.0,0.5,-6.3
35+
2024-06-30,3.5,46.0,0.1,11.0,0.1,29.7,1.9,0.8,0.5,0.2,1.0,0.0,4.8,2.1,3.9,0.5,-5.9
36+
2025-06-30,3.5,45.9,0.1,11.0,0.1,30.0,1.9,0.9,0.5,0.2,1.0,0.0,4.6,2.0,3.9,0.5,-5.9

data/raw/iea_oil_2024.pdf

3.99 MB
Binary file not shown.

notebooks/01_explore.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ def banner(text: str) -> None:
4040
print("=" * 72)
4141

4242

43-
# --------------------------------------------------------------------- #
4443
# 1. OWID oil consumption by country (1965 - 2024)
45-
# --------------------------------------------------------------------- #
4644
banner("OWID — oil consumption by country (TWh)")
4745

4846
owid = pd.read_csv(RAW / "owid_oil_consumption_by_country.csv")
@@ -101,10 +99,7 @@ def is_country(row) -> bool:
10199
# Save processed
102100
owid.to_csv(OUT / "consumption_by_country.csv", index=False)
103101

104-
105-
# --------------------------------------------------------------------- #
106102
# 2. EIA U.S. refinery yield (% of crude input by product, annual)
107-
# --------------------------------------------------------------------- #
108103
banner("EIA — U.S. refinery yield (percent of crude input)")
109104

110105
# The EIA XLS has 2 sheets: 'Contents' and 'Data 1'. We pre-converted the
@@ -156,9 +151,7 @@ def is_country(row) -> bool:
156151
long.to_csv(OUT / "us_refinery_yield.csv", index=False)
157152

158153

159-
# --------------------------------------------------------------------- #
160154
# 3. Compose the 'one barrel' summary for the D3 tower scene
161-
# --------------------------------------------------------------------- #
162155
banner("Building one-barrel summary for the distillation tower scene")
163156

164157
# Group EIA's 16 finer products into the 7 bands the tower will show.
@@ -211,10 +204,7 @@ def is_country(row) -> bool:
211204
(OUT / "tower.json").write_text(json.dumps(tower_payload, indent=2))
212205
print(f"\nWrote {OUT / 'tower.json'}")
213206

214-
215-
# --------------------------------------------------------------------- #
216207
# 4. World time series for scene 5 (stacked area / trend)
217-
# --------------------------------------------------------------------- #
218208
banner("World time series 1965 - 2024")
219209

220210
world_ts = owid[owid["entity"] == "World"][["year", "mbd", "oil_twh"]].copy()
@@ -223,9 +213,7 @@ def is_country(row) -> bool:
223213
print(world_ts.iloc[::10].to_string(index=False))
224214

225215

226-
# --------------------------------------------------------------------- #
227216
# 5. Yield time series for scene "tower changes over time" (optional)
228-
# --------------------------------------------------------------------- #
229217
banner("Yield trends 1993 - 2025 (selected bands)")
230218

231219
bands_long = long.copy()
@@ -244,9 +232,7 @@ def is_country(row) -> bool:
244232
print(f" {col:<22} {first:5.1f}% -> {last:5.1f}% ({sign}{delta:.1f} pp)")
245233

246234

247-
# --------------------------------------------------------------------- #
248235
# 6. Useful site-wide numbers for copy + live counter
249-
# --------------------------------------------------------------------- #
250236
banner("Numbers for the M1 copy and the live counter")
251237

252238
if not world_2024.empty:

notebooks/02_steo.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ def banner(text: str) -> None:
3636
print("=" * 72)
3737

3838

39-
# --------------------------------------------------------------------- #
4039
# Read STEO 3e (world consumption) — wide format with monthly columns
41-
# --------------------------------------------------------------------- #
4240
banner("STEO Table 3e — World Petroleum & Other Liquid Fuels Consumption")
4341

4442
wb = openpyxl.load_workbook(RAW, data_only=True)
@@ -103,9 +101,7 @@ def banner(text: str) -> None:
103101
print(f" {c:<20} {l}")
104102

105103

106-
# --------------------------------------------------------------------- #
107104
# Useful pivots for the D3 site
108-
# --------------------------------------------------------------------- #
109105
banner("Headline figures from STEO May 2026")
110106

111107
world = df[df["code"] == "patc_world"].sort_values("date")
@@ -133,9 +129,7 @@ def banner(text: str) -> None:
133129
print(f"\nwrote {OUT / 'steo_monthly_consumption.csv'} ({len(focus_df)} rows)")
134130

135131

136-
# --------------------------------------------------------------------- #
137132
# Reconciliation: STEO vs OWID for the same year
138-
# --------------------------------------------------------------------- #
139133
banner("Reconciling STEO (broad) vs OWID/EI (narrow) for 2024")
140134

141135
owid = pd.read_csv(ROOT / "data" / "processed" / "consumption_by_country.csv")

notebooks/03_figures.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
"""
2+
Emit data/processed/figures.json — the single source of truth for every
3+
site-wide number that used to be hand-typed in src/lib/constants.js.
4+
5+
Every value here is DERIVED from the processed datasets, so the website can
6+
import it at build time and no headline number is ever typed by hand again.
7+
The two editorial agency deltas that are NOT in our data (IEA, OPEC — they come
8+
from those agencies' own reports) stay in constants.js with their citations;
9+
only EIA's delta is derivable here (STEO is EIA's own series).
10+
11+
Run with:
12+
python3 notebooks/03_figures.py
13+
"""
14+
15+
from __future__ import annotations
16+
17+
import json
18+
from datetime import datetime, timezone
19+
from pathlib import Path
20+
21+
import pandas as pd
22+
23+
ROOT = Path(__file__).resolve().parent.parent
24+
PROC = ROOT / "data" / "processed"
25+
26+
27+
def _world_annual(steo: pd.DataFrame) -> dict[int, float]:
28+
world = steo[steo["code"] == "patc_world"].copy()
29+
world["year"] = world["date"].str[:4].astype(int)
30+
return world.groupby("year")["mbd"].mean().round(2).to_dict()
31+
32+
33+
def build_figures() -> dict:
34+
# 1. Processing gain (latest year, absolute value).
35+
yld = pd.read_csv(PROC / "us_refinery_yield.csv")
36+
latest_yld_year = int(yld["year"].max())
37+
gain_row = yld[
38+
(yld["year"] == latest_yld_year)
39+
& (yld["product"] == "U.S. Refinery Processing Gain")
40+
]
41+
processing_gain_pct = round(abs(float(gain_row["pct"].iloc[0])), 1)
42+
43+
# 2. Headline 2025 yields, from the tower snapshot.
44+
tower = json.loads((PROC / "tower.json").read_text())
45+
bands = {b["band"]: b["pct"] for b in tower["bands"]}
46+
yields = {
47+
"gasoline": round(bands["Gasoline"], 1),
48+
"diesel": round(bands["Diesel / Distillate"], 1),
49+
"jet": round(bands["Kerosene / Jet"], 1),
50+
}
51+
52+
# 3. Diesel drift over the full refinery-yield series.
53+
bot = pd.read_csv(PROC / "yield_by_band_over_time.csv")
54+
diesel = bot[bot["band"] == "Diesel / Distillate"].sort_values("year")
55+
diesel_delta_pp = round(
56+
float(diesel["pct"].iloc[-1]) - float(diesel["pct"].iloc[0]), 1
57+
)
58+
59+
# 4. World demand (broad STEO basis) + derived counter rate + EIA delta.
60+
steo = pd.read_csv(PROC / "steo_monthly_consumption.csv")
61+
world = _world_annual(steo)
62+
world_demand = {str(y): world[y] for y in (2024, 2025, 2026, 2027) if y in world}
63+
# Floor: the counter ticks whole barrels (1205.56/s → 1205 complete barrels).
64+
counter_rate_bps = int(world[2026] * 1e6 / 86_400)
65+
eia_2026_delta_kbd = round((world[2026] - world[2025]) * 1000)
66+
67+
# 5. Long-run growth (narrow OWID basis).
68+
wc = pd.read_csv(PROC / "world_consumption.csv").sort_values("year")
69+
g_from, g_to = wc.iloc[0], wc.iloc[-1]
70+
world_growth = {
71+
"from_year": int(g_from["year"]),
72+
"from_mbd": round(float(g_from["mbd"]), 1),
73+
"to_year": int(g_to["year"]),
74+
"to_mbd": round(float(g_to["mbd"]), 1),
75+
"multiple": round(float(g_to["mbd"]) / float(g_from["mbd"]), 2),
76+
}
77+
78+
return {
79+
"_meta": {
80+
"generated_by": "notebooks/03_figures.py",
81+
"generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
82+
"note": "Every number is derived from data/processed/*. Do not hand-edit.",
83+
"refinery_year": latest_yld_year,
84+
},
85+
"processing_gain_pct": processing_gain_pct,
86+
"yields_2025": yields,
87+
"diesel_delta_pp": diesel_delta_pp,
88+
"world_demand_mbd": world_demand,
89+
"counter_rate_bps": counter_rate_bps,
90+
"eia_2026_delta_kbd": eia_2026_delta_kbd,
91+
"world_growth": world_growth,
92+
}
93+
94+
95+
def main() -> None:
96+
figures = build_figures()
97+
out = PROC / "figures.json"
98+
out.write_text(json.dumps(figures, indent=2) + "\n")
99+
print(f"wrote {out}")
100+
print(json.dumps(figures, indent=2))
101+
102+
103+
if __name__ == "__main__":
104+
main()

0 commit comments

Comments
 (0)