Help us understand the problem. What is going on with this article?

[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)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした