Skip to content

Commit 8085fcb

Browse files
world maps
1 parent e0a1084 commit 8085fcb

4 files changed

Lines changed: 48 additions & 27 deletions

File tree

cybench/runs/analysis/index_map_lib.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
import re
77
import shutil
88
from pathlib import Path
9-
from typing import Any
9+
from typing import TYPE_CHECKING, Any
1010

1111
from cybench.runs.analysis.publish_dashboard_bundle import IndexEntry, _COUNTRY_NAMES
1212

13+
if TYPE_CHECKING:
14+
import geopandas as gpd
15+
1316
_BUNDLED_GEOJSON = (
1417
Path(__file__).resolve().parent.parent / "viz" / "data" / "world_countries_110m.geojson"
1518
)
@@ -29,6 +32,7 @@
2932
"FR": (-5.5, 41.0, 10.0, 51.5),
3033
}
3134
_OVERSEAS_MAP_ISO = "XX"
35+
_EXCLUDED_MAP_ISOS = frozenset({"AQ"})
3236

3337

3438
def _explode_metropolitan_map_units(frame: gpd.GeoDataFrame) -> gpd.GeoDataFrame:
@@ -157,6 +161,7 @@ def export_world_geojson(dest: Path, *, simplify: float = 0.08) -> Path:
157161
iso = iso.where(~bad, world[wb_col].astype(str))
158162
keep["ISO_A2"] = iso
159163
keep = keep[keep["ISO_A2"].notna() & (keep["ISO_A2"] != "-99") & (keep["ISO_A2"] != "nan")]
164+
keep = keep[~keep["ISO_A2"].isin(_EXCLUDED_MAP_ISOS)]
160165
keep["geometry"] = keep.geometry.simplify(simplify, preserve_topology=True)
161166
keep = _explode_metropolitan_map_units(keep)
162167
dest.parent.mkdir(parents=True, exist_ok=True)

cybench/runs/viz/index_map_template.html

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,18 +210,33 @@ <h3>${c.name}</h3>
210210

211211
const width = 960;
212212
const height = 520;
213+
const margin = 8;
213214
const svg = d3.select("#map-wrap").html("").append("svg")
214215
.attr("viewBox", `0 0 ${width} ${height}`)
215216
.attr("role", "img")
216217
.attr("aria-label", "World map of CY-Bench dashboard countries");
217218

218219
const g = svg.append("g");
219-
const projection = d3.geoNaturalEarth1().fitSize([width, height], {type: "Sphere"});
220-
const path = d3.geoPath(projection);
220+
let projection = d3.geoNaturalEarth1();
221+
let path = d3.geoPath(projection);
222+
223+
function mapFeaturesWithoutAntarctica(features) {
224+
return (features || []).filter(f => f.properties.ISO_A2 !== "AQ");
225+
}
226+
227+
function fitMapProjection(features) {
228+
projection = d3.geoNaturalEarth1().fitExtent(
229+
[[margin, margin], [width - margin, height - margin]],
230+
{ type: "FeatureCollection", features },
231+
);
232+
path = d3.geoPath(projection);
233+
}
221234

222235
d3.json(DATA.geojson_href).then(geo => {
236+
const features = mapFeaturesWithoutAntarctica(geo.features);
237+
fitMapProjection(features);
223238
g.selectAll("path")
224-
.data(geo.features)
239+
.data(features)
225240
.join("path")
226241
.attr("class", d => {
227242
const c = isoToCountry(d.properties.ISO_A2);

cybench/runs/viz/model_family_radar_template.html

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ <h2>World map</h2>
296296
<div class="benefit-legend" id="benefit-legend" style="display:none;">
297297
<span class="benefit-gradient" aria-hidden="true"></span>
298298
<span id="benefit-legend-label">−40% · 0% · +40%</span>
299-
<span class="muted">red = traditional better · yellow = little gain · green = AI better · outliers saturated</span>
299+
<span class="muted">red = traditional better · yellow = little gain · green = AI better · hover for exact %</span>
300300
</div>
301301
<p class="muted winner-summary" id="winner-summary"></p>
302302
</div>
@@ -845,14 +845,27 @@ <h2>World map</h2>
845845

846846
const MAP_WIDTH = 960;
847847
const MAP_HEIGHT = 520;
848+
const MAP_MARGIN = 8;
848849
const mapSvg = d3.select("#winner-map-wrap").html("").append("svg")
849850
.attr("viewBox", `0 0 ${MAP_WIDTH} ${MAP_HEIGHT}`)
850851
.attr("role", "img")
851852
.attr("aria-label", "World map of winning model families");
852-
const mapProjection = d3.geoNaturalEarth1().fitSize([MAP_WIDTH, MAP_HEIGHT], { type: "Sphere" });
853-
const mapPath = d3.geoPath(mapProjection);
853+
let mapProjection = d3.geoNaturalEarth1();
854+
let mapPath = d3.geoPath(mapProjection);
854855
let worldFeatures = null;
855856

857+
function mapFeaturesWithoutAntarctica(features) {
858+
return (features || []).filter(f => f.properties.ISO_A2 !== "AQ");
859+
}
860+
861+
function fitMapProjection(features) {
862+
mapProjection = d3.geoNaturalEarth1().fitExtent(
863+
[[MAP_MARGIN, MAP_MARGIN], [MAP_WIDTH - MAP_MARGIN, MAP_HEIGHT - MAP_MARGIN]],
864+
{ type: "FeatureCollection", features },
865+
);
866+
mapPath = d3.geoPath(mapProjection);
867+
}
868+
856869
function winnerColorMap() {
857870
const out = {};
858871
Object.entries(DATA.family_catalog || {}).forEach(([fam, obj]) => {
@@ -968,19 +981,8 @@ <h2>World map</h2>
968981
if (!rec || rec.benefit_pct == null) return MAP_FILL_NO_DATA;
969982
return benefitColor(rec.benefit_pct, extent);
970983
})
971-
.attr("stroke", d => {
972-
const iso = d.properties.ISO_A2;
973-
if (!isBenchmarkIso(iso)) return "#d0d7de";
974-
const rec = byCountry.get(iso);
975-
if (rec && benefitOffScale(rec.benefit_pct, extent)) return "#1f2328";
976-
return "#fff";
977-
})
978-
.attr("stroke-width", d => {
979-
const iso = d.properties.ISO_A2;
980-
if (!isBenchmarkIso(iso)) return 0.25;
981-
const rec = byCountry.get(iso);
982-
return rec && benefitOffScale(rec.benefit_pct, extent) ? 1.1 : 0.5;
983-
});
984+
.attr("stroke", d => isBenchmarkIso(d.properties.ISO_A2) ? "#fff" : "#d0d7de")
985+
.attr("stroke-width", d => isBenchmarkIso(d.properties.ISO_A2) ? 0.5 : 0.25);
984986

985987
countriesSel.selectAll("title")
986988
.data(d => [d])
@@ -1011,7 +1013,7 @@ <h2>World map</h2>
10111013
+ `${rows.length} countries (${nPositive} with AI better than traditional). `
10121014
+ `Color scale ±${extent}% (85th percentile, largest outlier excluded).`;
10131015
if (nOffScale) {
1014-
summary += ` ${nOffScale} countr${nOffScale === 1 ? "y" : "ies"} beyond scale (dark border).`;
1016+
summary += ` ${nOffScale} countr${nOffScale === 1 ? "y" : "ies"} beyond scale (color clamped; hover for exact value).`;
10151017
}
10161018
winnerSummary.textContent = summary;
10171019
}
@@ -1082,8 +1084,7 @@ <h2>World map</h2>
10821084
function buildMapExportSvgString() {
10831085
const mapNode = winnerMapWrap.querySelector("svg");
10841086
if (!mapNode || !worldFeatures) return null;
1085-
const { hzLabel, cropLabel, modeLabel } = mapExportMeta();
1086-
const padT = 48;
1087+
const padT = 12;
10871088
const padB = 72;
10881089
const totalH = MAP_HEIGHT + padT + padB;
10891090
const legendY = padT + MAP_HEIGHT + 16;
@@ -1094,8 +1095,6 @@ <h2>World map</h2>
10941095
return `<?xml version="1.0" encoding="UTF-8"?>
10951096
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${MAP_WIDTH} ${totalH}" width="${MAP_WIDTH}" height="${totalH}">
10961097
<rect width="100%" height="100%" fill="#ffffff"/>
1097-
<text x="24" y="28" font-size="16" font-weight="600" font-family="system-ui,sans-serif" fill="#1f2328">${escapeXml(`CY-Bench model families · ${hzLabel} · ${cropLabel}`)}</text>
1098-
<text x="24" y="44" font-size="12" font-family="system-ui,sans-serif" fill="#656d76">${escapeXml(modeLabel)}</text>
10991098
<svg x="0" y="${padT}" width="${MAP_WIDTH}" height="${MAP_HEIGHT}" viewBox="0 0 ${MAP_WIDTH} ${MAP_HEIGHT}">
11001099
${mapContent}
11011100
</svg>
@@ -1128,7 +1127,7 @@ <h2>World map</h2>
11281127
if (!svg) return;
11291128
const url = URL.createObjectURL(new Blob([svg], { type: "image/svg+xml;charset=utf-8" }));
11301129
const img = new Image();
1131-
const padT = 48;
1130+
const padT = 12;
11321131
const padB = 72;
11331132
const totalH = MAP_HEIGHT + padT + padB;
11341133
const scale = 2;
@@ -1161,7 +1160,8 @@ <h2>World map</h2>
11611160
return;
11621161
}
11631162
d3.json(DATA.geojson_href).then(geo => {
1164-
worldFeatures = geo.features || [];
1163+
worldFeatures = mapFeaturesWithoutAntarctica(geo.features);
1164+
fitMapProjection(worldFeatures);
11651165
setMapExportEnabled(true);
11661166
renderWorldMap();
11671167
}).catch(err => {

tests/runs/test_index_map.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def test_export_world_geojson_includes_france(tmp_path: Path):
6363
export_world_geojson(dest, simplify=0.2)
6464
text = dest.read_text(encoding="utf-8")
6565
assert '"ISO_A2": "FR"' in text or '"ISO_A2":"FR"' in text
66+
assert '"ISO_A2": "AQ"' not in text and '"ISO_A2":"AQ"' not in text
6667

6768
import geopandas as gpd
6869

0 commit comments

Comments
 (0)