ドル円レートの取得
yfinance でドル円は以下のティッカーで取得できます:
* USDJPY=X
gold: 金先物価格(USD/oz)
cpi: 米国の消費者物価指数(FREDから)
oil: WTI原油価格(USD/バレル)
usd_jpy: ドル円為替レート(1 USD = ◯◯ JPY)
取得した結果はcsvに保存し sqliteに保存することで毎回再取得せずに行えるようにしたい
mkdir auto_deel
cd auto_deel
で作業ディレクトリ作成
vim fetch_and_save_all.py
でスクリプト作成
import pandas as pd
import pandas_datareader.data as web
import yfinance as yf
import datetime
import os
# 保存先
csv_dir = "csv_data"
os.makedirs(csv_dir, exist_ok=True)
# 日付範囲
start = "2000-01-01"
end = datetime.datetime.today().strftime("%Y-%m-%d")
# 金価格(すでに保存済みのCSVを使用)
gold = pd.read_csv("gold_price_gc_f.csv", skiprows=[1], parse_dates=["Price"])
gold.rename(columns={"Price": "Date", "Close": "gold_price"}, inplace=True)
gold = gold[["Date", "gold_price"]]
gold.to_csv(f"{csv_dir}/gold.csv", index=False)
# CPI
cpi = web.DataReader("CPIAUCSL", "fred", start, end).reset_index()
cpi.columns = ["Date", "cpi"]
cpi.to_csv(f"{csv_dir}/cpi.csv", index=False)
# WTI
oil = web.DataReader("DCOILWTICO", "fred", start, end).reset_index()
oil.columns = ["Date", "oil"]
oil.to_csv(f"{csv_dir}/oil.csv", index=False)
# ドル円
usd_jpy = yf.download("USDJPY=X", start=start, end=end, interval="1d")[["Close"]]
usd_jpy.rename(columns={"Close": "usd_jpy"}, inplace=True)
usd_jpy.reset_index(inplace=True)
usd_jpy.to_csv(f"{csv_dir}/usd_jpy.csv", index=False)
print("✅ すべてのデータをCSVに保存しました。")
これで実行すると
Traceback (most recent call last):
File "/Users/snowpool/aw10s/auto_deel/fetch_and_save_all.py", line 16, in <module>
gold = pd.read_csv("gold_price_gc_f.csv", skiprows=[1], parse_dates=["Price"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 1026, in read_csv
return _read(filepath_or_buffer, kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 620, in _read
parser = TextFileReader(filepath_or_buffer, **kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 1620, in __init__
self._engine = self._make_engine(f, self.engine)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 1880, in _make_engine
self.handles = get_handle(
^^^^^^^^^^^
File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/common.py", line 873, in get_handle
handle = open(
^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'gold_price_gc_f.csv'
これは金価格を保存ファイルから読み込んでいるため
新規に作業ディレクトリ作成しているため、これだと動作しない
import pandas as pd
import pandas_datareader.data as web
import yfinance as yf
import datetime
import os
# 保存先ディレクトリ
csv_dir = "csv_data"
os.makedirs(csv_dir, exist_ok=True)
# 期間
start = "2000-01-01"
end = datetime.datetime.today().strftime("%Y-%m-%d")
# ✅ 金価格(GC=F)
gold = yf.download("GC=F", start=start, end=end, interval="1d")[["Close"]]
gold.rename(columns={"Close": "gold_price"}, inplace=True)
gold.reset_index(inplace=True)
gold.to_csv(f"{csv_dir}/gold.csv", index=False)
# ✅ CPI(FRED)
cpi = web.DataReader("CPIAUCSL", "fred", start, end).reset_index()
cpi.columns = ["Date", "cpi"]
cpi.to_csv(f"{csv_dir}/cpi.csv", index=False)
# ✅ 原油(WTI:FRED)
oil = web.DataReader("DCOILWTICO", "fred", start, end).reset_index()
oil.columns = ["Date", "oil"]
oil.to_csv(f"{csv_dir}/oil.csv", index=False)
# ✅ ドル円(USD/JPY)
usd_jpy = yf.download("USDJPY=X", start=start, end=end, interval="1d")[["Close"]]
usd_jpy.rename(columns={"Close": "usd_jpy"}, inplace=True)
usd_jpy.reset_index(inplace=True)
usd_jpy.to_csv(f"{csv_dir}/usd_jpy.csv", index=False)
print("✅ すべてのデータをCSVに保存しました。")
というように全て取得するに修正
これで実行すれば
/Users/snowpool/aw10s/auto_deel/fetch_and_save_all.py:16: FutureWarning: YF.download() has changed argument auto_adjust default to True
gold = yf.download("GC=F", start=start, end=end, interval="1d")[["Close"]]
[*********************100%***********************] 1 of 1 completed
/Users/snowpool/aw10s/auto_deel/fetch_and_save_all.py:32: FutureWarning: YF.download() has changed argument auto_adjust default to True
usd_jpy = yf.download("USDJPY=X", start=start, end=end, interval="1d")[["Close"]]
[*********************100%***********************] 1 of 1 completed
✅ すべてのデータをCSVに保存しました。
となって CSVファイルに保存ができる
次に
CSV → SQLite登録スクリプト
vim save_to_sqlite.py
内容は
import sqlite3
import pandas as pd
import os
csv_dir = "csv_data"
db_path = "commodity_data.db"
conn = sqlite3.connect(db_path)
# 読み込むCSVファイル
datasets = {
"gold_price": "gold.csv",
"cpi": "cpi.csv",
"oil": "oil.csv",
"usd_jpy": "usd_jpy.csv"
}
for table, file in datasets.items():
df = pd.read_csv(os.path.join(csv_dir, file), parse_dates=["Date"])
df.to_sql(table, conn, if_exists="replace", index=False)
print(f"✅ {table} を保存しました。")
conn.close()
print("✅ すべてのデータを SQLite に保存しました。")
これを実行すると
✅ gold_price を保存しました。
✅ cpi を保存しました。
✅ oil を保存しました。
✅ usd_jpy を保存しました。
✅ すべてのデータを SQLite に保存しました。
次に
SQLiteからデータ読み込んで相関分析する
🔹 対象テーブル
* gold_price
* cpi
* oil
* usd_jpy
SQLite → Pandas データフレーム → 日付で結合
相関分析・ヒートマップの作成
ステップ 説明 優先度
SQLite→Pandas→結合 分析のベースとなる時系列データを生成 ✅必須
相関係数・ヒートマップ 経済指標と金価格の関係性を把握 ✅必須
Prophet予測 簡単・解釈しやすい時系列予測 👍推奨
LSTM予測 複雑だが精度の高い多変量時系列予測 必要に応じて
とりあえず価格予測は置いておいて
相関関係までをやる
SQLite → pandas データ読み込み & 日付で整形
import sqlite3
import pandas as pd
# SQLiteファイルのパス
db_path = "commodity_data.db"
# SQLiteに接続
conn = sqlite3.connect(db_path)
# 各テーブルを読み込み(Dateをdatetime型に)
gold = pd.read_sql("SELECT * FROM gold_price", conn, parse_dates=["Date"])
cpi = pd.read_sql("SELECT * FROM cpi", conn, parse_dates=["Date"])
oil = pd.read_sql("SELECT * FROM oil", conn, parse_dates=["Date"])
usd_jpy = pd.read_sql("SELECT * FROM usd_jpy", conn, parse_dates=["Date"])
conn.close()
日付で結合(内部結合)
# 日付で結合(内部結合:全ての指標が揃っている日付のみ残す)
df = gold.merge(cpi, on="Date") \
.merge(oil, on="Date") \
.merge(usd_jpy, on="Date")
# 欠損値を除外
df.dropna(inplace=True)
# 日付順に並べ替え
df.sort_values("Date", inplace=True)
# 結果確認
print(df.head())
print(df.tail())
これを保存
# 必要に応じてCSV保存して後工程へ渡せるように
df.to_csv("merged_commodity_data.csv", index=False)
print("✅ データを merged_commodity_data.csv に保存しました。")
データの中身確認(列構成)
print("📊 列名一覧:", df.columns.tolist())
を行うようにする
結合方式の違い(用途別)
結合方式 使いどころ
how=”inner” 全ての指標が存在する日だけ使いたい(分析用)✅推奨
how=”outer” 欠損があっても全部のデータを残したい場合
how=”left” 特定の指標(例:金価格)を中心に他を揃えたい時
これらを行うスクリプト
sqlite_to_pandas_and_merge.py
を作成
これは
SQLite → pandas → 結合&保存スクリプト
内容は
import sqlite3
import pandas as pd
# SQLiteファイルのパス
db_path = "commodity_data.db"
# SQLiteに接続
conn = sqlite3.connect(db_path)
# 各テーブル読み込み(Date列をdatetime型として読み込む)
gold = pd.read_sql("SELECT * FROM gold_price", conn, parse_dates=["Date"])
cpi = pd.read_sql("SELECT * FROM cpi", conn, parse_dates=["Date"])
oil = pd.read_sql("SELECT * FROM oil", conn, parse_dates=["Date"])
usd_jpy = pd.read_sql("SELECT * FROM usd_jpy", conn, parse_dates=["Date"])
conn.close()
# 日付で内部結合(共通の日付のみ残す)
df = gold.merge(cpi, on="Date") \
.merge(oil, on="Date") \
.merge(usd_jpy, on="Date")
# 欠損値を除去
df.dropna(inplace=True)
# 日付順に並べ替え
df.sort_values("Date", inplace=True)
# 結果の確認
print("✅ 結合完了。データの先頭:")
print(df.head())
print("\n📊 列構成:")
print(df.columns.tolist())
# CSVとして保存
df.to_csv("merged_commodity_data.csv", index=False)
print("\n✅ merged_commodity_data.csv に保存完了")
で
実行結果
python sqlite_to_pandas_and_merge.py
✅ 結合完了。データの先頭:
Date gold_price cpi oil usd_jpy
0 2000-09-01 277.0 173.6 33.42 105.94999694824219
1 2000-11-01 263.8999938964844 174.2 33.14 108.25
2 2000-12-01 268.70001220703125 174.6 32.06 111.19000244140625
3 2001-02-01 268.5 176.0 29.88 115.41999816894531
4 2001-03-01 265.20001220703125 176.1 27.78 117.5
📊 列構成:
['Date', 'gold_price', 'cpi', 'oil', 'usd_jpy']
✅ merged_commodity_data.csv に保存完了
これで
* 📊 相関分析(ヒートマップ)
* 🔮 Prophetで金価格予測(CPI・ドル円あり)
* 🤖 LSTM構築(多変量予測)
ができるらしいのでまずは目的の相関分析を試す
相関分析+ヒートマップ表示のスクリプトを作成
vim correlation_heatmap.py
内容は
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# CSVファイル読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
# 相関対象の列だけ抽出
corr_df = df[["gold_price", "cpi", "oil", "usd_jpy"]]
# 相関係数を計算
corr_matrix = corr_df.corr(method="pearson") # 他に "spearman", "kendall" も可能
# 相関係数の表示
print("📊 相関係数:")
print(corr_matrix)
# ヒートマップ描画
plt.figure(figsize=(8, 6))
sns.heatmap(corr_matrix, annot=True, cmap="coolwarm", fmt=".2f", square=True)
plt.title("相関ヒートマップ(金価格・CPI・WTI・ドル円)")
plt.tight_layout()
plt.show()
実行結果は
📊 相関係数:
gold_price cpi oil usd_jpy
gold_price 1.000000 0.919815 0.541180 0.156031
cpi 0.919815 1.000000 0.445084 0.431734
oil 0.541180 0.445084 1.000000 -0.224121
usd_jpy 0.156031 0.431734 -0.224121 1.000000
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 30456 (\N{CJK UNIFIED IDEOGRAPH-76F8}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 38306 (\N{CJK UNIFIED IDEOGRAPH-95A2}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12498 (\N{KATAKANA LETTER HI}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12540 (\N{KATAKANA-HIRAGANA PROLONGED SOUND MARK}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12488 (\N{KATAKANA LETTER TO}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12510 (\N{KATAKANA LETTER MA}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12483 (\N{KATAKANA LETTER SMALL TU}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12503 (\N{KATAKANA LETTER PU}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 65288 (\N{FULLWIDTH LEFT PARENTHESIS}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 37329 (\N{CJK UNIFIED IDEOGRAPH-91D1}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 20385 (\N{CJK UNIFIED IDEOGRAPH-4FA1}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 26684 (\N{CJK UNIFIED IDEOGRAPH-683C}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12539 (\N{KATAKANA MIDDLE DOT}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12489 (\N{KATAKANA LETTER DO}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12523 (\N{KATAKANA LETTER RU}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 20870 (\N{CJK UNIFIED IDEOGRAPH-5186}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 65289 (\N{FULLWIDTH RIGHT PARENTHESIS}) missing from font(s) DejaVu Sans.
plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 30456 (\N{CJK UNIFIED IDEOGRAPH-76F8}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 38306 (\N{CJK UNIFIED IDEOGRAPH-95A2}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12498 (\N{KATAKANA LETTER HI}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12540 (\N{KATAKANA-HIRAGANA PROLONGED SOUND MARK}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12488 (\N{KATAKANA LETTER TO}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12510 (\N{KATAKANA LETTER MA}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12483 (\N{KATAKANA LETTER SMALL TU}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12503 (\N{KATAKANA LETTER PU}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 65288 (\N{FULLWIDTH LEFT PARENTHESIS}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 37329 (\N{CJK UNIFIED IDEOGRAPH-91D1}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 20385 (\N{CJK UNIFIED IDEOGRAPH-4FA1}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 26684 (\N{CJK UNIFIED IDEOGRAPH-683C}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12539 (\N{KATAKANA MIDDLE DOT}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12489 (\N{KATAKANA LETTER DO}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12523 (\N{KATAKANA LETTER RU}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 20870 (\N{CJK UNIFIED IDEOGRAPH-5186}) missing from font(s) DejaVu Sans.
plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 65289 (\N{FULLWIDTH RIGHT PARENTHESIS}) missing from font(s) DejaVu Sans.
plt.show()
となるが表示されるグラフは文字化けをしている
表示されている 文字化けの原因 は、matplotlib(および seaborn)が 日本語フォント(特にCJK漢字やカタカナ)をサポートしていないフォントを使っているため
macOSの場合、ヒラギノ角ゴ ProN や AppleGothic などを使うと安定するらしい
import matplotlib.font_manager as fm
import platform
# 日本語フォント設定(macOS想定)
if platform.system() == 'Darwin': # macOS
plt.rcParams['font.family'] = 'Hiragino Sans'
elif platform.system() == 'Windows':
plt.rcParams['font.family'] = 'Meiryo'
else: # Linux(必要ならIPAフォントなど)
plt.rcParams['font.family'] = 'IPAexGothic'
を
Import文の後に追加すると解決した
次に
金価格・CPI・原油価格・ドル円 を、日付をX軸にして色分けした折れ線グラフで可視化
economic_indicators_time_series.py:
経済指標の時系列データであることを折れ線グラフで表示するスクリプトの作成
vim economic_indicators_time_series.py
内容は
import pandas as pd
import matplotlib.pyplot as plt
import platform
# ✅ 日本語フォント設定(macOSなどで文字化け防止)
if platform.system() == 'Darwin':
plt.rcParams['font.family'] = 'Hiragino Sans'
elif platform.system() == 'Windows':
plt.rcParams['font.family'] = 'Meiryo'
else:
plt.rcParams['font.family'] = 'IPAexGothic'
# 📥 CSVファイル読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)
# 📊 折れ線グラフを描画
plt.figure(figsize=(14, 6))
plt.plot(df["Date"], df["gold_price"], label="金価格", linewidth=2)
plt.plot(df["Date"], df["cpi"], label="CPI", linewidth=2)
plt.plot(df["Date"], df["oil"], label="WTI原油", linewidth=2)
plt.plot(df["Date"], df["usd_jpy"], label="ドル円", linewidth=2)
plt.title("金価格・CPI・WTI原油・ドル円の推移")
plt.xlabel("日付")
plt.ylabel("値")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
これで表示できるけどわかりにくい
株のチャートみたいに 金価格の推移とWTI価格の推移 ドル円レートの推移 CPIの推移が一度にわかるチャートを表示したい
pip install plotly
でインストール
import pandas as pd
from plotly.subplots import make_subplots
import plotly.graph_objects as go
# データ読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)
# サブプロット作成(4行1列)
fig = make_subplots(
rows=4, cols=1, shared_xaxes=True,
subplot_titles=("① 金価格", "② WTI原油価格", "③ ドル円レート", "④ CPI(消費者物価指数)"),
vertical_spacing=0.02
)
# 金価格
fig.add_trace(go.Scatter(x=df["Date"], y=df["gold_price"], name="金価格", line=dict(color='gold')), row=1, col=1)
# 原油価格
fig.add_trace(go.Scatter(x=df["Date"], y=df["oil"], name="WTI原油", line=dict(color='green')), row=2, col=1)
# ドル円
fig.add_trace(go.Scatter(x=df["Date"], y=df["usd_jpy"], name="ドル円", line=dict(color='red')), row=3, col=1)
# CPI
fig.add_trace(go.Scatter(x=df["Date"], y=df["cpi"], name="CPI", line=dict(color='blue')), row=4, col=1)
# レイアウト
fig.update_layout(
height=800,
title="金・原油・ドル円・CPIの推移(マルチチャート)",
showlegend=False,
xaxis4=dict(rangeslider=dict(visible=True)), # ✅ スクロール可能
template="plotly_white"
)
fig.show()
で
表示はできたけど、いまいちわかりにくい
マウスオーバーした時に一番上にマウスオーバーした日時の全ての値を表示するようにしたい
hovermode="x unified", # ✅ ここでマウスオーバー時に全値を表示
を追記
しかしこれだと個々の値にしかならない
なので重ねて表示する
import pandas as pd
import plotly.graph_objects as go
# データ読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)
# 折れ線グラフを1つの図に重ねて表示
fig = go.Figure()
fig.add_trace(go.Scatter(x=df["Date"], y=df["gold_price"], name="金価格", line=dict(color='gold')))
fig.add_trace(go.Scatter(x=df["Date"], y=df["oil"], name="WTI原油", line=dict(color='green')))
fig.add_trace(go.Scatter(x=df["Date"], y=df["usd_jpy"], name="ドル円", line=dict(color='red')))
fig.add_trace(go.Scatter(x=df["Date"], y=df["cpi"], name="CPI", line=dict(color='blue')))
# レイアウト設定
fig.update_layout(
title="金価格・WTI原油・ドル円・CPIの重ね表示チャート",
xaxis_title="日付",
yaxis_title="値",
hovermode="x unified", # ✅ 一括マウスオーバー
template="plotly_white",
height=600,
xaxis=dict(rangeslider=dict(visible=True)) # ✅ スクロール可能
)
fig.show()
これだと全て数値は出るけどグラフが読みにくい
すべて同じグラフに描いても、スケールが違っていて視認しづらい
金価格:2000〜3000(単位:ドル/トロイオンス)
CPI:100〜300
ドル円:100〜150
原油:30〜80
金価格の値が圧倒的に大きく、他の指標が 下に張り付いて見えにくい
解決策:二次Y軸(dual y-axis)または正規化
2軸グラフでスケールの異なる指標を分離表示
Plotlyで金価格とその他を別Y軸で描画する
import pandas as pd
import plotly.graph_objects as go
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)
fig = go.Figure()
# 金価格(左Y軸)
fig.add_trace(go.Scatter(
x=df["Date"], y=df["gold_price"],
name="金価格", line=dict(color='gold'),
yaxis="y1"
))
# その他(右Y軸)
fig.add_trace(go.Scatter(
x=df["Date"], y=df["cpi"],
name="CPI", line=dict(color='blue'),
yaxis="y2"
))
fig.add_trace(go.Scatter(
x=df["Date"], y=df["usd_jpy"],
name="ドル円", line=dict(color='red'),
yaxis="y2"
))
fig.add_trace(go.Scatter(
x=df["Date"], y=df["oil"],
name="WTI原油", line=dict(color='green'),
yaxis="y2"
))
# レイアウト設定
fig.update_layout(
title="金価格(左軸) vs CPI・WTI・ドル円(右軸)",
xaxis=dict(title="日付", rangeslider=dict(visible=True)),
yaxis=dict(title="金価格", side="left"),
yaxis2=dict(title="他指標", overlaying="y", side="right"),
hovermode="x unified",
height=600,
template="plotly_white"
)
fig.show()
これで
📈 金価格は左Y軸
📉 CPI・ドル円・WTIは右Y軸
🖱 マウスオーバーで全ての値を同時に表示
ただしこれだとCPIが飛び出ているのでわかりにくい
CPIはグラフに線としては描かず、マウスオーバー時の数値表示だけにしたい
指標 グラフ表示 マウスオーバー表示
金価格 ✅ 線あり ✅ 値を表示
WTI原油 ✅ 線あり ✅ 値を表示
ドル円 ✅ 線あり ✅ 値を表示
CPI ❌ 線なし ✅ 値のみ表示
CPIは透明な線として追加(表示されないがホバー時は値が出る)
Plotlyでは line=dict(width=0) や opacity=0 を使うことで実現
コードを
import pandas as pd
import plotly.graph_objects as go
# データ読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)
fig = go.Figure()
# 金価格(左軸)
fig.add_trace(go.Scatter(
x=df["Date"], y=df["gold_price"],
name="金価格", line=dict(color='gold'),
yaxis="y1"
))
# WTI原油(右軸)
fig.add_trace(go.Scatter(
x=df["Date"], y=df["oil"],
name="WTI原油", line=dict(color='green'),
yaxis="y2"
))
# ドル円(右軸)
fig.add_trace(go.Scatter(
x=df["Date"], y=df["usd_jpy"],
name="ドル円", line=dict(color='red'),
yaxis="y2"
))
# ✅ CPIを透明線で追加(線は非表示、値だけ表示)
fig.add_trace(go.Scatter(
x=df["Date"], y=df["cpi"],
name="CPI(表示なし)",
line=dict(color='rgba(0,0,0,0)'), # 完全に透明
yaxis="y2",
hoverinfo="x+y+name", # ホバーは有効
showlegend=False # 凡例も非表示
))
# レイアウト設定
fig.update_layout(
title="金価格・WTI・ドル円(CPIは非表示・値のみ)",
xaxis=dict(title="日付", rangeslider=dict(visible=True)),
yaxis=dict(title="金価格", side="left"),
yaxis2=dict(title="WTI・ドル円", overlaying="y", side="right"),
hovermode="x unified",
height=600,
template="plotly_white"
)
fig.show()
として保存
📈 金・WTI・ドル円は見やすく線で表示
🖱 CPIは線は出ないが、マウスオーバーで数値が見える
だいぶわかりやすくなった
次は
正規化して同軸で比較(相対変化に注目)を試す
pip install plotly scikit-learn
でインストール
normalized_economic_indicators_comparison.py
がファイル名
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
import plotly.graph_objects as go
# データ読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)
# 正規化する対象列
columns_to_normalize = ["gold_price", "oil", "usd_jpy", "cpi"]
# 正規化処理
scaler = MinMaxScaler()
df_normalized = df.copy()
df_normalized[columns_to_normalize] = scaler.fit_transform(df[columns_to_normalize])
# グラフ作成(正規化された値で重ね描き)
fig = go.Figure()
fig.add_trace(go.Scatter(x=df["Date"], y=df_normalized["gold_price"], name="金価格", line=dict(color='gold')))
fig.add_trace(go.Scatter(x=df["Date"], y=df_normalized["oil"], name="WTI原油", line=dict(color='green')))
fig.add_trace(go.Scatter(x=df["Date"], y=df_normalized["usd_jpy"], name="ドル円", line=dict(color='red')))
fig.add_trace(go.Scatter(x=df["Date"], y=df_normalized["cpi"], name="CPI", line=dict(color='blue')))
fig.update_layout(
title="正規化された金価格・WTI・ドル円・CPIの相対変動比較",
xaxis_title="日付",
yaxis_title="正規化値(0〜1)",
hovermode="x unified",
xaxis=dict(rangeslider=dict(visible=True)),
template="plotly_white",
height=600
)
fig.show()
として実行
これでだいぶ見やすくなった