金融データ可視化における Plotly の応用
現代の金融市場において、データ可視化技術は投資判断を支える羅針盤としての役割を果たしています。従来の静的なグラフから、インタラクティブな可視化へと移行する動きが加速しており、業界の調査によると动态可视化的導入により投資意思決定の効率が大幅に向上することが示されています。
本稿では、Python の可視化ライブラリである Plotly を用いて、ポートフォリオの構成分析や金融時系列データの動的表現を実現する具体的な手法を解説します。
1. ポートフォリオ構成の可視化
投資ポートフォリオの分析において、資産配分(アセットアロケーション)の把握は不可欠です。各資産クラスの比率を視覚化することで、戦略のバランスを即座に評価できます。
1.1. 資産配分の円グラフと棒グラフ
plotly.graph_objects を利用し、サブプロットとして円グラフと棒グラフを併設することで、多角的な視点から資産構成を確認できます。
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# 資産クラスと配分比率の定義
asset_classes = ["株式", "債券", "現金", "コモディティ"]
allocation_rates = [0.45, 0.35, 0.15, 0.05]
# サブプロットの初期化
chart_container = make_subplots(
rows=1,
cols=2,
horizontal_spacing=0.15,
specs=[[{"type": "domain"}, {"type": "xy"}]],
subplot_titles=["資産構成比率 (円)", "資産構成比率 (棒)"]
)
# 円グラフの追加
chart_container.add_trace(
go.Pie(
labels=asset_classes,
values=allocation_rates,
hole=0.4
),
row=1,
col=1
)
# 棒グラフの追加
chart_container.add_trace(
go.Bar(
x=asset_classes,
y=allocation_rates,
marker_color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
),
row=1,
col=2
)
chart_container.update_layout(height=400, showlegend=False)
chart_container.show()
1.2. 時間軸に沿った配分変動の表示
ポートフォリオは静的なものではなく、時間とともに再調整されます。Plotly のアップデートメニュー機能を用いると、特定の資産クラスのみを表示したり、全ての推移を確認したりするインタラクティブな操作が可能になります。
import pandas as pd
import plotly.express as px
# 月次資産配分データの作成
monthly_data = pd.DataFrame({
"報告日": ["2024-01", "2024-02", "2024-03"],
"株式": [0.45, 0.50, 0.55],
"債券": [0.35, 0.30, 0.25],
"現金": [0.15, 0.15, 0.15],
"コモディティ": [0.05, 0.05, 0.05]
})
# 積み上げ棒グラフの作成
fig_timeline = px.bar(
monthly_data,
x="報告日",
y=["株式", "債券", "現金", "コモディティ"],
title="月次資産配分推移",
labels={"value": "比率", "variable": "資産クラス"}
)
# ボタンメニューによる表示切り替え設定
fig_timeline.update_layout(
updatemenus=[
dict(
type="buttons",
direction="down",
showactive=True,
x=0.1,
y=1.1,
buttons=[
dict(label="すべて表示", method="update", args=[{"visible": [True, True, True, True]}]),
dict(label="株式のみ", method="update", args=[{"visible": [True, False, False, False]}]),
dict(label="債券のみ", method="update", args=[{"visible": [False, True, False, False]}]),
]
)
]
)
fig_timeline.show()
1.3. 投資戦略プロファイルの比較
異なるリスク許容度に基づく複数の戦略を比較する場合、複数のバーを並列に配置することで差異を明確にできます。
# 防御型戦略と攻撃型戦略のデータ
profile_defensive = {"資産": ["株式", "債券", "現金"], "比率": [0.3, 0.5, 0.2]}
profile_aggressive = {"資産": ["株式", "債券", "現金"], "比率": [0.7, 0.2, 0.1]}
comparison_fig = go.Figure()
# 各戦略のトレース追加
comparison_fig.add_trace(go.Bar(
name="防御型ポートフォリオ",
x=profile_defensive["資産"],
y=profile_defensive["比率"],
marker_color='green'
))
comparison_fig.add_trace(go.Bar(
name="攻撃型ポートフォリオ",
x=profile_aggressive["資産"],
y=profile_aggressive["比率"],
marker_color='red'
))
comparison_fig.update_layout(
title="投資戦略プロファイルの比較",
barmode='group',
yaxis_title="配分比率"
)
comparison_fig.show()
2. リスクとリターンの関係性分析
投資理論において、リスク(変動性)とリターン(期待収益率)の関係を把握することは重要です。散布図を用いることで、各投資対象の特性を平面的にマッピングできます。
# 投資対象のパフォーマンスデータ
investment_items = pd.DataFrame({
"銘柄": ["銘柄 A", "銘柄 B", "債券 X", "投資信託 Y"],
"期待リターン": [0.15, 0.12, 0.04, 0.09],
"リスク(標準偏差)": [0.25, 0.20, 0.05, 0.12]
})
# 散布図の作成
scatter_fig = go.Figure()
scatter_fig.add_trace(go.Scatter(
x=investment_items["リスク(標準偏差)"],
y=investment_items["期待リターン"],
mode="markers+text",
text=investment_items["銘柄"],
textposition="top center",
marker=dict(size=15, color="#00CCFF"),
name="投資対象"
))
scatter_fig.update_layout(
title="リスク・リターン分析マップ",
xaxis_title="リスク(変動性)",
yaxis_title="期待リターン"
)
scatter_fig.show()
さらに、理論上の最適ポートフォリオ集合である「効率的フロンティア」を重ね合わせることで、現在 holdings が最適化されているかどうかの判断材料となります。
# 効的フロンティアの仮想データ
efficient_frontier = pd.DataFrame({
"リスク": [0.05, 0.10, 0.15, 0.20, 0.25],
"リターン": [0.03, 0.06, 0.09, 0.12, 0.14]
})
scatter_fig.add_trace(go.Scatter(
x=efficient_frontier["リスク"],
y=efficient_frontier["リターン"],
mode="lines",
name="効的フロンティア",
line=dict(color="orange", width=2, dash="dash")
))
scatter_fig.show()
3. アニメーションによる時系列変化の表現
金融データは時間軸に沿って変化します。Plotly Express が提供する animation_frame 機能を使用すると、スライダー操作を通じて時間の経過に伴う資産比率の変遷を直感的に理解できます。
# 時系列ポートフォリオデータ
time_series_portfolio = pd.DataFrame({
"timestamp": ["Q1", "Q1", "Q1", "Q2", "Q2", "Q2", "Q3", "Q3", "Q3"],
"category": ["株式", "債券", "現金"] * 3,
"ratio": [0.4, 0.4, 0.2, 0.5, 0.3, 0.2, 0.6, 0.25, 0.15]
})
# アニメーション付き棒グラフ
anim_fig = px.bar(
time_series_portfolio,
x="category",
y="ratio",
animation_frame="timestamp",
range_y=[0, 1],
title="四半期別ポートフォリオ構成変化",
labels={"ratio": "配分比率", "category": "資産カテゴリ"}
)
anim_fig.update_layout(transition=dict(duration=300), frame=dict(duration=300))
anim_fig.show()