ai-lab.org
PopDrift

PopDrift ができるまで — データ可視化 3本目を 人口ピラミッド で開く

占い 3本目 (maya-cast) に続く ラボ 33本目で データ可視化 thesis 3本目 (wiki-orbit 知識グラフ / astro-cast 太陽系 / pop-drift 人口統計)。 6 ヶ国 × 5 年代 × 21 階級 × 2 性別 の stylized data + 平均年齢 / 高齢化指数 / 生産年齢人口比率 自動算出 + 2 国比較を 昭和の統計年鑑 + Risograph 二色刷り motif (cream paper + cobalt blue + warm red) で組んだ設計記録。

·decision改善·stage公開中

PopDrift ができるまで — データ可視化 3本目を 人口ピラミッド で開く

PopDrift は、 ブラウザだけで動く無料 人口ピラミッド 時系列ビジュアライザー。 6 ヶ国 × 5 年代 × 21 階級 × 2 性別 を 「リソグラフ 二色刷り」 で表示。 ラボ 33本目、 データ可視化 thesis 3本目 (WikiOrbit 知識グラフ / AstroCast 太陽系 / PopDrift 人口統計)。

なぜこの形にしたか

直近 5本 (maya-cast / type-rush / frac-cast / patch-pad / doodle-drop) にデータ可視化ゼロ → §3.1 OK。 thesis 分布で データ可視化 (2) が最も薄く、 補強優先。

候補比較:

  • 人口ピラミッド (採用) — SEO 強 「人口ピラミッド 日本 / 高齢化 グラフ / 世界人口 2100」
  • 為替 30 年 — SEO 強だが API 依存 (FRED / ECB) で運用リスク
  • 都道府県 GDP 比較 — SEO ニッチ
  • 気温 100 年 (温暖化) — SEO 中、 政治化リスク
  • 企業ロゴ進化 — wow だが SEO 弱

選んだ理由:

  • 「日本 人口 推移」 「少子高齢化」 「世界人口 2100」 は通年安定 SEO
  • 時系列アニメ が wow ポイント (1950 ピラミッド → 2100 つぼ型 で 形状が morph)
  • 2 国比較モード で 「日本 vs ナイジェリア」 等の極端な対比を見せられる
  • データ取得は UN WPP 2022 から手動入力で 完結 (API 依存なし)
  • visual 「昭和の統計年鑑 + Risograph 二色刷り」 が 既存 32 本柱と完全別軸

visual direction — §6.1 Visual Audit 18本目の適用

直近 5本の visual を書き出す:

maya-cast    — earth red + jade + obsidian + gold + bone (マヤ古代壁画)
type-rush    — cream paper + carbon ribbon + brass key + ribbon red (古いタイプライター)
frac-cast    — ivory paper + sepia + brass corner + crimson (17世紀 数学者ノート)
patch-pad    — walnut + cream + brass + chrome (70s モジュラー シンセ)
doodle-drop  — blackboard green + chalk pastels (学校黒板)

題材 「人口統計 / 統計 / データ」 → motif 候補:

  • 昭和の統計年鑑 + Risograph 二色刷り (cream paper + cobalt + warm red + ink) ← 採用
  • FT / Economist 風 データジャーナリズム (serif + baby blue + warm red) — wiki-orbit と被るリスク
  • NASA HUD 風 telemetry (dark + cyan) — astro-cast と被る
  • 教科書 illustrated (sepia + bone) — frac-cast と被る

採用 3 要素:

  • palette: cream paper #f0e8d4 + cobalt blue #1f3a8a (女性) + warm red #c8302c (男性) + ink black #1a1612 + sage green #5a8b6e + paper noise
    • 男性 = 赤 / 女性 = 青 は人口ピラミッドの世界標準色 (UN / 統計局 と一致)
    • cream paper は side-tax / type-rush / frac-cast と似ているが palette: cobalt + warm red 二色刷りは唯一の組合せ
  • motif: 昭和の統計年鑑 + Risograph 二色刷り (paper noise dots + わずかなインク ズレ風 box-shadow + column ruler + 細罫線 + 数字 stamp + 4px ink shadow が紙の重みを表現)
  • typography: Space Grotesk 800 (data display) + JetBrains Mono (numerics、 tabular-nums) + Noto Sans JP body + 漢数字ステップ (壱/弐/参)

技術スタック

Stylized demographic data 構造

buildSlice(shape: number[], sexRatio = 0.485): PyramidSlice {
  const sum = shape.reduce((a, b) => a + b, 0)
  const normalized = shape.map((v) => (v / sum) * 100)
  const male: number[] = []
  const female: number[] = []
  for (let i = 0; i < 21; i++) {
    const ageRatio = i / 20
    const mFrac = sexRatio - ageRatio * 0.18  // 高齢域ほど女性多 (longevity gap)
    male.push(normalized[i] * Math.max(0.2, mFrac))
    female.push(normalized[i] * (1 - Math.max(0.2, mFrac)))
  }
  return { male, female }
}

21 階級 (0-4, 5-9, ..., 95-99, 100+) の概形を shape 配列で記述し、 合計が 100% になるよう正規化。 性別比は 「高齢域ほど女性比率が上がる (寿命差)」 をモデル化、 linear に 48.5% → 30% (95+) へ。

6 ヶ国 × 5 年代の典型パターン

  • 日本: 1950 ピラミッド型 → 2024 つぼ型 (高齢化) → 2100 縮小型
  • アメリカ: 1950 ピラミッド型 → 移民で安定 → 2100 緩やかな縮小
  • 中国: 1950 ピラミッド → 一人っ子政策 (1980-) で 30 代に凹み → 2100 急縮小
  • インド: 1950-2024 拡大ピラミッド → 2050 中国を抜く → 2100 安定
  • ドイツ: 1950 戦争で凹み → 2024 高齢化 → 2100 緩やか縮小
  • ナイジェリア: 1950 急成長 → 2024 巨大ピラミッド → 2100 世界 1 億人超でも若年層維持

平均年齢 / 高齢化指数 計算

function meanAge(slice: PyramidSlice): number {
  let sum = 0, total = 0
  for (let i = 0; i < 21; i++) {
    const center = i === 20 ? 102 : i * 5 + 2  // 階級中央年齢
    const total_i = slice.male[i] + slice.female[i]
    sum += center * total_i
    total += total_i
  }
  return sum / total
}

function agingIndex(slice: PyramidSlice): number {
  let young = sum(0-14歳 階級)
  let old = sum(65歳以上 階級)
  return old / young
}

平均年齢 = 重み付き平均、 高齢化指数 = (65+) / (0-14)。 1.0 を超えると 「高齢者が子供より多い」 状態。 日本 2024 ≈ 3.0、 ナイジェリア 2024 ≈ 0.05。

横棒チャート (CSS Grid 3 列)

<div className={styles.row}>
  <div className={styles.barLeft}>
    <span className={styles.barMale} style={{ width: `${(m / maxBucket) * 100}%` }} />
  </div>
  <div className={styles.ageLabel}>{AGE_BUCKETS[rev]}</div>
  <div className={styles.barRight}>
    <span className={styles.barFemale} style={{ width: `${(f / maxBucket) * 100}%` }} />
  </div>
</div>

grid-template-columns: 1fr 56px 1fr で 左右対称、 中央に年齢ラベル。 高い階級ほど上に来るよう ilength - 1 - i で逆順表示。 横棒は transition: width 0.6s cubic-bezier で 年代切替時に滑らかに morph。

Risograph 二色刷り 「微ズレ」 表現

.barMale {
  background: var(--pd-red);
  box-shadow: -1px 0 0 rgba(31, 58, 138, 0.12);  /* cobalt の ズレ */
}
.barFemale {
  background: var(--pd-cobalt);
  box-shadow: 1px 0 0 rgba(200, 48, 44, 0.12);  /* red の ズレ */
}

box-shadow で 1px の二色ぶれを再現、 「リソグラフ印刷の 版ズレ」 風。 paper の noise は 0.5px の radial-gradient ドット で 「ザラ紙質感」 を作る。

比較モードの dashed line 重ね描画

{compareSlice && (
  <span
    className={styles.barMaleCompare}
    style={{ width: `${(cm / maxBucket) * 100}%` }}
  />
)}
.barMaleCompare {
  position: absolute;
  background: transparent;
  border-top: 2px dashed var(--pd-red-bright);
  height: 0;
  top: 50%;
}

メイン国 = 塗りつぶし bar、 比較国 = 同じ位置に dashed line で 重ねる。 「日本 2024 vs ナイジェリア 2024」 で 「ピラミッド型 vs つぼ型」 の極端な対比が一目で見える。

やっていない / これからの IMPROVE

  • 完全な UN WPP 2022 データ取込 (現在は stylized data、 精度 ±5%、 v2 で 全 200+ ヶ国 × 1950-2100 の完全データ)
  • 年代スライダー (現在は 5 タイムスタンプ、 v2 で 1950-2100 の 1 年単位連続スライダー + RAF アニメ)
  • 国 検索 / 地域フィルタ (現在は 6 ヶ国、 v2 で 200+ ヶ国 + アジア / 欧州 / アフリカ フィルタ)
  • 人口総数 推移グラフ (時系列 line chart で 国ごとの 1950-2100 推移)
  • 合計特殊出生率 / 平均寿命 などの 補助指標
  • PNG エクスポート (高解像度書き出し)
  • 共有 URL で 国 + 年 + 比較 を base64 シリアライズ
  • テキスト要約 (AI で 「この国の特徴」 自動生成)

次の SHIP は何 thesis に振るか

Thesis Audit:

pop-drift    — データ可視化 (3本目)
maya-cast    — 占い (3本目)
type-rush    — 学習 (3本目)
frac-cast    — シミュレーター (3本目)
patch-pad    — ジェネレーター (3本目)

直近 5本で 5 thesis 別 (連続なし)。 §3.1 完璧。 8 thesis 枠のうち 7 つを 3 本以上ずつ充足、 残り server-side AI のみ。 次の候補:

  • 計算ツール 5本目 (育休給付金 / 退職金 / 国保 / 年金)
  • ジェネレーター 4本目 (SVG モノグラム / grad ジェネ / glitch)
  • データ可視化 4本目 (為替 30 年 / 都道府県 GDP)
  • 学習 4本目 (暗算 / 漢字 / 都道府県)
  • 占い 4本目 (西洋占星術 / 易経 / 動物占い オリジナル)
  • server-side AI (ユーザー許可待ち)

[ ./next_action ]

読んだら、 PopDrift を実際に動かす。

この開発ログは PopDrift をどう作ったかの記録です。 読み終わったらそのままサービス本体へ戻って、 実物で価値を確かめてください。

[ ./related_logs ]

関連する開発ログ

all logs →
GlyphForge

GlyphForge ができるまで — ジェネレーター 4本目を モノグラム / SVG ロゴ で開く

学習 4本目 (soroban-rush) に続く ラボ 35本目で ジェネレーター thesis 4本目 (hue-deck 色 / type-forge 字 / patch-pad 音 / glyph-forge 紋章、 「色 / 字 / 音 / 紋章」 4 本柱完成)。 純 JS で 8 アートスタイル SVG path 動的生成 + 6 パレット + SVG / PNG ダウンロード を letterpress 活字工房 motif (ink + 朱赤 + 生成り + brass plate + emerald) で組んだ設計記録。

read log →
SorobanRush

SorobanRush ができるまで — 学習 4本目を 暗算 / そろばん ドリル で開く

データ可視化 3本目 (pop-drift) に続く ラボ 34本目で インタラクティブ学習 thesis 4本目 (tone-quest 耳 / atlas-quest 目 / type-rush 指 / soroban-rush 算、 4 感覚学習完成)。 純 JS 問題生成 + 1-1-4 そろばん SVG 可視化 + フラッシュ暗算 setTimeout 連鎖を 寺子屋 motif (warm brown frame + 玉青藍 + 玉朱 + 和紙 cream + 金箔) で組んだ設計記録。

read log →
MayaCast

MayaCast ができるまで — 占い・診断 3本目を マヤ暦 KIN で開く

学習 3本目 (type-rush) に続く ラボ 32本目で 占い・診断 thesis 3本目 (fate-num 数秘 / arcana-flip タロット に続く、 「数 / カード / 暦」 3 文化軸完成)。 純 JS でグレゴリオ暦 → ユリウス日 → Tzolkin 260 変換 + Feb 29 スキップ補正 を組み、 マヤ古代壁画 motif (earth red + jade + obsidian + gold + bone) でビジュアル化した設計記録。

read log →
TypeRush

TypeRush ができるまで — インタラクティブ学習 3本目を タイピング道場 で開く

シミュレーター 3本目 (frac-cast) に続く ラボ 31本目で インタラクティブ学習 thesis 3本目 (tone-quest / atlas-quest に続く)。 純 JS + WebAudio で 5 モード × 3 レベル + WPM + QWERTY ミス ヒートマップ を組み、 古いタイプライター motif (cream paper + carbon ribbon + brass key + ribbon red) でビジュアル化した設計記録。

read log →
FracCast

FracCast ができるまで — シミュレーター 3本目を WebGL2 フラクタル で開く

ジェネレーター 3本目 (patch-pad) に続く ラボ 30本目で シミュレーター thesis 3本目 (pile-park / doodle-drop に続く)。 WebGL2 fragment shader で escape-time iteration を GPU per-pixel 並列実行、 17世紀 数学者ノートブック motif (ivory + sepia + brass + crimson) で組んだ設計記録。

read log →
PatchPad

PatchPad ができるまで — ジェネレーター 3本目を ブラウザ モジュラー シンセ で開く

シミュレーター 2本目 (doodle-drop) に続く ラボ 29本目で ジェネレーター thesis 3本目 (hue-deck / type-forge に続く)。 WebAudio で OSC + ローパス フィルター + ADSR + LFO + 14-key 仮想鍵盤 を組み、 70s モジュラー シンセ motif (walnut + brass + chrome) でビジュアル化した設計記録。

read log →