Python

応用編: PythonとPlotlyを使ったデータの可視化

2023年6月11日

PythonでPlotlyを使ったグラフ描画応用編

以前にPlotly基礎編の記事を書かせて頂きました。

あわせて読みたい
PythonでPlotlyを使ったグラフ描画
基礎編: PythonとPlotlyを使ったデータの可視化

Pythonの優れたデータ可視化ライブラリのPlotlyを使ってみませんか?Plotlyは美しいグラフやプロットで、視覚的に理解しやすくなるのでプロフェッショナルなデータサイエンティストから初心者まで ...

続きを見る

最新のデータから洞察するにはデータ可視化は不可欠なツールです。
Plotlyを使用することで、複雑なデータを魅力的なグラフや図に変換することができます。
さらに、高度な機能を駆使することでデータを最大限に活かすことができます。

今回はサブプロットの出力方法やプロットのアニメーション化、リアルタイムデータの可視化 などを応用編として紹介します。

詳細な手順と実行例のコードを記事に掲載しているので、是非試してみてください。

①Plotlyで高度なデータ可視化を行う方法

Plotlyで高度なデータ可視化

以下の内容でPlotlyを使った高度なデータの可視化方法について解説します。

Plotlyで高度なデータ可視化を行う方法

  • サブプロットの作成と複数グラフの組み合わせ
  • プロットのアニメーション化
  • ツールチップの追加

サブプロットの作成と複数グラフの組み合わせ

サブプロットの作成と配置

サブプロットを作成することで1つの図に複数のグラフを組み合わせることができれば、
複数のデータを効果的に比較したり、関連する情報をまとめて表示したりすることができます。

以下にサブプロットの作成と配置の方法を説明します。

import plotly.graph_objects as go
from plotly.subplots import make_subplots

# サンプルデータの生成
categories = ['A', 'B', 'C']
values = [5, 3, 8]

# サブプロットを作成
fig = make_subplots(rows=2, cols=2,
subplot_titles=["ヒストグラム", "散布図", "折れ線グラフ", "棒グラフ"])

# ヒストグラムを1行1列に追加
fig.add_trace(go.Histogram(x=[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5], nbinsx=5, name='ヒストグラム'), row=1, col=1)

# 散布図を1行2列に追加
fig.add_trace(go.Scatter(x=[1, 2, 3, 4, 5], y=[1, 4, 9, 16, 25], mode='markers', name='散布図'), row=1, col=2)

# 折れ線グラフを2行1列に追加
fig.add_trace(go.Scatter(x=[1, 2, 3, 4, 5], y=[1, 2, 3, 4, 5], mode='lines', name='折れ線グラフ'), row=2, col=1)

# 棒グラフを2行2列に追加
fig.add_trace(go.Bar(x=categories, y=values, name='棒グラフ'), row=2, col=2)

# サブプロットのレイアウト設定とタイトル追加
fig.update_layout(
    xaxis1=dict(title='X軸1'),
    yaxis1=dict(title='Y軸1'),
    xaxis2=dict(title='X軸2'),
    yaxis2=dict(title='Y軸2', anchor='x2'),
    xaxis3=dict(title='X軸3'),
    yaxis3=dict(title='Y軸3', anchor='x3'),
    xaxis4=dict(title='X軸4'),
    yaxis4=dict(title='Y軸4', anchor='x4'),
    title='2行2列のサブプロット'
)

# 凡例を表示
fig.update_layout(showlegend=True, legend=dict(x=0.5, y=-0.15, orientation='h'))

# グラフの表示
fig.update_layout(height=600, width=800)
fig.show()

fig.write_html(r'D:/Document/ブログ/メカタナブログ/26.応用編 PythonとPlotlyを使ったデータの可視化/html/Plotly-subplot.html',include_plotlyjs='cdn',full_html=False) 

このコードはmake_subplots関数を使用して2行2列のサブプロットを作成します。
各グラフを指定された位置に追加しています。subplot_titlesパラメータを使用して、各サブプロットにタイトルを設定しています。

各グラフの種類は以下のようになっています:

  • 1行1列: ヒストグラム
  • 1行2列: 散布図
  • 2行1列: 折れ線グラフ
  • 2行2列: 棒グラフ

最後に、グラフの表示領域のサイズやタイトルの表示などのレイアウト設定を行い、
fig.show()を使用してグラフを表示しています。

このコードを実行すると、2行2列のサブプロットが表示され、それぞれのサブプロットには指定されたグラフとタイトルが表示されます。

プロットのアニメーション化

プロットのアニメーション化

プロットのアニメーションを活用することで、
データの動きやパターンの変化を容易に理解することができます。

以下にアニメーションを作成するプログラムを示します。

import plotly.graph_objects as go
import numpy as np

# データを生成
x = np.linspace(0, 10, 50)
y = np.sin(x)

# プロットオブジェクトを作成
fig = go.Figure()

# プロットを追加
fig.add_trace(go.Scatter(x=[x[0]], y=[y[0]], mode='markers', marker=dict(size=10)))

# アニメーションフレームを追加
frames = []
for i in range(1, len(x)):
    frame_data = go.Frame(data=[go.Scatter(x=x[:i+1], y=y[:i+1], mode='markers', marker=dict(size=10))])
    frames.append(frame_data)

fig.frames = frames

# アニメーションの設定
fig.update_layout(
    updatemenus=[
        go.layout.Updatemenu(
            type="buttons",
            buttons=[
                go.layout.updatemenu.Button(
                    label="Play",
                    method="animate",
                    args=[None, {"frame": {"duration": 500, "redraw": True}, "fromcurrent": True, "mode": "immediate"}],
                ),
                go.layout.updatemenu.Button(
                    label="Pause",
                    method="animate",
                    args=[[None], {"frame": {"duration": 0, "redraw": False}, "mode": "immediate", "transition": {"duration": 0}}],
                ),
            ],
        )
    ],
)

# グラフを表示
fig.show()

x = np.linspace(0, 10, 50)で0から10までの範囲を50の等間隔なデータポイントで生成し、
y = np.sin(x)ではsin関数を適用してyの値を計算します。

fig = go.Figure()でプロットオブジェクトを作成します。

fig.add_trace(go.Scatter(x=[x[0]], y=[y[0]], mode='markers', marker=dict(size=10)))では
最初のデータポイントをプロットに追加します。

frames = []
for i in range(1, len(x)):
    frame_data = go.Frame(data=[go.Scatter(x=x[:i+1], y=y[:i+1], mode='markers', marker=dict(size=10))])
    frames.append(frame_data)

fig.frames = frames

上記ではアニメーションのフレームを作成し、データを更新します。
ループを使用して各フレームでデータを追加しています。

fig.update_layout(
    updatemenus=[
        go.layout.Updatemenu(
            type="buttons",
            buttons=[
                go.layout.updatemenu.Button(
                    label="Play",
                    method="animate",
                    args=[None, {"frame": {"duration": 500, "redraw": True}, "fromcurrent": True, "mode": "immediate"}],
                ),
                go.layout.updatemenu.Button(
                    label="Pause",
                    method="animate",
                    args=[[None], {"frame": {"duration": 0, "redraw": False}, "mode": "immediate", "transition": {"duration": 0}}],
                ),
            ],
        )
    ],
)

上のプログラムはアニメーションの設定を更新します。
PlayボタンとPauseボタンを追加してアニメーションの動作を制御します。

問題なく実行できればアニメーションのフレームごとにデータが追加され、
PlayボタンとPauseボタンによってアニメーションが制御されます。
各フレームでデータが更新されるため、データのプロットが時間の経過とともに表示されます。

ツールチップの追加

ツールチップの追加

ツールチップはマウスオーバー時にデータポイントの詳細情報を表示するための
ポップアップ機能です。

以下にPlotlyでツールチップを追加するプログラムを示します。

import plotly.graph_objects as go

# グラフのデータを定義
x = [1, 2, 3, 4, 5]
y = [2, 4, 1, 3, 5]

# ツールチップに表示する情報を準備
labels = ['Data Point 1', 'Data Point 2', 'Data Point 3', 'Data Point 4', 'Data Point 5']
values = [10, 20, 30, 40, 50]

# プロットオブジェクトを作成
fig = go.Figure()

# データを追加
fig.add_trace(go.Scatter(
    x=x,
    y=y,
    mode='markers',
    marker=dict(
        size=10,
        color='blue'
    ),
    text=labels,  # ツールチップに表示するテキストを指定
    hovertemplate='<b>%{text}</b><br><br>' +  # ツールチップの書式を指定
                  'Value: %{y}'  # ツールチップに表示する情報を指定
))

# グラフのレイアウトをカスタマイズ
fig.update_layout(
    title='ツールチップ',
    hovermode='closest',  # マウスオーバー時に最も近いデータポイントのツールチップを表示
    xaxis_title='X軸',  # x軸のラベルを設定
    yaxis_title='Y軸'  # y軸のラベルを設定
)

# グラフを表示
fig.show()

ツールチップに表示する情報を準備します。
例えばデータポイントのラベルや値などが考えられるので、labelsを定義します。

go.Scatterを使用して折れ線グラフを定義し、
text引数にツールチップに表示するテキストを指定します。

hovertemplateでツールチップの書式を設定します。
ここでは、データポイントのテキストとy軸の値を表示するようにしています。

update_layoutメソッドを使用して、タイトルや軸のラベルを設定します。

問題なく実行できたら折れ線グラフが表示され、
データポイントにマウスを重ねるとツールチップが表示されと思います。

ツールチップはデータポイントのラベルとy軸の値を表示するように設定しています。

②Plotlyの活用例と応用テクニック

Plotlyの活用例と応用テクニック

以下にPlotlyの活用例と応用テクニックを紹介します。

Python Plotlyの活用例と応用テクニック

  • リアルタイムデータの可視化
  • マップや3Dグラフの作成

リアルタイムデータの可視化

リアルタイムデータのストリーミングと可視化

Plotlyはデータの変化をリアルタイムにグラフやチャートとして表示できます。
以下にリアルタイムデータ可視化のプログラムを記します。

import plotly.graph_objects as go
from collections import deque
import random
import time

# データキューの初期化
max_data_points = 100  # 表示するデータ点の最大数
data_x = deque(maxlen=max_data_points)
data_y = deque(maxlen=max_data_points)

# グラフの初期化
fig = go.Figure()

# プロットオブジェクトを作成
fig.add_trace(go.Scatter(x=list(data_x), y=list(data_y), mode='lines'))

# グラフのレイアウトをカスタマイズ
fig.update_layout(
    title='リアルタイムデータ可視化',
    xaxis_title='時間',
    yaxis_title='データ値',
    autosize=True,
)

# グラフを表示
fig.show()

# リアルタイムデータの生成とグラフの更新
while True:
    # 新しいデータの生成
    new_data_point = random.randint(0, 10)

    # データキューに新しいデータを追加
    data_x.append(time.strftime('%H:%M:%S'))  # 時間情報などのX軸データを追加
    data_y.append(new_data_point)  # Y軸データを追加

    # グラフを更新
    fig.update_traces(x=list(data_x), y=list(data_y))

    # グラフの再描画
    fig.update_layout(autosize=False)  # autosizeを一時的にオフにする
    fig.show()
    fig.update_layout(autosize=True)  # autosizeを再度オンにする

    # データ更新の待機時間(秒)
    time.sleep(1)

最初に、データキュー(deque)を初期化して最大データ点数を設定することで、
表示されるデータ点の数を制限します。
ここでは、max_data_points変数を使用して100点としています。
データキューは新しいデータが追加されると古いデータを自動的に削除して、一定数のデータ点のみを保持します。

次に、グラフオブジェクト(Figure)を作成します。go.Scatterを使用して、折れ線グラフのプロットオブジェクトを作成し、それをグラフに追加します。この時点ではまだデータは空ですので、x軸とy軸のデータは空リストです。

グラフのレイアウトをカスタマイズするために、update_layoutメソッドを使用します。ここでは、グラフのタイトルやx軸、y軸のラベルを設定しています。また、autosizeをTrueに設定することで、グラフのサイズが自動的に調整されるようにしています。

これまでの設定が完了したらfig.show()を呼び出すことで、初期の空グラフが表示されます。

次にループに入ります。
ループ内では、新しいデータポイントをランダムに生成しでデータキューに追加します。
ここではrandom.randint()を使用して0から10までのランダムな整数を生成しています。
また、時間情報をx軸のデータとして追加するために、
time.strftime('%H:%M:%S')を使用して現在の時刻を取得しています。

データが更新された後fig.update_traces()を使用してグラフのプロットデータを更新します。
データキューをリストに変換して、x軸とy軸のデータとして指定します。

次にグラフを再描画するためfig.update_layout()を使用します。
ここでは一時的にautosizeをFalseに設定し、グラフのサイズを固定します。
その後、再度fig.show()を呼び出してグラフを再描画します。これにより、新しいデータが追加されたグラフが表示されます。

最後にtime.sleep(1)を使用して1秒の待機時間を設定します。
これにより、データの更新が1秒ごとに行われるようになります。

このプログラムを実行すると、データがリアルタイムに生成され、折れ線グラフが動的に更新される様子を視覚的に確認することができます。

今回はデータをランダムに表示させましたが、例えば実際の波形データを取り込めたら
面白いかもしれませんね。

マップや3Dグラフの作成

地理情報データのマッピングと可視化

地理情報データのマッピングと可視化にはPlotly Expressを使用することができます。

以下に地理情報データをマップ上にプロットして可視化するための基本的な
プログラムを示します。

import plotly.express as px
import pandas as pd

# データフレームに地理情報データを準備
df = pd.DataFrame({
    'name': ['Tokyo', 'Osaka', 'Kyoto', 'Sapporo', 'Fukuoka'],
    'latitude': [35.6895, 34.6937, 35.0116, 43.0621, 33.5904],
    'longitude': [139.6917, 135.5023, 135.7681, 141.3544, 130.4017],
    'population': [13929286, 8397000, 1474570, 1952356, 1544681]
})

# 地理情報データをプロット
fig = px.scatter_mapbox(data_frame=df, lat='latitude', lon='longitude', hover_data=['name', 'population'])

# マップのスタイルと初期表示をカスタマイズ
fig.update_layout(
    mapbox_style="carto-positron",
    mapbox_zoom=10,
    mapbox_center={"lat": 35.6895, "lon": 139.6917}  # 東京都庁の座標を指定
)

# マップを表示
fig.show()

必要なライブラリであるplotly.expresspxとしてインポートします。

地理情報データを含むデータフレームを作成します。name列は地名、latitude列は緯度、
longitude列は経度、population列は人口を表します。

scatter_mapbox関数を使用して地理情報データをプロットします。
data_frame引数にデータフレームを指定し、
lat引数に緯度列、lon引数に経度列を指定します。
hover_data引数では、ホバー時に表示するデータを指定できます。

update_layoutメソッドを使用してマップのスタイルや初期表示をカスタマイズします。
mapbox_style引数でマップのスタイルを指定します。
今回はcarto-positronを使用しましたが、他にも以下のようなスタイルがあるので
いろいろ試してみてください。

open-street-map: OpenStreetMapのデフォルトスタイル。

white-bg: 白い背景のシンプルなスタイル。

carto-darkmatter: Cartoのダークマタースタイル。

stamen-terrain: Stamenの地形情報を基にしたスタイル。

stamen-toner: Stamenのトナーと呼ばれる白黒のスタイル。

stamen-watercolor: Stamenの水彩画風のスタイル。

mapbox_zoom引数でズームレベル、
mapbox_center引数で初期表示の中心座標を指定します。

プログラムを実行すると、地理情報データが散布図としてマップ上に表示されます。
マウスをホバーすると、地名と人口が表示されます。
マップのスタイルや初期表示位置はカスタマイズ可能です。

基礎編からもう一度学びなおしたい方は以下の記事を読むと大丈夫です。

あわせて読みたい
PythonでPlotlyを使ったグラフ描画
基礎編: PythonとPlotlyを使ったデータの可視化

Pythonの優れたデータ可視化ライブラリのPlotlyを使ってみませんか?Plotlyは美しいグラフやプロットで、視覚的に理解しやすくなるのでプロフェッショナルなデータサイエンティストから初心者まで ...

続きを見る

かなり長くなってしましましたが、今回は以上です。

  • この記事を書いた人

メカタナ

副業ブロガー【経歴】関西出身▶︎理系国立大学院▶︎東証プライム上場企業メーカー開発職▶︎妻と息子1人と暮らしています。▶︎メカタナブログを開設⇒仕事や日常で役立つPythonプログラムを紹介していきます!

-Python