人口分布マップチャートライブラリ比較
地理的な位置情報と人口データをバブルマップで可視化し、3つのアプローチを比較
このページについて: 地理的な座標(緯度・経度)を軸にバブルを配置する「地図型バブル表現」を扱います。 任意のXY軸で3変数を比較する汎用的なバブルチャートは バブルチャート(Bubble Chart) を参照してください。
📊 使用しているサンプルデータ
日本の8地方区分+沖縄の人口データを使用しています。バブルのサイズは人口に比例し、位置は各地方の代表的な経緯度に基づいています。
[
{
"region": "北海道",
"population": 522,
"density": 63,
"x": 143.2,
"y": 43.1
},
{
"region": "東北",
"population": 862,
"density": 129,
"x": 140.3,
"y": 39.5
},
{
"region": "関東",
"population": 4349,
"density": 1348,
"x": 139.7,
"y": 36
},
{
"region": "中部",
"population": 2128,
"density": 314,
"x": 137,
"y": 36.2
},
{
"region": "近畿",
"population": 2229,
"density": 667,
"x": 135.5,
"y": 34.7
},
{
"region": "中国",
"population": 719,
"density": 227,
"x": 132.5,
"y": 34.5
},
{
"region": "四国",
"population": 372,
"density": 198,
"x": 133.5,
"y": 33.8
},
{
"region": "九州",
"population": 1282,
"density": 304,
"x": 131,
"y": 33
},
{
"region": "沖縄",
"population": 146,
"density": 641,
"x": 127.7,
"y": 26.3
}
]1. カスタム React 実装(SVG バブルマップ)
React + SVGでカスタム実装したバブルマップ。地理的な配置と人口密度による色分けで直感的な人口分布を表現。
バブルのサイズ = 人口(万人)、色 = 人口密度(人/km²)
'use client';
// React + SVGのみでバブルマップを実装(外部ライブラリ不要)
const sampleData = [
{ region: '北海道', population: 522, density: 63, x: 143.2, y: 43.1 },
{ region: '東北', population: 862, density: 129, x: 140.3, y: 39.5 },
{ region: '関東', population: 4349, density: 1348, x: 139.7, y: 36.0 },
{ region: '中部', population: 2128, density: 314, x: 137.0, y: 36.2 },
{ region: '近畿', population: 2229, density: 667, x: 135.5, y: 34.7 },
{ region: '中国', population: 719, density: 227, x: 132.5, y: 34.5 },
{ region: '四国', population: 372, density: 198, x: 133.5, y: 33.8 },
{ region: '九州', population: 1282, density: 304, x: 131.0, y: 33.0 },
{ region: '沖縄', population: 146, density: 641, x: 127.7, y: 26.3 },
];
const maxPopulation = Math.max(...sampleData.map((d) => d.population));
function mapX(lon: number) { return ((lon - 126) / (146 - 126)) * 440 + 40; }
function mapY(lat: number) { return 400 - ((lat - 25) / (45 - 25)) * 360 + 20; }
function getRadius(pop: number) { return Math.sqrt(pop / maxPopulation) * 32 + 4; }
function getColor(density: number) {
if (density > 1000) return 'rgba(239,68,68,0.75)';
if (density > 500) return 'rgba(249,115,22,0.7)';
if (density > 200) return 'rgba(234,179,8,0.65)';
if (density > 100) return 'rgba(16,185,129,0.65)';
return 'rgba(59,130,246,0.65)';
}
export function CustomSvgBubbleMap() {
return (
<svg viewBox="0 0 520 420" className="w-full max-w-lg">
{sampleData.map((d) => (
<circle key={d.region}
cx={mapX(d.x)} cy={mapY(d.y)}
r={getRadius(d.population)}
fill={getColor(d.density)}
stroke="white" strokeWidth={1}>
<title>{d.region} 人口:{d.population}万人 密度:{d.density}人/km²</title>
</circle>
))}
{sampleData.map((d) => (
<text key={d.region + '-label'}
x={mapX(d.x)} y={mapY(d.y) + getRadius(d.population) + 12}
textAnchor="middle" fontSize={9} fill="#374151">{d.region}</text>
))}
</svg>
);
}🤖 AIプロンプトテンプレート
React + Tailwind CSSで、カスタムReact実装(SVGバブルマップ)を使った人口分布マップを実装してください。 - 使用ライブラリ: 外部ライブラリなし。React + SVGのみで経緯度→SVG座標変換・バブルサイズ計算・色分けをすべて自前実装すること - サンプルデータ: 日本の地域別人口分布9地域(緯度・経度・人口・人口密度)を用意すること - インタラクティブ: SVG の title 要素を使って各バブルにホバーツールチップを実装すること - バブルサイズ: Math.sqrt(population / maxPopulation) * スケール係数 + 最小半径 でサイズを計算すること - 地図表示: 日本列島のGeoJSONアウトライン座標をSVGの path 要素で背景描画すること - スタイリング: 人口密度に応じて5段階の色を設定し、バブルサイズと色の二重エンコーディングで情報密度を高めること
⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
2. Nivo (@nivo/scatterplot)
ScatterPlotの動的ノードサイズ機能でバブルマップを実現。東日本・西日本のグループ分けで地域の対比を表現。
'use client';
import { ResponsiveScatterPlot } from '@nivo/scatterplot';
const data = [
{
id: '東日本',
data: [
{ x: 143.2, y: 43.1, population: 522, region: '北海道', density: 63 },
{ x: 140.3, y: 39.5, population: 862, region: '東北', density: 129 },
{ x: 139.7, y: 36.0, population: 4349, region: '関東', density: 1348 },
{ x: 137.0, y: 36.2, population: 2128, region: '中部', density: 314 },
],
},
{
id: '西日本',
data: [
{ x: 135.5, y: 34.7, population: 2229, region: '近畿', density: 667 },
{ x: 132.5, y: 34.5, population: 719, region: '中国', density: 227 },
{ x: 133.5, y: 33.8, population: 372, region: '四国', density: 198 },
{ x: 131.0, y: 33.0, population: 1282, region: '九州', density: 304 },
{ x: 127.7, y: 26.3, population: 146, region: '沖縄', density: 641 },
],
},
];
const maxPopulation = 4349;
export function NivoPopulationMap() {
return (
<div style={{ height: 400 }}>
<ResponsiveScatterPlot
data={data}
margin={{ top: 20, right: 120, bottom: 60, left: 70 }}
xScale={{ type: 'linear', min: 125, max: 146 }}
yScale={{ type: 'linear', min: 24, max: 46 }}
nodeSize={(datum: any) => Math.sqrt(datum.data.population / maxPopulation) * 32 + 4}
axisBottom={{ legend: '経度', legendPosition: 'middle', legendOffset: 46 }}
axisLeft={{ legend: '緯度', legendPosition: 'middle', legendOffset: -56 }}
colors={['#3b82f6', '#10b981']}
useMesh={true}
tooltip={({ node }: any) => (
<div style={{ background: 'white', padding: '8px', border: '1px solid #ccc', borderRadius: 4 }}>
<strong>{node.data.region}</strong><br />
人口: {node.data.population}万人<br />
密度: {node.data.density}人/km²
</div>
)}
/>
</div>
);
}🤖 AIプロンプトテンプレート
React + Tailwind CSSで、Nivo(@nivo/scatterplot)を使った人口分布バブルマップを実装してください。
- 使用ライブラリ: @nivo/scatterplot の ResponsiveScatterPlot コンポーネント
- サンプルデータ: 日本の地域別人口分布9地域を東日本・西日本の2グループに分けた { id, data: [{ x, y, population, region, density }] } 形式で用意すること
- インタラクティブ: tooltip プロパティでカスタムツールチップを実装し、地域名・人口・人口密度を表示すること
- バブルサイズ: nodeSize 関数で population に応じた動的なノードサイズを計算すること
- 地図表示: layers プロパティにカスタムレイヤーを追加し、xScale・yScale を使って日本列島アウトラインをSVGで描画すること
- スタイリング: useMesh={true} でメッシュベースのインタラクションを有効化し、東日本・西日本を色分けすること⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
3. Chart.js (Bubble Chart)
Chart.jsのネイティブBubbleチャートを活用。Canvas APIによる高パフォーマンスなレンダリングで大量データも安定。
rプロパティでバブルサイズを直接指定。Canvas APIを活用するためデータポイントが増えてもパフォーマンスが安定。'use client';
import { Bubble } from 'react-chartjs-2';
import { Chart as ChartJS, LinearScale, PointElement, Tooltip, Legend } from 'chart.js';
ChartJS.register(LinearScale, PointElement, Tooltip, Legend);
const maxPopulation = 4349;
function r(pop: number) { return Math.sqrt(pop / maxPopulation) * 20 + 3; }
const data = {
datasets: [
{
label: '東日本',
data: [
{ x: 143.2, y: 43.1, r: r(522), region: '北海道', population: 522 },
{ x: 140.3, y: 39.5, r: r(862), region: '東北', population: 862 },
{ x: 139.7, y: 36.0, r: r(4349), region: '関東', population: 4349 },
{ x: 137.0, y: 36.2, r: r(2128), region: '中部', population: 2128 },
],
backgroundColor: 'rgba(59,130,246,0.5)',
},
{
label: '西日本',
data: [
{ x: 135.5, y: 34.7, r: r(2229), region: '近畿', population: 2229 },
{ x: 132.5, y: 34.5, r: r(719), region: '中国', population: 719 },
{ x: 133.5, y: 33.8, r: r(372), region: '四国', population: 372 },
{ x: 131.0, y: 33.0, r: r(1282), region: '九州', population: 1282 },
{ x: 127.7, y: 26.3, r: r(146), region: '沖縄', population: 146 },
],
backgroundColor: 'rgba(16,185,129,0.5)',
},
],
};
export function ChartJSPopulationMap() {
return (
<Bubble data={data} options={{
responsive: true,
maintainAspectRatio: false,
plugins: {
tooltip: {
callbacks: {
label: (ctx: any) => {
const d = ctx.raw;
return [`${d.region}`, `人口: ${d.population}万人`];
},
},
},
},
scales: {
x: { min: 125, max: 147, title: { display: true, text: '経度' } },
y: { min: 24, max: 46, title: { display: true, text: '緯度' } },
},
}} height={400} />
);
}🤖 AIプロンプトテンプレート
React + Tailwind CSSで、Chart.js(react-chartjs-2 Bubble)を使った人口分布バブルマップを実装してください。
- 使用ライブラリ: chart.js と react-chartjs-2 の Bubble コンポーネント。LinearScale・PointElement・Tooltip・Legend を ChartJS.register で登録すること
- サンプルデータ: 日本の地域別人口分布9地域を東日本・西日本に分け、{ x: 経度, y: 緯度, r: バブル半径, region, population, density } 形式で用意すること
- インタラクティブ: options.plugins.tooltip.callbacks.label でカスタムツールチップを実装し、地域名・人口・人口密度を表示すること
- バブルサイズ: r プロパティに Math.sqrt(population / maxPopulation) * スケール係数 を設定すること
- 地図表示: Chart.jsプラグイン(beforeDatasetsDraw)でCanvas APIを使って日本列島アウトラインを背景描画すること
- スタイリング: responsive: true・maintainAspectRatio: false を設定し、東日本・西日本をそれぞれ別色で塗り分けること⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
4. Recharts (ScatterChart + ZAxis)
ScatterChartのZAxisを活用してバブルサイズを制御。Reactの宣言的APIで直感的なコード記述が可能。
'use client';
import {
ScatterChart, Scatter, XAxis, YAxis, ZAxis,
Tooltip, Legend, ResponsiveContainer,
} from 'recharts';
const eastJapan = [
{ x: 143.2, y: 43.1, population: 522, region: '北海道', density: 63 },
{ x: 140.3, y: 39.5, population: 862, region: '東北', density: 129 },
{ x: 139.7, y: 36.0, population: 4349, region: '関東', density: 1348 },
{ x: 137.0, y: 36.2, population: 2128, region: '中部', density: 314 },
];
const westJapan = [
{ x: 135.5, y: 34.7, population: 2229, region: '近畿', density: 667 },
{ x: 132.5, y: 34.5, population: 719, region: '中国', density: 227 },
{ x: 133.5, y: 33.8, population: 372, region: '四国', density: 198 },
{ x: 131.0, y: 33.0, population: 1282, region: '九州', density: 304 },
{ x: 127.7, y: 26.3, population: 146, region: '沖縄', density: 641 },
];
export function RechartsPopulationMap() {
return (
<ResponsiveContainer width="100%" height={400}>
<ScatterChart margin={{ top: 20, right: 20, bottom: 40, left: 40 }}>
<XAxis type="number" dataKey="x" name="経度" domain={[125, 147]}
label={{ value: '経度', position: 'insideBottom', offset: -5 }} />
<YAxis type="number" dataKey="y" name="緯度" domain={[24, 46]}
label={{ value: '緯度', angle: -90, position: 'insideLeft' }} />
<ZAxis type="number" dataKey="population" range={[50, 2000]} />
<Tooltip cursor={{ strokeDasharray: '3 3' }} />
<Legend verticalAlign="top" />
<Scatter name="東日本" data={eastJapan} fill="#3b82f6" fillOpacity={0.6} />
<Scatter name="西日本" data={westJapan} fill="#10b981" fillOpacity={0.6} />
</ScatterChart>
</ResponsiveContainer>
);
}🤖 AIプロンプトテンプレート
React + Tailwind CSSで、Recharts(ScatterChart + ZAxis)を使った人口分布バブルマップを実装してください。
- 使用ライブラリ: recharts の ScatterChart・Scatter・XAxis・YAxis・ZAxis・CartesianGrid・Tooltip・Legend・ResponsiveContainer・Customized コンポーネント
- サンプルデータ: 日本の地域別人口分布9地域を東日本・西日本に分け、{ x: 経度, y: 緯度, population, density, region } 形式で用意すること
- インタラクティブ: Tooltip の content プロパティにカスタムコンポーネントを渡し、地域名・人口・人口密度を表示すること
- バブルサイズ: ZAxis の dataKey="population"・range={[最小面積, 最大面積]} でバブルサイズを宣言的に制御すること
- 地図表示: Customized コンポーネントで xAxisMap・yAxisMap のスケール関数を取得し、日本列島アウトラインをSVGで背景描画すること
- スタイリング: 東日本・西日本を Scatter コンポーネントで分けて異なる fill 色を設定すること⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
ライブラリ比較
| アプローチ | レンダリング | バブルサイズ制御 | 地図的表現 | おすすめ用途 |
|---|---|---|---|---|
| カスタム React (SVG) | SVG | ◎(完全自由) | ◎ | 独自デザインのマップ |
| Nivo | SVG | ◎(動的nodeSize) | ◯ | 分析ダッシュボード |
| Chart.js | Canvas | ◯(rプロパティ) | ◯ | 大量データ・高速描画 |
| Recharts | SVG | ◯(ZAxis) | ◯ | Reactプロジェクト全般 |
選択のポイント
- •カスタム React (SVG): 地図的なレイアウトや密度による色分けなど、独自のビジュアル表現が必要な場合。依存ゼロでバンドルサイズへの影響もなし。
- •Nivo: 動的nodeSize設定で手軽にバブルマップを実現。メッシュベースのインタラクションとカスタムツールチップで高い操作性。
- •Chart.js: ネイティブBubbleチャートで簡潔な実装。Canvas描画により数百のデータポイントでもパフォーマンスが安定。
- •Recharts: ZAxisによるバブルサイズ制御が宣言的。既にRechartsを使用しているプロジェクトへの統合が容易。