Pythonでデータ可視化を楽しもう：Pygalライブラリの完全ガイド

## はじめに

データ可視化は、複雑な情報を理解しやすい形で表現する重要な技術です。Pythonには多くのデータ可視化ライブラリがありますが、その中でもPygalは特に注目に値します。Pygalは、インタラクティブでカスタマイズ性の高いSVGグラフを簡単に作成できるライブラリです。このガイドでは、Pygalの基本から応用まで、15の章に分けて詳しく解説します。各章では、具体的なコード例と詳細な説明を提供し、Pygalの魅力を存分に体験していただきます。

## 第1章：Pygalのインストールと基本設定

Pygalを使い始める前に、まずはインストールが必要です。Pythonの環境が整っていることを確認し、以下のコマンドでPygalをインストールしましょう。

```python
pip install pygal
```

インストールが完了したら、簡単なグラフを作成して動作確認をします。以下のコードは、基本的な棒グラフを作成し、SVGファイルとして保存します。

```python
import pygal

# 棒グラフオブジェクトの作成
bar_chart = pygal.Bar()

# タイトルの設定
bar_chart.title = '果物の人気度調査'

# データの追加
bar_chart.add('りんご', 40)
bar_chart.add('バナナ', 35)
bar_chart.add('オレンジ', 30)
bar_chart.add('ぶどう', 25)

# SVGファイルとして保存
bar_chart.render_to_file('fruit_popularity.svg')
```

このコードを実行すると、'fruit_popularity.svg'というファイルが生成されます。このファイルをウェブブラウザで開くと、美しい棒グラフが表示されます。Pygalの特徴は、SVGフォーマットを使用していることです。SVGは拡大しても画質が劣化しない、軽量なベクターグラフィックス形式です。

## 第2章：線グラフの作成

線グラフは、時系列データや連続的な変化を表現するのに適しています。Pygalを使って、簡単に美しい線グラフを作成できます。以下のコードは、複数の線を含む線グラフを作成する例です。

```python
import pygal

# 線グラフオブジェクトの作成
line_chart = pygal.Line()

# タイトルとx軸ラベルの設定
line_chart.title = '月別売上推移'
line_chart.x_labels = ['1月', '2月', '3月', '4月', '5月', '6月']

# データの追加
line_chart.add('商品A', [100, 150, 200, 180, 220, 190])
line_chart.add('商品B', [80, 120, 160, 150, 180, 200])
line_chart.add('商品C', [60, 90, 110, 130, 150, 170])

# SVGファイルとして保存
line_chart.render_to_file('monthly_sales.svg')
```

このコードでは、3つの商品の6ヶ月間の売上推移を表現しています。`pygal.Line()`で線グラフオブジェクトを作成し、`x_labels`でx軸のラベルを設定しています。`add`メソッドを使って、各商品のデータを追加しています。結果として、3本の線が描かれた見やすいグラフが生成されます。

## 第3章：円グラフの作成

円グラフは、全体に対する各部分の割合を視覚的に表現するのに適しています。Pygalを使えば、簡単に美しい円グラフを作成できます。以下のコードは、基本的な円グラフを作成する例です。

```python
import pygal

# 円グラフオブジェクトの作成
pie_chart = pygal.Pie()

# タイトルの設定
pie_chart.title = '好きな色のアンケート結果'

# データの追加
pie_chart.add('赤', 35)
pie_chart.add('青', 30)
pie_chart.add('緑', 20)
pie_chart.add('黄', 15)

# SVGファイルとして保存
pie_chart.render_to_file('favorite_colors.svg')
```

このコードでは、アンケート結果を円グラフで表現しています。`pygal.Pie()`で円グラフオブジェクトを作成し、`add`メソッドで各色のデータを追加しています。結果として、4つの色の割合が一目で分かる円グラフが生成されます。

円グラフは、データの比率を直感的に理解するのに役立ちますが、あまり多くの項目を含めすぎると見にくくなるので注意が必要です。通常は5〜7項目程度が適切です。

## 第4章：棒グラフの応用

棒グラフは、カテゴリー別のデータを比較するのに適しています。Pygalでは、単純な棒グラフだけでなく、積み上げ棒グラフや水平棒グラフなど、様々なバリエーションを作成できます。以下のコードは、積み上げ棒グラフを作成する例です。

```python
import pygal

# 積み上げ棒グラフオブジェクトの作成
stacked_bar = pygal.StackedBar()

# タイトルとx軸ラベルの設定
stacked_bar.title = '四半期別売上（製品カテゴリー別）'
stacked_bar.x_labels = ['Q1', 'Q2', 'Q3', 'Q4']

# データの追加
stacked_bar.add('電子機器', [120, 150, 180, 210])
stacked_bar.add('家具', [90, 110, 130, 150])
stacked_bar.add('衣料品', [60, 80, 100, 120])
stacked_bar.add('食品', [30, 40, 50, 60])

# SVGファイルとして保存
stacked_bar.render_to_file('quarterly_sales_by_category.svg')
```

このコードでは、四半期ごとの売上を製品カテゴリー別に積み上げて表示しています。`pygal.StackedBar()`で積み上げ棒グラフオブジェクトを作成し、各カテゴリーのデータを`add`メソッドで追加しています。

積み上げ棒グラフは、全体の推移と各カテゴリーの貢献度を同時に表現できる点が特徴です。このグラフを見ることで、総売上の増加傾向と、各製品カテゴリーの売上構成比の変化を一目で把握できます。

## 第5章：散布図の作成

散布図は、2つの変数間の関係を視覚化するのに適しています。Pygalを使って、簡単に散布図を作成できます。以下のコードは、基本的な散布図を作成する例です。

```python
import pygal

# XY散布図オブジェクトの作成
xy_chart = pygal.XY(stroke=False)

# タイトルの設定
xy_chart.title = '身長と体重の関係'

# データの追加
xy_chart.add('男性', [
    (170, 65), (175, 70), (180, 75), (165, 60), (185, 85),
    (175, 80), (170, 75), (180, 80), (165, 70), (185, 90)
])
xy_chart.add('女性', [
    (160, 50), (165, 55), (170, 60), (155, 45), (175, 65),
    (165, 60), (160, 55), (170, 65), (155, 50), (175, 70)
])

# SVGファイルとして保存
xy_chart.render_to_file('height_weight_scatter.svg')
```

このコードでは、身長と体重のデータを男女別に散布図で表現しています。`pygal.XY(stroke=False)`でXY散布図オブジェクトを作成しています。`stroke=False`を指定することで、点と点を線で結ばないようにしています。

各データポイントは(x, y)の形式でタプルとして追加します。この例では、(身長, 体重)のペアを複数追加しています。

散布図は、データの分布や傾向を視覚的に捉えるのに役立ちます。この例では、男性と女性のデータを別々に追加することで、性別による身長と体重の関係の違いを比較できます。

## 第6章：ヒストグラムの作成

ヒストグラムは、データの分布を視覚化するのに適しています。Pygalを使って、簡単にヒストグラムを作成できます。以下のコードは、基本的なヒストグラムを作成する例です。

```python
import pygal
import random

# ヒストグラムオブジェクトの作成
hist = pygal.Histogram()

# タイトルの設定
hist.title = 'テストスコアの分布'

# データの生成
scores = [random.gauss(70, 10) for _ in range(200)]

# データの追加
hist.add('スコア', [
    (0, 20, 5),
    (20, 40, 15),
    (40, 60, 30),
    (60, 80, 100),
    (80, 100, 50)
])

# SVGファイルとして保存
hist.render_to_file('test_scores_histogram.svg')
```

このコードでは、テストスコアの分布をヒストグラムで表現しています。`pygal.Histogram()`でヒストグラムオブジェクトを作成しています。

データは(開始値, 終了値, 頻度)の形式でタプルとして追加します。この例では、0-20点、20-40点、40-60点、60-80点、80-100点の5つの区間に分けて、それぞれの頻度を指定しています。

ヒストグラムは、データの分布の形状、中心傾向、散らばりを視覚的に理解するのに役立ちます。この例では、テストスコアが正規分布に近い形で分布していることが分かります。

## 第7章：箱ひげ図の作成

箱ひげ図（ボックスプロット）は、データの分布を要約して表示するのに適しています。中央値、四分位数、外れ値などの情報を一度に表現できます。以下のコードは、Pygalを使って箱ひげ図を作成する例です。

```python
import pygal
import random

# 箱ひげ図オブジェクトの作成
box_plot = pygal.Box()

# タイトルの設定
box_plot.title = '部署別の年間売上（万円）'

# データの生成と追加
box_plot.add('営業部', [random.gauss(1000, 200) for _ in range(50)])
box_plot.add('マーケティング部', [random.gauss(800, 150) for _ in range(50)])
box_plot.add('開発部', [random.gauss(1200, 250) for _ in range(50)])
box_plot.add('人事部', [random.gauss(600, 100) for _ in range(50)])

# SVGファイルとして保存
box_plot.render_to_file('department_sales_boxplot.svg')
```

このコードでは、4つの部署の年間売上データを箱ひげ図で表現しています。`pygal.Box()`で箱ひげ図オブジェクトを作成しています。

各部署のデータは、ガウス分布（正規分布）に従うランダムな値を50個生成しています。`random.gauss(平均, 標準偏差)`を使用して、それぞれの部署に特徴的な分布を持つデータを生成しています。

箱ひげ図は、データの中央値（箱の中の線）、第1四分位数と第3四分位数（箱の下端と上端）、最小値と最大値（ひげの端）、そして外れ値（個別の点）を表示します。これにより、各部署の売上の分布を簡潔に比較することができます。

## 第8章：レーダーチャートの作成

レーダーチャート（スパイダーチャート）は、複数の変数を同時に比較するのに適しています。各変数を軸として放射状に配置し、データポイントを線で結ぶことで、全体的な特徴を視覚化します。以下のコードは、Pygalを使ってレーダーチャートを作成する例です。

```python
import pygal

# レーダーチャートオブジェクトの作成
radar_chart = pygal.Radar()

# タイトルの設定
radar_chart.title = 'プログラミング言語のスキル評価'

# 軸ラベルの設定
radar_chart.x_labels = ['Python', 'JavaScript', 'Java', 'C++', 'Ruby', 'PHP']

# データの追加
radar_chart.add('開発者A', [9, 7, 8, 6, 5, 4])
radar_chart.add('開発者B', [7, 8, 6, 7, 8, 6])
radar_chart.add('開発者C', [6,6, 9, 7, 8, 5, 7])

# SVGファイルとして保存
radar_chart.render_to_file('programming_skills_radar.svg')
```

このコードでは、3人の開発者のプログラミング言語スキルをレーダーチャートで表現しています。`pygal.Radar()`でレーダーチャートオブジェクトを作成し、`x_labels`で軸のラベルを設定しています。

各開発者のデータは、6つの言語それぞれに対するスキルレベル（0-10のスケール）を表しています。レーダーチャートでは、各軸の値が中心から外側に向かって大きくなるように表示されます。

このグラフを見ることで、各開発者の得意分野や、チーム全体としての言語カバレッジを一目で把握することができます。例えば、開発者Aはpythonが得意で、開発者BはRubyに強いといった特徴が分かります。

## 第9章：ゲージチャートの作成

ゲージチャートは、単一の値を視覚的に表現するのに適しています。特に、目標値や上限値に対する達成度を示すのに効果的です。以下のコードは、Pygalを使ってゲージチャートを作成する例です。

```python
import pygal

# ゲージチャートオブジェクトの作成
gauge = pygal.Gauge(human_readable=True)

# タイトルの設定
gauge.title = '四半期の売上目標達成率'

# 範囲の設定
gauge.range = [0, 100]

# データの追加
gauge.add('Q1', 67)
gauge.add('Q2', 83)
gauge.add('Q3', 92)
gauge.add('Q4', 78)

# SVGファイルとして保存
gauge.render_to_file('quarterly_sales_gauge.svg')
```

このコードでは、四半期ごとの売上目標達成率をゲージチャートで表現しています。`pygal.Gauge(human_readable=True)`でゲージチャートオブジェクトを作成しています。`human_readable=True`を指定することで、大きな数値を読みやすい形式（例：1000000 → 1M）に自動変換します。

`range`メソッドで値の範囲を0から100に設定しています。これは、達成率が0%から100%の範囲で表示されることを意味します。

各四半期のデータを`add`メソッドで追加しています。ゲージチャートでは、追加されたデータが円弧状のゲージとして表示されます。

このグラフを見ることで、各四半期の目標達成状況を直感的に理解できます。例えば、Q3が最も高い達成率を示していることが一目で分かります。

## 第10章：地図チャートの作成

地図チャートは、地理的なデータを視覚化するのに適しています。Pygalには世界地図や特定の国や地域の地図を描画する機能があります。以下のコードは、世界地図を使って各国のデータを表示する例です。

```python
import pygal

# 世界地図チャートオブジェクトの作成
worldmap = pygal.maps.world.World()

# タイトルの設定
worldmap.title = '主要国のGDP（兆ドル、2023年推定）'

# データの追加（国コードと値のペア）
worldmap.add('GDP', {
    'us': 26.95,  # アメリカ
    'cn': 17.70,  # 中国
    'jp': 4.41,   # 日本
    'de': 4.31,   # ドイツ
    'in': 3.73,   # インド
    'gb': 3.33,   # イギリス
    'fr': 3.05,   # フランス
})

# SVGファイルとして保存
worldmap.render_to_file('world_gdp_map.svg')
```

このコードでは、主要国のGDPデータを世界地図上に表示しています。`pygal.maps.world.World()`で世界地図チャートオブジェクトを作成しています。

データは国コードと値のペアとして追加します。国コードはISO 3166-1 alpha-2形式（2文字のコード）を使用しています。例えば、'us'はアメリカ、'jp'は日本を表します。

地図チャートでは、データの値に応じて国の色が変化します。値が大きいほど濃い色で表示されるため、GDPの大きさを視覚的に比較することができます。

このグラフを見ることで、世界のGDP分布を一目で把握できます。例えば、アメリカと中国のGDPが他国と比べて突出して大きいことが分かります。

## 第11章：複合グラフの作成

Pygalでは、異なる種類のグラフを1つのチャートに組み合わせることができます。これは、複数の関連するデータセットを効果的に比較したい場合に特に有用です。以下のコードは、棒グラフと線グラフを組み合わせた複合グラフを作成する例です。

```python
import pygal

# 複合グラフオブジェクトの作成
chart = pygal.Bar(secondary_range=(0, 100))

# タイトルとx軸ラベルの設定
chart.title = '月別売上と顧客満足度'
chart.x_labels = ['1月', '2月', '3月', '4月', '5月', '6月']

# 主軸（左）のデータ追加（棒グラフ）
chart.add('売上（万円）', [120, 150, 180, 210, 240, 270])

# 副軸（右）のデータ追加（線グラフ）
chart.add('顧客満足度（%）', [85, 88, 90, 87, 91, 93], secondary=True)

# SVGファイルとして保存
chart.render_to_file('sales_and_satisfaction.svg')
```

このコードでは、月別の売上データを棒グラフで、顧客満足度を線グラフで表現しています。`pygal.Bar(secondary_range=(0, 100))`で複合グラフオブジェクトを作成し、副軸（右側）の範囲を0から100に設定しています。

主軸（左側）のデータは通常通り`add`メソッドで追加します。副軸のデータを追加する際は、`secondary=True`を指定します。これにより、このデータセットが右側の軸を使用することを指示します。

複合グラフは、関連する複数の指標を同時に表示し、その相関関係を視覚化するのに適しています。この例では、売上の増加と顧客満足度の変化の関係を一目で確認することができます。

## 第12章：スタイルのカスタマイズ

Pygalでは、グラフの見た目を細かくカスタマイズすることができます。色、フォント、背景など、様々な要素を調整して、独自のスタイルを作成できます。以下のコードは、スタイルをカスタマイズした棒グラフを作成する例です。

```python
import pygal
from pygal.style import Style

# カスタムスタイルの定義
custom_style = Style(
    background='#f0f0f0',
    plot_background='white',
    foreground='#333333',
    foreground_strong='#666666',
    foreground_subtle='#999999',
    opacity='.6',
    opacity_hover='.9',
    transition='400ms ease-in',
    colors=('#E853A0', '#E8537A', '#E95355', '#E87653', '#E89B53')
)

# カスタムスタイルを適用した棒グラフオブジェクトの作成
chart = pygal.Bar(style=custom_style, x_label_rotation=45)

# タイトルとx軸ラベルの設定
chart.title = '果物の月間販売量'
chart.x_labels = ['1月', '2月', '3月', '4月', '5月']

# データの追加
chart.add('りんご', [30, 35, 45, 49, 42])
chart.add('バナナ', [40, 45, 50, 55, 60])
chart.add('オレンジ', [35, 40, 45, 50, 48])

# SVGファイルとして保存
chart.render_to_file('fruit_sales_custom_style.svg')
```

このコードでは、`Style`クラスを使ってカスタムスタイルを定義しています。背景色、プロット領域の背景色、文字色、不透明度、トランジション効果、使用する色のセットなどを指定しています。

カスタムスタイルは、グラフオブジェクトを作成する際に`style`パラメータとして渡します。また、`x_label_rotation=45`を指定して、x軸のラベルを45度回転させています。

このようにスタイルをカスタマイズすることで、会社のブランドカラーに合わせたグラフを作成したり、プレゼンテーションのテーマに合わせたデザインにしたりすることができます。Pygalの柔軟性を活かして、独自の美しいグラフを作成しましょう。

## 第13章：インタラクティブ機能の活用

Pygalの大きな特徴の一つは、インタラクティブな機能を簡単に実装できることです。SVGフォーマットを使用しているため、マウスオーバーやクリックなどのイベントに対応したグラフを作成できます。以下のコードは、ツールチップをカスタマイズした折れ線グラフを作成する例です。

```python
import pygal

# 折れ線グラフオブジェクトの作成
line_chart = pygal.Line(
    x_label_rotation=20,
    show_minor_x_labels=False,
    tooltip_border_radius=10
)

# タイトルとx軸ラベルの設定
line_chart.title = '過去5年間の四半期別売上'
line_chart.x_labels = map(str, range(2019, 2024))
line_chart.x_labels_major = map(str, range(2019, 2024))

# データの追加（カスタムツールチップ付き）
line_chart.add('製品A', [
    {'value': 100, 'label': '2019Q1: 100万円'},
    {'value': 120, 'label': '2019Q2: 120万円'},
    {'value': 140, 'label': '2019Q3: 140万円'},
    {'value': 160, 'label': '2019Q4: 160万円'},
    {'value': 180, 'label': '2020Q1: 180万円'},
    # ... 他の四半期のデータ
])

line_chart.add('製品B', [
    {'value': 80, 'label': '2019Q1: 80万円'},
    {'value': 100, 'label': '2019Q2: 100万円'},
    {'value': 130, 'label': '2019Q3: 130万円'},
    {'value': 150, 'label': '2019Q4: 150万円'},
    {'value': 170, 'label': '2020Q1: 170万円'},
    # ... 他の四半期のデータ
])

# SVGファイルとして保存
line_chart.render_to_file('quarterly_sales_interactive.svg')
```

このコードでは、過去5年間の四半期別売上データを折れ線グラフで表現しています。`x_label_rotation=20`でx軸のラベルを20度回転させ、`show_minor_x_labels=False`で小さなx軸ラベルを非表示にしています。

データを追加する際、各データポイントに`value`と`label`を持つ辞書を使用しています。これにより、マウスオーバー時に表示されるツールチップの内容をカスタマイズしています。

`tooltip_border_radius=10`を指定して、ツールチップの角を丸くしています。

このようなインタラクティブ機能を使うことで、ユーザーがグラフ上の特定のポイントにマウスを合わせたときに、詳細な情報を表示することができます。これにより、データの詳細を失うことなく、全体的なトレンドを示すシンプルなグラフを作成することができます。

## 第14章：アニメーションの追加

Pygalでは、SVGの特性を活かしてアニメーション効果を追加することができます。これにより、データの変化や推移をより動的に表現することが可能です。以下のコードは、アニメーション効果を持つ棒グラフを作成する例です。

```python
import pygal

# アニメーション付き棒グラフオブジェクトの作成
bar_chart = pygal.Bar(
    dynamic_print_values=True,
    print_values_position='top',
    print_zeroes=False,
    x_label_rotation=45,
    animation_duration=2000
)

# タイトルとx軸ラベルの設定
bar_chart.title = '部門別年間予算（単位：百万円）'
bar_chart.x_labels = ['営業部', '開発部', 'マーケティング部', '人事部', '財務部']

# データの追加
bar_chart.add('2023年度', [300, 450, 200, 150, 180])

# SVGファイルとして保存
bar_chart.render_to_file('department_budget_animated.svg')
```

このコードでは、部門別の年間予算を表す棒グラフにアニメーション効果を追加しています。主な特徴は以下の通りです：

- `dynamic_print_values=True`: 各バーの上に値を動的に表示します。
- `print_values_position='top'`: 値をバーの上部に表示します。
- `print_zeroes=False`: 値が0の場合は表示しません。
- `x_label_rotation=45`: x軸のラベルを45度回転させます。
- `animation_duration=2000`: アニメーションの持続時間を2000ミリ秒（2秒）に設定します。

このグラフをウェブブラウザで開くと、棒が下から上に向かって成長するアニメーションが表示されます。これにより、静的なグラフよりも注目を集め、データの大小関係をより印象的に伝えることができます。

アニメーション効果は、プレゼンテーションやウェブサイトでのデータ表示に特に効果的です。ただし、過度なアニメーションはかえって読みづらくなる可能性があるので、適度に使用することが重要です。

## 第15章：複数のグラフの組み合わせ

Pygalでは、複数のグラフを1つのSVGファイルに組み合わせることができます。これは、関連するデータセットを並べて表示したい場合や、異なる視点からデータを分析したい場合に非常に有用です。以下のコードは、2つの異なるグラフを1つのファイルに組み合わせる例です。

```python
import pygal
from pygal.style import Style

# カスタムスタイルの定義
custom_style = Style(
    colors=('#E853A0', '#E8537A', '#E95355', '#E87653', '#E89B53')
)

# 棒グラフの作成
bar_chart = pygal.Bar(style=custom_style, width=400, height=300)
bar_chart.title = '四半期別売上'
bar_chart.x_labels = ['Q1', 'Q2', 'Q3', 'Q4']
bar_chart.add('2023年', [100, 120, 140, 180])

# 円グラフの作成
pie_chart = pygal.Pie(style=custom_style, width=400, height=300)
pie_chart.title = '製品別売上比率'
pie_chart.add('製品A', 40)
pie_chart.add('製品B', 30)
pie_chart.add('製品C', 20)
pie_chart.add('その他', 10)

# 2つのグラフを組み合わせる
from pygal.ghost import Ghost
ghost = Ghost(width=800, height=400)
ghost.add_data(bar_chart.render_data(), 0, 0)
ghost.add_data(pie_chart.render_data(), 400, 0)

# SVGファイルとして保存
ghost.render_to_file('combined_charts.svg')
```

このコードでは、四半期別売上を示す棒グラフと、製品別売上比率を示す円グラフを1つのSVGファイルに組み合わせています。主な特徴は以下の通りです：

1. カスタムスタイルを定義し、両方のグラフに適用しています。
2. 各グラフのサイズを`width=400, height=300`で指定しています。
3. `Ghost`クラスを使用して、2つのグラフを1つのSVGファイルに結合しています。
4. `ghost.add_data()`メソッドを使って、各グラフの位置を指定しています。

この方法を使うことで、複数の関連するデータセットを効果的に比較・対照することができます。例えば、この例では四半期ごとの売上推移と、その売上の製品別内訳を同時に見ることができます。

複数のグラフを組み合わせる際は、全体のレイアウトやバランスに注意を払い、データの関連性が明確に伝わるようにすることが重要です。また、必要に応じて凡例や説明文を追加し、グラフの解釈を助けることも効果的です。

以上で、Pygalを使ったデータ可視化の詳細ガイドは終了です。これらの章を通じて、Pygalの基本から応用まで、幅広い機能と使い方を学ぶことができました。Pygalを活用して、あなたのデータを魅力的で情報豊かなビジュアルに変換してください。