みなさん、こんにちは。
今回はHTMLベースのグラフを作成するplotlyを使用して複合グラフの作成の方法をシェアします。
plotlyについて
plotlyとは
今回使用するライブラリは『plotly』です。
pythonでグラフ作成と言えば「matplotlib」を思いつきますが、plotlyはmatplotlibよりもきれいで細やかなグラフが作成出来ます。
matplotlibとの大きな違いとしては、グラフをHTMLベースで出力することが出来ます。Webブラウザに表示されたグラフの上にマウスを載せると下のように値が表示されます(表示している画像はスクリーンショットです)。
ライブラリのインストール
plotlyを下記のコマンドでインストールします。
pip install plotly
準備
作成するグラフ
下記の為替(ドル円とIMMポジション数)の複合グラフを作成します。
折れ線グラフと棒グラフは下記の様にします。
- 棒グラフ・・・・IMMポジション数
- 折れ線グラフ・・・・ドル円レート
- x軸は年月日、左側Y軸はIMMポジション数、右側y軸はドル円レートを表示
データについて
データは外為どっとコムのページからIMMポジションダウンロード[XLS]をダウンロードします。
imm_currency.xlsファイル内のシート「IMMyen」からA列(年月日)、B列(ドル円レート)、I列(IMMポジション数差引)を使用します。
プログラムコード
ではプログラムコードの説明をします。
import pandas as pd
import plotly
xlsfile = "C:/Labo/python/immcurrency.xls"
df_a = pd.read_excel(xlsfile, sheet_name="IMMyen", usecols=[0, 8])
df_b = pd.read_excel(xlsfile, sheet_name="IMMyen", usecols=[0, 1])
df1 = df_a[50:len(df_a)]
df2 = df_b[50:len(df_b)]
graph1 = plotly.graph_objs.Bar(
x=df1.iloc[:, 0],
y=df1.iloc[:, 1],
yaxis="y1",
name="差引数"
)
graph2 = plotly.graph_objs.Scatter(
x=df2.iloc[:, 0],
y=df2.iloc[:, 1],
yaxis="y2",
name="ドル円"
)
adjust1 = (df1.iloc[:, 1].max() - df1.iloc[:, 1].min())/10 / 2
adjust2 = (df2.iloc[:, 1].max() - df2.iloc[:, 1].min())/10 / 2
layout = plotly.graph_objs.Layout(
title="複合グラフ",
xaxis=dict(title="日付"),
yaxis=dict(
title="IMMポジション差引数",
range=[df1.iloc[:, 1].min() - adjust1, df1.iloc[:, 1].max() + adjust1]),
yaxis2=dict(
title="ドル円レート",
range=[df2.iloc[:, 1].min() - adjust2, df2.iloc[:, 1].max() + adjust2],
overlaying="y1", side="right", showgrid=False)
)
data = [graph1, graph2]
fig = plotly.graph_objs.Figure(data=data, layout=layout)
fig.show()
1、2行目 ライブラリのインポート
グラフのデータを扱うために「pandas」と、今回のグラフを描画する「plotly」をインポートします。
5~7行目 データの取り込み
エクセルデータを読み込みます。
棒グラフとしてA列I列、折れ線グラフとしてA列B列のデータフレームを用意します。
df_a = pd.read_excel(xlsfile, sheet_name="IMMyen", usecols=[0, 8])
df_b = pd.read_excel(xlsfile, sheet_name="IMMyen", usecols=[0, 1])
ファイルにはシートが複数あるので、読み取るシートを特定する為にsheet_nameで定義します。
また、2列のデータフレームを作成する為に、特定の列を抽出します。特定の列を抽出する為にはusecolsを使用します。A列I列を抽出するには0列8列、A列B列を抽出するには0列1列を指定します。
10、11行目 データの抜粋
今回データが多いので、50行目から最後の行までのデータを利用します。
df1 = df_a[50:len(df_a)]
df2 = df_b[50:len(df_b)]
14~19行目 棒グラフの設定
graph1 = plotly.graph_objs.Bar(
x=df1.iloc[:, 0],
y=df1.iloc[:, 1],
yaxis="y1",
name="差引数"
)
「plotly.graph_objs.Bar」で棒グラフの設定を行います。
次の行は「df1」のどの列が、x軸の要素、y軸の要素かを定義しています。
「yaxis」は複合グラフを扱うとき、見分けがつくようにy軸の名称を定義します。
「name」はグラフ名になります。
21~26行目 折れ線グラフのデータ設定
graph2 = plotly.graph_objs.Scatter(
x=df2.iloc[:, 0],
y=df2.iloc[:, 1],
yaxis="y2",
name="ドル円"
)
「plotly.graph_objs.Scatter」で折れ線グラフの設定を行います。
次の行は「df2」のどの列が、x軸の要素、y軸の要素かを定義しています。
「yaxis」は複合グラフを扱うとき、見分けがつくようにy軸の名称を定義します。
「name」はグラフ名になります。
29,30行目 Y軸の余白
adjust1 = (df1.iloc[:, 1].max() - df1.iloc[:, 1].min())/10 / 2
adjust2 = (df2.iloc[:, 1].max() - df2.iloc[:, 1].min())/10 / 2
adjust1、adjust2はそれぞれのY軸の最大値、最小値の差の20分の1を定義しています。
これは、のちにグラフを描画する時に、Y軸の上下の余白を持たせるためです。
33~48行目 複合グラフの配置関係の設定
layout = plotly.graph_objs.Layout(
title="複合グラフ",
xaxis=dict(title="日付"),
yaxis=dict(
title="IMMポジション差引数",
range=[df1.iloc[:, 1].min() - adjust1, df1.iloc[:, 1].max() + adjust1]),
yaxis2=dict(
title="ドル円レート",
range=[df2.iloc[:, 1].min() - adjust2, df2.iloc[:, 1].max() + adjust2],
overlaying="y1", side="right", showgrid=False)
)
複合グラフの配置関係の設定は「plotly.graph_objs.Layout」を使用します。
「title」は複合ぐフラフのタイトル名です。
「xaxis=dict(title=””)」で、複合グラフのx軸のタイル名を決めます。
「yaxis=dict(title=””, range=””)」, 「title」で棒グラフの方のy軸の名前、「range」でy軸の高さを決めます。
「yaxis2=dict(title=””, range=””, overlaying=””, side=””, showgrid=””)」で、「title」で折れ線グラフグラフの方のy軸の名前、「range」でy軸の高さを決めます。
「overlaying」はy1(棒グラフ)の上部に表示させる設定です。
「side」はY軸を右側に設定します。
「showgrid」はグラフにグリッド(線)を表示設定です。標準でグリッドが表示され、複合グラフの場合、それぞれのグリッド線が表示され、分かりに行くくなるのでOFFにしています。
51~53 複合グラフのデータ設定、表示
data = [graph1, graph2]
fig = plotly.graph_objs.Figure(data=data, layout=layout)
fig.show()
「plotly.graph_objs.Figure」の「data」で複合グラフの2つの要素を設定し、「layout」で先ほどの複合グラフの配置関係の設定「layout」を代入します。
最後にグラフを表示するために「fig.show()」を実行します。
そうするとブラウザ上にグラフが表示されます。
まとめ
いかがだったでしょうか。
グラフが思った以上にキレイじゃなかったでしょうか。またブラウザ上に表示されたグラフは画像データではないので、グラフ上にマウスを置くとデータが読み取れます。こういうグラフがあれば、グラフを使って説明する時に便利ですよね。
みなさんも、色々と試していてくださいね。
「役に立った!」と思れましたら、下のSNSボタンで記事のシェアをしていただけると嬉しいです!
コメント