Pythonデータ可視化:Matplotlib, Seaborn, Plotly, Bokehの四つの主要ライブラリと14の実装例

Pythonデータ可視化

Pythonは強力なプログラミング言語であり、データ分析、機械学習、ウェブ開発など幅広い分野で活用されています。特にデータ可視化においても、Pythonのグラフィックライブラリは非常に優れた性能を発揮します。これにより、複雑なデータを視覚的に理解しやすくするための様々な図表を作成することが可能です。

Pythonにおける主要な4つの可視化ライブラリ

1. Matplotlib

Pythonで最も人気のある可視化ライブラリの一つです。静的・動的・インタラクティブなチャートを描画するための豊富なツールと関数を提供しています。Matplotlibは機能が豊富であり、柔軟性が高いので、さまざまな複雑な図表を簡単に作成できます。線グラフや棒グラフから散布図やヒートマップまで、幅広く対応可能です。

2. Seaborn

Matplotlibに基づいた統計的データ可視化ライブラリで、より高レベルのインターフェースを提供し、統計グラフの作成を容易にします。分布図、相関図、ペアプロットなどの一般的な統計グラフを内蔵しており、データの分析と表現を迅速に行うことができます。

3. Plotly

インタラクティブなグラフ描画ライブラリで、オンラインおよびオフラインでの使用に対応しています。美しいデザインと豊かなインタラクティブ機能を持つチャートを作成でき、マウスホバー、クリック、ドラッグなどで情報を取得できます。

4. Bokeh

インタラクティブなWebグラフを作成するためのPythonライブラリで、複雑な統計グラフの作成と大規模データセットのレンダリングをサポートします。Webアプリケーションに適したインタラクティブなチャートの構築に最適です。

14の実装例によるグラフ作成

Pythonの可視化ライブラリは、折れ線グラフ、散布図、棒グラフ、円グラフ、ヒートマップ、ボックスプロット、面グラフ、極座標グラフ、スパイダー図、太陽グラフ、サニーマップ、フローチャート、パラレル座標、ツリーチャートなど、多様なグラフタイプをサポートしています。これらは、データ分析と可視化のニーズを満たすために設計されており、データの特徴と傾向を直感的に理解するのに役立ちます。

折れ線グラフ例

Matplotlibを使用したシンプルな折れ線グラフの例です:

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]

plt.plot(x, y)
plt.title('Simple Line Chart')
plt.xlabel('X Axis')
plt.ylabel('Y Axis')
plt.show()

このコードではmatplotlib.pyplotモジュールをインポートし、xとyのリストをデータとして定義します。plt.plot()関数で折れ線グラフを描画し、plt.title()plt.xlabel()plt.ylabel()でタイトルと軸ラベルを追加し、plt.show()でグラフを表示します。

正弦波折れ線グラフ例

Matplotlibを使用して正弦波を描画する例です:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)

plt.plot(x, y)
plt.title('Simple Line Plot')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()

この例では、numpyを使って正弦波を生成し、matplotlibで描画します。データと描画関数のパラメータを調整することで、複雑なグラフを簡単に作成できます。

散布図例

matplotlibを使用した散布図の例です:

import matplotlib.pyplot as plt
import numpy as np

x = np.random.rand(50)
y = np.random.rand(50)

plt.figure(figsize=(8, 6))
plt.scatter(x, y, color='blue', marker='o', label='Random Data')

plt.title('Scatter Plot Example')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.legend()
plt.grid(True)
plt.show()

このコードでは、numpyでランダムなデータポイントを生成し、matplotlibのscatter()関数で散布図を描画します。タイトル、軸ラベル、凡例、グリッドを追加して視覚的に整理しています。

棒グラフ例

pandasとmatplotlibを使用した棒グラフの例です:

import pandas as pd
import matplotlib.pyplot as plt

data = {'A': [10, 15, 7, 10, 20],
        'B': [5, 20, 14, 24, 1],
        'C': [12, 10, 15, 8, 13]}
df = pd.DataFrame(data)

df.plot(kind='bar')
plt.title('Bar Chart Example')
plt.xlabel('Categories')
plt.ylabel('Values')
plt.show()

この例では、pandasでDataFrameを作成し、df.plot(kind='bar')で棒グラフを描画します。タイトルと軸ラベルを追加して表示します。

円グラフ例

matplotlibを使用した円グラフの例です:

import matplotlib.pyplot as plt

labels = ['A', 'B', 'C', 'D']
sizes = [15, 30, 45, 10]
colors = ['#ff9999','#66b3ff','#99ff99','#ffcc99']

plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
plt.title('Pie Chart Example')
plt.axis('equal')
plt.show()

この例では、plt.pie()で円グラフを描画し、各セクターの割合を表示します。axis('equal')で円形を保証します。

ヒートマップ例

matplotlibを使用したヒートマップの例です:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap

np.random.seed(0)
data = np.random.rand(10, 12)

cmap = LinearSegmentedColormap.from_list("", ["white", "red"])
fig, ax = plt.subplots()
cax = ax.matshow(data, cmap=cmap)
fig.colorbar(cax)

ax.set_xticklabels([''] + list(range(1, data.shape[1] + 1)), rotation=90)
ax.set_yticklabels([''] + list(range(1, data.shape[0] + 1)))
plt.show()

この例では、numpyでランダムなデータを生成し、matplotlibでヒートマップを描画します。色の変化で値の大小を視覚的に表現します。

ボックスプロット例

matplotlibを使用したボックスプロットの例です:

import matplotlib.pyplot as plt
import numpy as np

data1 = np.random.normal(100, 10, 200)
data2 = np.random.normal(90, 20, 200)
data3 = np.random.normal(80, 30, 200)
data4 = np.random.normal(70, 40, 200)

plt.figure(figsize=(10, 6))
plt.boxplot([data1, data2, data3, data4], 
             labels=['Group 1', 'Group 2', 'Group 3', 'Group 4'], 
             patch_artist=True)
plt.title('Box plot comparison')
plt.ylabel('Values')
plt.grid(True)
plt.show()

この例では、numpyで正規分布のデータを生成し、matplotlibでボックスプロットを描画します。各グループの中央値、四分位数、異常値などを視覚的に比較できます。

面グラフ例

matplotlibを使用した面グラフの例です:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()
ax.fill_between(x, y1, color='skyblue', alpha=0.5)
ax.fill_between(x, y2, color='pink', alpha=0.5)
ax.plot(x, y1, color='blue', alpha=1)
ax.plot(x, y2, color='red', alpha=1)

ax.set_title('Area Chart Example')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.grid(True)
plt.show()

この例では、正弦と余弦関数の値を用いて面グラフを描画し、それぞれの値の変化を視覚的に比較できます。

極座標グラフ例

matplotlibを使用した極座標グラフの例です:

import matplotlib.pyplot as plt
import numpy as np

plt.subplot(111, projection='polar')
r = np.arange(0, 2, 0.01)
theta = 2 * np.pi * r

plt.plot(theta, r)
plt.title("Polar Chart Example")
plt.thetagrids(range(0, 360, 45), ["N", "E", "S", "W", "N", "E", "S", "W"])
plt.rgrids(range(1, 3))
plt.show()

この例では、極座標系を使用してデータを描画し、角度と距離の関係を視覚的に表現します。

スパイダー図例

matplotlibを使用したスパイダー図の例です:

import numpy as np
import matplotlib.pyplot as plt

labels = ['A', 'B', 'C', 'D', 'E']
data = [3, 8, 5, 10, 7]

angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False).tolist()
data += data[:1]
angles += angles[:1]

fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))
ax.plot(angles, data, 'o-', linewidth=2)
ax.fill(angles, data, alpha=0.25)
ax.set_yticklabels([])
ax.set_xticks(angles[:-1])
ax.set_xticklabels(labels)
ax.tick_params(axis='x', which='major', pad=10)
ax.grid(True)
plt.title("Spider Web Chart Example", va='bottom')
plt.show()

この例では、複数の次元のデータを視覚的に比較するためにスパイダー図を描画します。

太陽グラフ例

matplotlibを使用した太陽グラフの例です:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
import matplotlib.path as mpath

data = {
    'Level1': ['A', 'A', 'B', 'B', 'B', 'C'],
    'Level2': ['X', 'Y', 'X', 'Y', 'Z', 'X'],
    'Value': [10, 20, 30, 40, 50, 60]
}
df = pd.DataFrame(data)

df['Cumulative'] = df.groupby('Level1')['Value'].cumsum()
df['Normalized'] = df['Cumulative'] / df.groupby('Level1')['Cumulative'].transform('max')
df['StartAngle'] = df.groupby('Level1')['Normalized'].cumsum().apply(lambda x: 2 * np.pi * x)
df['EndAngle'] = df.groupby('Level1')['Normalized'].shift(-1).cumsum().apply(lambda x: 2 * np.pi * x)
df.loc[df.groupby('Level1').cumcount() == 0, 'StartAngle'] = 0
df.loc[df.groupby('Level1')['Value'].transform('sum') == df['Value'], 'EndAngle'] = 2 * np.pi

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})

for _, row in df.iterrows():
    verts = [(row['StartAngle'], row['Cumulative']),
             (row['EndAngle'], row['Cumulative']),
             (row['EndAngle'], 0),
             (row['StartAngle'], 0)]
    path = mpath.Path(verts)
    patch = PathPatch(path, facecolor='skyblue', lw=0.5, alpha=0.75)
    ax.add_patch(patch)

    ax.text(0.5 * (row['StartAngle'] + row['EndAngle']),
            row['Cumulative'] + 2,
            row['Level2'],
            ha='center',
            va='center',
            rotation=(row['StartAngle'] + row['EndAngle']) / 2. * 180. / np.pi,
            rotation_mode='anchor')

ax.set_ylim(0, df['Cumulative'].max() * 1.1)
ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)
ax.set_yticklabels([])
ax.set_xticklabels([])
ax.spines['polar'].set_visible(False)
plt.show()

この例では、極座標を使用して階層的なデータを視覚化する太陽グラフを描画します。

サニーマップ例

matplotlibを使用したサニーマップの例です:

import matplotlib.pyplot as plt
from matplotlib.patches import ConnectionPatch
import numpy as np

left = np.array([0, 0, 1, 1])
bottom = np.array([0, 1, 0, 1])
width = 0.2
height = np.array([0.5, 0.5, 0.7, 0.3])
total = sum(height)
norm_height = height / total

fig, ax = plt.subplots()
rects = ax.barh(bottom, norm_height, height=width, left=left, align='center')

ax.set_yticks(bottom + width / 2)
ax.set_yticklabels(['A', 'B', 'C', 'D'])
ax.set_xlim(0, 2)

for i in range(4):
    con = ConnectionPatch(
        xyA=(left[i] + width / 2, bottom[i]),
        coordsA='data',
        xyB=(left[i] + width / 2, bottom[i] + height[i]),
        coordsB='data',
        axesA=ax,
        axesB=ax,
        arrowstyle="-|>",
        connectionstyle="arc3,rad=.2",
        color="k"
    )
    ax.add_artist(con)

for i in range(4):
    ax.text(left[i] + width / 2, bottom[i] - 0.05, f"{height[i]:.2f}", ha='center')
    ax.text(left[i] + width + 0.02, bottom[i] + height[i] / 2, f"{height[i]:.2f}", ha='left', va='center')

plt.show()

この例では、matplotlibでサニーマップを手動で構築します。データの流れを視覚的に表現します。

フローチャート例

matplotlibを使用したフローチャートの例です:

import matplotlib.pyplot as plt
import numpy as np

nodes = ['A', 'B', 'C', 'D', 'E']
flows = {'A': {'B': 10, 'C': 5},
         'B': {'C': 8, 'D': 2},
         'C': {'D': 7, 'E': 6},
         'D': {'E': 9},
         'E': {}}

fig, ax = plt.subplots(figsize=(8, 6))
pos = {node: (i, 0) for i, node in enumerate(nodes)}

for node in nodes:
    ax.text(pos[node][0], pos[node][1], node, ha='center', va='center')

for source, targets in flows.items():
    x, y = pos[source]
    for target, flow in targets.items():
        x_target, y_target = pos[target]
        ax.annotate('', xy=(x_target, y_target), xytext=(x, y),
                    arrowprops=dict(arrowstyle='->', lw=2, color='r'))
        ax.text((x + x_target) / 2, (y + y_target) / 2, flow, ha='center', va='center', color='r')

ax.set_xlim(-0.5, len(nodes) - 0.5)
ax.set_ylim(-0.5, 0.5)
ax.set_xticks([])
ax.set_yticks([])
ax.axis('off')
plt.show()

この例では、ノード間の流れを矢印と数字で示したフローチャートを描画します。

パラレル座標図例

matplotlibを使用したパラレル座標図の例です:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

data = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
    [13, 14, 15, 16],
    [17, 18, 19, 20]
])

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

classes = ['Feature 1', 'Feature 2', 'Feature 3', 'Feature 4']
offset = 0.2

for i in range(data.shape[0]):
    xs = np.arange(data.shape[1])
    ys = data[i]
    zs = np.full_like(ys, offset * i)
    ax.plot(xs, ys, zs, 'o-')

ax.set_xticks(np.arange(data.shape[1]))
ax.set_xticklabels(classes)
plt.show()

この例では、4つの特徴量をパラレル座標で視覚化します。

ツリーチャート例

plotlyを使用したツリーチャートの例です:

import plotly.graph_objects as go

fig = go.Figure(data=[go.Treemap(
    labels=["Headquarters", "Department A", "Department B", "Employee 1", "Employee 2", "Employee 3", "Employee 4"],
    parents=["", "Headquarters", "Headquarters", "Department A", "Department A", "Department B", "Department B"],
    values=[100, 50, 50, 20, 20, 15, 15]
)])

fig.update_layout(
    margin = dict(t=50, l=25, r=25, b=15),
    title_text = "Company Organizational Tree"
)

fig.show()

この例では、企業構造を階層的に表示するツリーチャートを描画します。

ライブラリ選択と応用場面

データの規模、可視化の要件、インタラクティブ性の必要性などを考慮してライブラリを選択します。小さなデータセットではMatplotlibやSeabornで十分ですが、インタラクティブなオンラインチャートが必要な場合はPlotlyやBokehが適しています。

上級技術と例

図表のスタイルカスタマイズ、凡例と注釈の追加、大規模データセットの処理など、高度な機能を活用することで、より魅力的な可視化が可能です。

散布図行列例

Seabornを使用した散布図行列の例です:

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

data = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [5, 4, 3, 2, 1],
    'C': [2, 3, 4, 5, 6],
    'D': [6, 5, 4, 3, 2]
})

sns.pairplot(data)
plt.show()

この例では、Seabornのpairplotを使用して複数の変数間の関係を視覚化します。

実践例とテクニック

多変量データの可視化

複数の変数を含むデータセットでは、平行座標図やスパイダー図が効果的です。

時系列データの可視化

時間経過に伴うデータ変化を示すには、折れ線グラフや面グラフが適しています。

インタラクティブチャートの活用

PlotlyやBokehでインタラクティブなチャートを作成することで、観客の関心を引きやすくなります。

自動化とバッチ処理

大量のデータを処理する際には、自動化とバッチ処理が効率を向上させます。Pythonのオブジェクト指向機能を活用して、再利用可能な可視化関数を設計できます。

まとめと展望

Pythonの可視化ライブラリは、データ分析と理解を支援する強力なツールです。今後の進化とともに、より多くの可能性が広がるでしょう。

タグ: Python matplotlib Seaborn Plotly bokeh

6月26日 22:10 投稿