Edited at

[Python] Plotlyでぐりぐり動かせるグラフを作る


はじめに

Pythonから利用できるライブラリ、Plotlyの初歩的な使い方を記述します。

リンク先のサンプルを見るとわかるように、Plotlyを用いると、非常に多くの種類の、ぐりぐり動かせるグラフを作ることができます。

なお、Plotlyには、作成したグラフをWeb上で編集したり、公開したりできる機能がありますが、

今回はすべてローカルで実行することとします。


実行環境


  • Windows 10

  • Python 3.5.2(Anaconda)

  • Jupyter notebook


インストール

pip install plotlyでPlotlyをインストールします。


データの取り込み

例として、Wikipediaから拾ってきた、日本の年ごとの出生数と出生率のデータをグラフ化してみます。

下記データをbirth.csvとしたものを、Jupyterのファイルと同一フォルダに置きます。

year,births,birth rate

2000,1190547,1.36
2001,1170662,1.33
2002,1153855,1.32
2003,1123610,1.29
2004,1110721,1.29
2005,1062530,1.26
2006,1092674,1.32
2007,1089818,1.34
2008,1091156,1.37
2009,1070035,1.37
2010,1071304,1.39
2011,1050806,1.39
2012,1037101,1.41
2013,1029816,1.43
2014,1003532,1.42
2015,1005656,1.46

データの取り込みや操作には、Pandasを用いると便利です。

Pandasは、Anacondaをインストールすると自動的に入っています。

import pandas as pd

raw = pd.read_csv("birth.csv")


グラフの作成


初期化

まず、Jupyter内部でプロットするために、下記コードを実行します。Jupyter内部で表示しない場合には不要です。

引数にある、connectedTrueにすると、PlotlyのJavascriptをインターネットから取得するようになります。

import plotly

plotly.offline.init_notebook_mode(connected=False)


プロットするデータの指定

続いて、プロットするデータを指定します。

今回、出生数は棒グラフ、出生率は折れ線グラフで表現します。

dataという配列を用意し、棒グラフだったらplotly.graph_objs.Bar

折れ線グラフだったらplotly.graph_objs.Scatterに、X軸やY軸のデータ、系列名を指定します。

yaxis="y2"と指定することで、第2軸にプロットすることができます。

data = [

plotly.graph_objs.Bar(x=raw["year"], y=raw["births"], name="Births"),
plotly.graph_objs.Scatter(x=raw["year"], y=raw["birth rate"], name="Birth Rate", yaxis="y2")
]


グラフレイアウトの指定

次に、グラフのレイアウトを指定します。グラフのタイトルや、凡例の位置、第2軸を設定します。

layout = plotly.graph_objs.Layout(

title="Births and Birth Rate in Japan",
legend={"x":0.8, "y":0.1},
xaxis={"title":"Year"},
yaxis={"title":"Births"},
yaxis2={"title":"Birth Rate", "overlaying":"y", "side":"right"},
)


プロット

Jupyter内で表示したい場合には、iplotを呼んで、グラフを作成します。

Jupyter外部で表示する場合や、HTMLを作成したい場合には、plotを呼びます。オプションでファイル名を指定しない場合には、同一フォルダにtemp-plot.htmlが作成されます。

fig = plotly.graph_objs.Figure(data=data, layout=layout)

plotly.offline.iplot(fig)
#plotly.offline.plot(fig)

こんな感じのグラフが出来上がります。

aa.gif

簡単な操作方法はこちら


  • グラフ内でドラッグすると、X軸方向、Y軸方向、矩形に拡大

  • X軸、Y軸上でドラッグすると、軸方向に移動

  • ダブルクリックすると、初期表示に戻る

  • ツールバーのボタンを押して画像として保存


その他オプション


グラフエリアの大きさ

layout = plotly.graph_objs.Layout(

width=800, height=600,
)


軸の最大値最小値

単に最大最小値を設定する場合は、axisrangeオプションを指定します。

ゼロから目盛りを始めたい場合や、負数を表示したくない場合には、

rangemodeオプションに"tozero""nonnegative"を指定します。

layout = plotly.graph_objs.Layout(

xaxis={"title":"Year", "range": [2010, 2016]}, #from year 2010 to 2016
yaxis={"title":"Births", "rangemode":"tozero"}, #starts from zero
)


フォント

font-familyはCSSで指定するのと同じようにします。

layout = plotly.graph_objs.Layout(

font={"family":"Yu Gothic Bold, sans-selif", "size":20},
)


そのほか

そのほか、Plotlyでは細かい部分まで指定することができます。

これらオプションについては、Plotlyのサイトを見たり、googleで検索してみましょう。


ツールバーの不要なボタンや「Edit in Plotly」の削除

ローカル外に漏らしたくないデータの場合、作成したグラフに、「Save and edit plot in cloud」や「Ploduced with Plotly」のボタンや、「Export to plot.ly」のリンクが存在するのは、気持ちのいいものではないです。そこで、これらを表示させないようにします。

buttons.png

まず、プロット時にshow_link=Falseを指定することで、「Export to plot.ly」を消すことができます。

plotly.offline.iplot(fig, show_link=False)

#plotly.offline.plot(fig, show_link=False)

一方、ツールバーのボタンの表示を消すオプションは、StackOverflowの投稿関連するプルリクエストがマージされていない状況を見る限り、存在しないようです。そこで、init_notebook_modeで読み込まれる、Plotlyのフォルダ内のplotly.min.jsを編集する方法をとります。

いつの間にかiplotの引数で渡せるようになっていました。

plotly.offline.iplot(fig, show_link=False, config={"displaylogo":False, "modeBarButtonsToRemove":["sendDataToCloud"]})

とすることで、消すことができます。


PandasのDataframeのプロット

Cufflinksというライブラリを利用すると、df.iplot()と書くだけでDataframeのPlotlyのグラフを描くことができます。

[Python] CufflinksでPandasのデータフレームをPlotlyに一発描画を参照ください。


matplotlibのPlotly化

matplotlib.pyplotで書いたグラフを、iplot_mpl(fig)と打つだけでPlotlyのインタラクティブなグラフへ変更することができます。

import matplotlib.pyplot as plt

import plotly.offline

plotly.offline.init_notebook_mode()

fig = plt.figure()
plt.plot([1,3,4,2,1,3])
plotly.offline.iplot_mpl(fig)

ただ、凡例を入れたい場合にはひと手間加える必要があるなど、まだ開発途中といったところでしょうか。

import matplotlib.pyplot as plt

import plotly.offline
import plotly.tools

plotly.offline.init_notebook_mode()

fig = plt.figure()
plt.plot([1,3,4,2,1,3], label="legend")
plt.title("title")
# plt.legend()は要らない
plotly_fig = plotly.tools.mpl_to_plotly( fig )
plotly_fig['layout']['showlegend'] = True
plotly.offline.iplot(plotly_fig, show_link=False)


(ひとまず折れ線グラフを描きたいときのコピペ用)

import plotly

plotly.offline.init_notebook_mode()
data = [
plotly.graph_objs.Scatter(y=[2,3,1,2,5,2], name="legend"),
plotly.graph_objs.Scatter(x=[1,2,3,4,5,6], y=[1,2,3,2,3,1], name="legend2"),
]
layout = plotly.graph_objs.Layout(
title="title",
xaxis={"title":"xlabel"},
yaxis={"title":"ylabel"},
)
fig = plotly.graph_objs.Figure(data=data, layout=layout)
plotly.offline.iplot(fig, show_link=False)