data-visualization について
inference.sh CLIでデータを可視化するスキルです。データを明確なチャートにしたい人向けに、チャート選択やデザイン、ストーリー構成の指針と実行例を提供します。
主な機能
- 01データ関係に応じたチャート選択
- 02軸と配色のデザイン指針
- 03タイトル、ラベル、注釈のガイド
- 04Matplotlibによるチャート生成例
- 05beltでのPythonコード実行
活用シーン
- 01カテゴリ間のデータ比較
- 02時系列の変化表示
- 03KPIカードやヒートマップの作成
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ magentosh/ superpowers --skill data-visualizationインストール後、Claude Code で/data-visualizationを入力して読み込まれたか確認します。
詳細
belt CLI スキルをインストールする:
npx skills add belt-sh/cli
データ可視化
inference.sh CLI を使って、明確で効果的なデータ可視化を作成します。
クイックスタート
inference.sh CLI(
belt)が必要です。インストール手順
belt login
# Generate a chart with Python
belt app run infsh/python-executor --input '{
"code": "import matplotlib.pyplot as plt\nimport matplotlib\nmatplotlib.use(\"Agg\")\n\nmonths = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\"]\nrevenue = [42, 48, 55, 61, 72, 89]\n\nfig, ax = plt.subplots(figsize=(10, 6))\nax.bar(months, revenue, color=\"#3b82f6\", width=0.6)\nax.set_ylabel(\"Revenue ($K)\")\nax.set_title(\"Monthly Revenue Growth\", fontweight=\"bold\")\nfor i, v in enumerate(revenue):\n ax.text(i, v + 1, f\"${v}K\", ha=\"center\", fontweight=\"bold\")\nplt.tight_layout()\nplt.savefig(\"revenue.png\", dpi=150)\nprint(\"Saved\")"
}'
グラフ選択ガイド
データに適したグラフ
| データの関係性 | 最適なグラフ | 使用しないグラフ |
|---|---|---|
| 時間による変化 | 折れ線グラフ | 円グラフ |
| カテゴリーの比較 | 棒グラフ(カテゴリーが多い場合は横棒グラフ) | 折れ線グラフ |
| 全体に占める割合 | 積み上げ棒グラフ、ツリーマップ | 円グラフ(議論の余地はありますが、棒グラフのほうが常に明確です) |
| 分布 | ヒストグラム、箱ひげ図 | 棒グラフ |
| 相関 | 散布図 | 棒グラフ |
| 順位 | 横棒グラフ | 縦棒グラフ、円グラフ |
| 地理情報 | コロプレスマップ | 棒グラフ |
| 時間による構成の変化 | 積み上げ面グラフ | 複数の円グラフ |
| 単一の指標 | 大きな数値(KPI カード) | あらゆるグラフ(過剰です) |
| 流れ/プロセス | サンキーダイアグラム | 棒グラフ |
円グラフの問題点
円グラフは、ほとんどの場合、適切な選択ではありません。
❌ Pie chart problems:
- Hard to compare similar-sized slices
- Can't show more than 5-6 categories
- 3D pie charts are always wrong
- Impossible to read exact values
✅ Use instead:
- Horizontal bar chart (easy comparison)
- Stacked bar (part of whole)
- Treemap (hierarchical parts)
- Just a table (if precision matters)
デザインルール
軸
| ルール | 理由 |
|---|---|
| Y 軸は常に 0 から始める(棒グラフ) | 誤解を招く視覚表現を防ぎます |
| 折れ線グラフは 0 より上から始めてもかまいません | 絶対値ではなく変化を示す場合 |
| 両方の軸にラベルを付ける | 読み手に単位を推測させないため |
| 不要なグリッド線を取り除く | 視覚的なノイズを減らします |
| ラベルは横向きにする | 縦書きのテキストは読みにくいため |
| 棒グラフは値の順に並べる | 理由がない限り、アルファベット順は使いません |
色
| 原則 | 適用方法 |
|---|---|
| グラフあたり最大 5~7 色 | 色が多すぎると読みにくくなります |
| 1 つの要素を強調する | それ以外をグレーにし、注目箇所に色を付けます |
| 量には連続色 | 少ない値から多い値へ、明るい色から暗い色へ |
| 正負には発散色 | 赤 ← 中間色 → 青 |
| グループにはカテゴリー色 | 明度をそろえ、色相をはっきり分けます |
| 色覚多様性に配慮する | 赤と緑だけの組み合わせを避け、形やラベルも追加します |
| 意味を一貫させる | 青が売上を表すなら、どこでも青にします |
使いやすいカラーパレット
# Sequential (low to high)
sequential = ["#eff6ff", "#bfdbfe", "#60a5fa", "#2563eb", "#1d4ed8"]
# Diverging (negative to positive)
diverging = ["#ef4444", "#f87171", "#d1d5db", "#34d399", "#10b981"]
# Categorical (distinct groups)
categorical = ["#3b82f6", "#f59e0b", "#10b981", "#8b5cf6", "#ef4444"]
# Colorblind-safe
cb_safe = ["#0077BB", "#33BBEE", "#009988", "#EE7733", "#CC3311"]
テキストとラベル
| 要素 | ルール |
|---|---|
| タイトル | データの種類ではなく、洞察を示します。「第 2 四半期の売上グラフ」ではなく、「第 2 四半期に売上が 2 倍に」 |
| 注釈 | 重要なデータポイントをグラフ上に直接示します |
| 凡例 | できるだけ使わず、グラフの線や棒に直接ラベルを付けます |
| フォントサイズ | 最小 12px、プレゼンテーションでは 14px 以上 |
| 数値の書式 | 大きな数値には K、M、B を使います(42,000 ではなく 42K) |
| データラベル | 正確な値が重要な場合は、棒や点に追加します |
グラフのレシピ
折れ線グラフ(時系列)
belt app run infsh/python-executor --input '{
"code": "import matplotlib.pyplot as plt\nimport matplotlib\nmatplotlib.use(\"Agg\")\n\nfig, ax = plt.subplots(figsize=(12, 6))\nfig.patch.set_facecolor(\"white\")\n\nmonths = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\nthis_year = [120, 135, 148, 162, 178, 195, 210, 228, 245, 268, 290, 320]\nlast_year = [95, 102, 108, 115, 122, 130, 138, 145, 155, 165, 178, 190]\n\nax.plot(months, this_year, color=\"#3b82f6\", linewidth=2.5, marker=\"o\", markersize=6, label=\"2024\")\nax.plot(months, last_year, color=\"#94a3b8\", linewidth=2, linestyle=\"--\", label=\"2023\")\nax.fill_between(range(len(months)), last_year, this_year, alpha=0.1, color=\"#3b82f6\")\n\nax.annotate(\"$320K\", xy=(11, 320), fontsize=14, fontweight=\"bold\", color=\"#3b82f6\")\nax.annotate(\"$190K\", xy=(11, 190), fontsize=12, color=\"#94a3b8\")\n\nax.set_ylabel(\"Revenue ($K)\", fontsize=12)\nax.set_title(\"Revenue grew 68% year-over-year\", fontsize=16, fontweight=\"bold\")\nax.legend(fontsize=12)\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nax.grid(axis=\"y\", alpha=0.3)\nplt.tight_layout()\nplt.savefig(\"line-chart.png\", dpi=150)\nprint(\"Saved\")"
}'
横棒グラフ(比較)
belt app run infsh/python-executor --input '{
"code": "import matplotlib.pyplot as plt\nimport matplotlib\nmatplotlib.use(\"Agg\")\n\nfig, ax = plt.subplots(figsize=(10, 6))\n\ncategories = [\"Email\", \"Social\", \"SEO\", \"Paid Ads\", \"Referral\", \"Direct\"]\nvalues = [12, 18, 35, 22, 8, 5]\ncolors = [\"#94a3b8\"] * len(values)\ncolors[2] = \"#3b82f6\" # Highlight the winner\n\n# Sort by value\nsorted_pairs = sorted(zip(values, categories, colors))\nvalues, categories, colors = zip(*sorted_pairs)\n\nax.barh(categories, values, color=colors, height=0.6)\nfor i, v in enumerate(values):\n ax.text(v + 0.5, i, f\"{v}%\", va=\"center\", fontsize=12, fontweight=\"bold\")\n\nax.set_xlabel(\"% of Total Traffic\", fontsize=12)\nax.set_title(\"SEO drives the most traffic\", fontsize=16, fontweight=\"bold\")\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nplt.tight_layout()\nplt.savefig(\"bar-chart.png\", dpi=150)\nprint(\"Saved\")"
}'
KPI/大きな数値のカード
belt app run infsh/html-to-image --input '{
"html": "<div style=\"display:flex;gap:20px;padding:20px;background:white;font-family:system-ui\"><div style=\"background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:24px;width:200px;text-align:center\"><p style=\"color:#64748b;font-size:14px;margin:0\">Monthly Revenue</p><p style=\"font-size:48px;font-weight:900;margin:8px 0;color:#1e293b\">$89K</p><p style=\"color:#22c55e;font-size:14px;margin:0\">↑ 23% vs last month</p></div><div style=\"background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:24px;width:200px;text-align:center\"><p style=\"color:#64748b;font-size:14px;margin:0\">Active Users</p><p style=\"font-size:48px;font-weight:900;margin:8px 0;color:#1e293b\">12.4K</p><p style=\"color:#22c55e;font-size:14px;margin:0\">↑ 8% vs last month</p></div><div style=\"background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:24px;width:200px;text-align:center\"><p style=\"color:#64748b;font-size:14px;margin:0\">Churn Rate</p><p style=\"font-size:48px;font-weight:900;margin:8px 0;color:#1e293b\">2.1%</p><p style=\"color:#ef4444;font-size:14px;margin:0\">↑ 0.3% vs last month</p></div></div>"
}'
ヒートマップ
belt app run infsh/python-executor --input '{
"code": "import matplotlib.pyplot as plt\nimport numpy as np\nimport matplotlib\nmatplotlib.use(\"Agg\")\n\nfig, ax = plt.subplots(figsize=(10, 6))\n\ndays = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"]\nhours = [\"9AM\", \"10AM\", \"11AM\", \"12PM\", \"1PM\", \"2PM\", \"3PM\", \"4PM\", \"5PM\"]\ndata = np.random.randint(10, 100, size=(len(hours), len(days)))\ndata[2][1] = 95 # Tuesday 11AM peak\ndata[2][3] = 88 # Thursday 11AM\n\nim = ax.imshow(data, cmap=\"Blues\", aspect=\"auto\")\nax.set_xticks(range(len(days)))\nax.set_yticks(range(len(hours)))\nax.set_xticklabels(days, fontsize=12)\nax.set_yticklabels(hours, fontsize=12)\n\nfor i in range(len(hours)):\n for j in range(len(days)):\n color = \"white\" if data[i][j] > 60 else \"black\"\n ax.text(j, i, data[i][j], ha=\"center\", va=\"center\", fontsize=10, color=color)\n\nax.set_title(\"Website Traffic by Day & Hour\", fontsize=16, fontweight=\"bold\")\nplt.colorbar(im, label=\"Visitors\")\nplt.tight_layout()\nplt.savefig(\"heatmap.png\", dpi=150)\nprint(\"Saved\")"
}'
データでストーリーを伝える
物語の流れ
| ステップ | 内容 | 例 |
|---|---|---|
| 1. 背景 | 読み手に必要な情報を提示します | 「顧客獲得コストを毎月追跡しています」 |
| 2. 問題提起 | 問題や変化を示します | 「第 3 四半期に CAC が 40% 増加しました」 |
| 3. 解決 | 洞察や解決策を示します | 「しかし、LTV が 80% 増加したため、ユニットエコノミクスは改善しました」 |
洞察をタイトルにする
❌ Descriptive titles (what the chart shows):
"Q3 Revenue by Product Line"
"Monthly Active Users 2024"
"Customer Satisfaction Survey Results"
✅ Insight titles (what the chart means):
"Enterprise product drives 70% of revenue growth"
"User growth accelerated after the free tier launch"
"Support response time is the #1 satisfaction driver"
注釈の手法
| 手法 | 使用する場面 |
|---|---|
| 吹き出しラベル | 特定のデータポイントを強調する場合(「ピーク:320K」) |
| 基準線 | 目標や基準値を示す場合(「目標:100K」) |
| 網掛け領域 | 期間を示す場合(「製品ローンチ期間」) |
| 矢印+テキスト | トレンドの変化に注目を集める場合 |
| イベント前後の線 | イベントの影響を示す場合 |
ダークモードのグラフ
belt app run infsh/python-executor --input '{
"code": "import matplotlib.pyplot as plt\nimport matplotlib\nmatplotlib.use(\"Agg\")\n\n# Dark theme\nplt.rcParams.update({\n \"figure.facecolor\": \"#0f172a\",\n \"axes.facecolor\": \"#0f172a\",\n \"axes.edgecolor\": \"#334155\",\n \"axes.labelcolor\": \"white\",\n \"text.color\": \"white\",\n \"xtick.color\": \"white\",\n \"ytick.color\": \"white\",\n \"grid.color\": \"#1e293b\"\n})\n\nfig, ax = plt.subplots(figsize=(12, 6))\nmonths = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\"]\nvalues = [45, 52, 58, 72, 85, 98]\n\nax.plot(months, values, color=\"#818cf8\", linewidth=3, marker=\"o\", markersize=8)\nax.fill_between(range(len(months)), values, alpha=0.15, color=\"#818cf8\")\nax.set_title(\"MRR Growth: On track for $100K\", fontsize=18, fontweight=\"bold\")\nax.set_ylabel(\"MRR ($K)\", fontsize=13)\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nax.grid(axis=\"y\", alpha=0.2)\n\nfor i, v in enumerate(values):\n ax.annotate(f\"${v}K\", (i, v), textcoords=\"offset points\", xytext=(0, 12), ha=\"center\", fontsize=11, fontweight=\"bold\")\n\nplt.tight_layout()\nplt.savefig(\"dark-chart.png\", dpi=150, facecolor=\"#0f172a\")\nprint(\"Saved\")"
}'
よくある間違い
| 間違い | 問題点 | 修正方法 |
|---|---|---|
| 円グラフ | 比較が難しく、常に誤解を招きます | 棒グラフまたはツリーマップを使います |
| 棒グラフの Y 軸が 0 から始まっていない | 違いを誇張してしまいます | 棒グラフは 0 から始め、折れ線グラフは途中で切り詰めてもかまいません |
| 色が多すぎる | 視覚的なノイズが生じ、わかりにくくなります | 色は最大 5~7 色にし、重要な点だけを強調します |
| タイトルがない、または一般的すぎるタイトル | 読者に重要な洞察が伝わりません | タイトルにはデータの種類ではなく、要点を示します |
| 3D グラフ | データが歪んで見え、プロフェッショナルらしさに欠けます | 必ず 2D を使います |
| Y 軸が 2 つある | 誤解を招き、読みづらくなります | グラフを 2 つに分けます |
| 棒グラフをアルファベット順に並べる | データが伝える内容が見えにくくなります | 値の大きい順に並べます |
| 軸のラベルがない | 読者が解釈できません | 必ず単位を付けてラベルを付けます |
| チャートジャンク(装飾要素) | データから注意をそらします | 情報を伝えない要素はすべて取り除きます |
| 色分けに赤と緑だけを使う | 色覚多様性のあるユーザーには読み取れません | 形やパターン、または色覚に配慮したパレットを使います |
関連スキル
npx skills add inference-sh/skills@pitch-deck-visuals
npx skills add inference-sh/skills@technical-blog-writing
npx skills add inference-sh/skills@competitor-teardown
すべてのアプリを表示:belt app list
コメント
Markdown 対応