著者が語るJupyter本の読みどころ

ご縁があって、 PythonユーザのためのJupyter[実践]入門 という書籍を共著で執筆させていただきました。

本記事では本書の読みどころなどについて、勢いに任せた乱筆ですがつらつらと語っていきたいと思います。

本書の目的

本書の3ページ「はじめに」を全文掲載します。まさにここに書かれていることが本書を読む動機となると思います。書店などで本書を手にとってパラパラ見ていだければ雰囲気はつかめると思います。

本書は、「Jupyter Notebook」の使い方と「データの可視化」にフォーカスを当てた書籍です。 Jupyter NotebookはPythonで実装されたオープンソースソフトウェア(OSS)です。Jupyter Notebookはデータ分析ツールとして、あるいはPythonの学習環境として多くのユーザに利用されています。

Jupyter Notebookは、データの加工や集計処理を得意とするパッケージ「pandas」や、グラフ描画パッケージ「Matplotlib」および「Bokeh」などと組み合わせて利用できます。「データの可視化」 にJupyter Notebookが活用されるのはこのためです。Jupyter Notebookは人気のツールであり、 インターネット上には既に可視化に関する多くのドキュメントやサンプルコードが存在します。 しかし私たちはJupyter Notebookを日々利用しながら「Jupyter Notebookの活用とデータ可視化における実践例や知見が集まった場所が少ない」と考えていました。

Jupyter Notebookは、インストールしてすぐに使い始められる手軽なツールですが、それだけに、キーボード・ショートカットや設定ファイルによるカスタマイズなど、便利な使い方を知らないまま利用している場合があります。Matplotlibを使ったデータ可視化を行うにあたり、同じグラフを描画するために複数の方法が存在するために、どの方法を採用したらよいか戸惑う場合があります。日本語の文字化けもしばしば問題になります。私たちはPythonやJupyter Notebookのユーザと交流をする中で、少なくないユーザが同じ課題を抱えていることを知りました。

本書はPythonを使ったデータ分析に興味があり、これからツールの使い方を学ぼうと考えている新規ユーザから、すでに日常的にJupyter Notebookを利用している既存ユーザまで、幅広い層に向けて書かれています。新規ユーザーは本書を通読することで、Jupyter Notebook上でデータ 加工や集計を行ったり、さまざまなグラフを描画したりといったことが行えるようになるでしょう。既存ユーザーは、グラフ描画パッケージに対する理解を更に深められるはずです。Jupyter Notebookの設定についても新たな発見があるかも知れません。

本書がわずかでもPythonやJupyter Notebookの魅力を広める役割を果たし、読者のみなさま に有益な情報を届けられることを願ってやみません。

2017年 著者一同

第1章 Jupyter Notebook を導入しよう

いわゆる環境構築の章です。紙面の都合上、Anaconda からの導入手順のみが記載されていますが。公式のPythonから導入していただいても問題ありません。
注意いただきたい点として、本書では使用するパッケージのバージョンを指定しているため、コードを試す際には仮想環境の構築をおすすめします。

1-4 日本語フォント環境の準備

matplotlib について聞かれることのダントツ一位が、「この豆腐なんとかならない?」です。 本節ではフォントのインストールから、matplotlibのコード上でフォントを設定する方法、環境変数でフォントを設定する方法などについて解説しています。 この情報が体系的にまとまっているところはなかなかないのではないでしょうか。

第8章 Jupyter Notebook をカスタマイズしよう

カスタマイズを先にやりたいかたは次にこの章を読み進めるのがよいかもしれません。
個人的におすすめなのは、フォントの設定をこの時点でやっておくことです。
ブラウザによってはデフォルトで等幅でないフォントになっていることもあり、設定をしておくことでコードの可読性がよくなります。本書がおすすめするフォントについても記載されています。

第2章 Jupyter Notebook の操作を学ぼう

キーボードショートカットやマジックコマンドなどについて解説しています。意外と知られていない機能などがあったりするので、Jupyter をある程度使っているかたでも有用な情報が入っているのではないでしょうか。

第3章 pandas でデータを処理しよう

pandas を初めて使うかたを前提に解説していますが、基礎的なことをもう一度確認したいかたにもそれなりに楽しんでいただける内容かと思います。
紙面の都合上、主要な機能や可視化の前処理で必要な処理をメインとしています。更に pandas を学びたいかたは 公式ドキュメントPythonによるデータ分析入門 などを参考にしていただければと。

本書ではサンプルデータとして、アニメのデータベースサイトから抜き出したデータと、アニメ制作会社の株価データを扱います。^1, ^2
誰もが知っている有名な作品やちょっとマニアックな作品名も出てきます。
アニメ好きなかたは本書のデータと処理方法を応用して、独自の分析をすると面白い結果が出てくるかもしれません。

In [1]:
import os
import pandas as pd

base_url = 'https://raw.githubusercontent.com/practical-jupyter/sample-data/master/anime/'
anime_csv = os.path.join(base_url, 'anime.csv')
pd.read_csv(anime_csv).head()
Out[1]:
anime_id name genre type episodes rating members
0 32281 Kimi no Na wa. Drama, Romance, School, Supernatural Movie 1 9.37 200630
1 5114 Fullmetal Alchemist: Brotherhood Action, Adventure, Drama, Fantasy, Magic, Mili... TV 64 9.26 793665
2 28977 Gintama° Action, Comedy, Historical, Parody, Samurai, S... TV 51 9.25 114262
3 9253 Steins;Gate Sci-Fi, Thriller TV 24 9.17 673572
4 9969 Gintama' Action, Comedy, Historical, Parody, Samurai, S... TV 51 9.16 151266
In [2]:
anime_stock_price_csv = os.path.join(base_url, 'anime_stock_price.csv')
pd.read_csv(anime_stock_price_csv, index_col=0, parse_dates=['Date']).head()
Out[2]:
TOEI ANIMATION IG Port
Date
2015-01-01 3356.86 1201.51
2015-01-02 3356.86 1201.51
2015-01-05 3396.12 1218.44
2015-01-06 3361.77 1201.51
2015-01-07 3297.97 1202.51

本書の物語はこのファイルから始まります。
このファイルに対して加工・集計・欠損値の処理などを3章で行い、このデータを元に4-7章でデータを可視化します。

また、3章では pandas からデータを可視化する方法についても解説しています。
下記のように凡例を外に出すような、サラッと出てこない設定についても触れています。

In [3]:
# 単にplotメソッドを呼び出すとこんな感じになってしまう

import matplotlib.pyplot as plt

plt.style.use('ggplot')
anime_genre_top10_pivoted_csv = os.path.join(base_url, 'anime_genre_top10_pivoted.csv')
anime_genre_top10_pivoted_df = pd.read_csv(anime_genre_top10_pivoted_csv, index_col=0)
anime_genre_top10_pivoted_df.plot.bar(logy=True)
plt.show()
In [4]:
ax = anime_genre_top10_pivoted_df.plot.bar(logy=True)
ax.legend(bbox_to_anchor=(1, 1))
plt.show()

第4章 Matplotlib でグラフを描画しよう

Jupyter 本 ですが、実は本書のメインコンテンツと言ってよいのかもしれません。

In [ ]:
fig = plt.figure()
ax = fig.add_subplot(111)

上記のようなコードをよく見かけるけど、実はなにをやってるかわからない・・・と思っているかたが意外と多いのではないでしょうか。
かくいう私も matplotlib を触り始めたときはなんのこっちゃっという感じでした。

4章を読むことで基礎から matplotlib についてしっかりと学ぶことができます。

余談ですが、4章ではヒストグラムの書き方が妙に充実しています。著者の趣味ですかね?
下記はヒストグラムの例です。

In [5]:
import numpy as np

anime_master_csv = os.path.join(base_url, 'anime_master.csv')
df = pd.read_csv(anime_master_csv, index_col='anime_id')

types = df['type'].unique()
labels = types.tolist()
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111)
b_num = np.arange(0, 10.5, 0.5)
for t in types:
    ax.hist(df.loc[df['type'] == t, 'rating'],
            bins=b_num,
            rwidth=0.9,
            alpha=0.5,
            label=t)
ax.legend()
ax.set_xlabel('rating')
ax.set_ylabel('Count(rating)')
plt.show()

第5章 Matplotlib を使いこなそう

あれ?軸を設定するのってどうするんだっけ?グラフの線を点線にするのどうするんだっけ? -> その都度ググる
これ経験ありますよね?5章では matplotlib の細かい設定周りを詳しく解説しています。
なんと 3,564円で matplotlib のやり方をいちいち探す苦労から解放されます。安い!

下記はグラフに描画するテキストの位置を設定した例です。

In [6]:
plt.style.use('default')

fig = plt.figure(figsize=(8, 3))
ax = fig.add_subplot(111)

# ベースライン描画
x, y = [0, 9], [0.5, 0.5]
ax.plot(x, y)

# テキストボックスの描画(垂直方向の配置)
ax.text(0, 0.5, 'bottom', verticalalignment='bottom', size=20)
ax.text(2.5, 0.5, 'baseline', verticalalignment='baseline', size=20)
ax.text(5.5, 0.5, 'center', verticalalignment='center', size=20)
ax.text(8, 0.5, 'top', verticalalignment='top', size=20)
ax.set_xticks([i * 3 for i in range(4)])
ax.set_yticks([0.5 * i for i in range(3)])
plt.show()

また、5章では本書が推奨するコーディングスタイルについて触れています。
matplotlib は MATLAB の影響を受けてることから、構文が Python ユーザにとってわかりにくい場合があります。^3
「このようにコードを書いたらわかりやすいよ」という提案をしているので、matplotlib をスッキリ書きたいというかたは是非読んでみて見てください。

第6章 Bokeh でグラフを描画しよう

前述のように、「matplotlib はトリッキーでわかりにくい」というかたは Bokeh を使ってみるという手もありかもしれません。
Notebook 上でグリグリ操作できるというのも利点です。

下記では簡単な例です。右にあるツールバーを操作してグリグリやって見てください。

In [7]:
from bokeh.plotting import output_notebook, figure, show

output_notebook()
p = figure(plot_width=200, plot_height=200)
p.line([1, 2], [1, 2])
p.circle([1.5], [1.5])
show(p)
Loading BokehJS ...

下記のように少し凝ったグラフの作り方も解説しています。本当はもっとたくさんあったのですが、ページ数の都合で割愛しました。機会があれば本ブログで紹介します。

In [8]:
from bokeh.palettes import d3

top10_df = pd.read_csv(os.path.join(base_url, 'anime_genre_top10.csv'))

# ジャンルをメンバ数で集計
genre = top10_df.groupby('genre')['members'].sum().sort_values()
p = figure(
    title='メンバ数が多いジャンルトップ10',
    plot_width=400, plot_height=400,
    x_range=(0, genre.max()),
    y_range=(-0.5, len(genre) - 0.5))

text_x = genre.min() * 0.1  # 注釈のX座標
colors = d3['Category20b'][10][::-1]  # カラーパレット(7章で解説)

# 枠、 罫線、 軸をすべて非表示
p.outline_line_color = None
p.grid.visible = False
p.axis.visible = False

for i, g in enumerate(genre):
    text = ': '.join((genre.index[i], '{:,}'.format(g)))
    p.hbar(y=i, left=0, right=g, height=1, color=colors[i])
    p.text(
        x=text_x,
        y=i,
        text=[text],
        text_color='#ffffff',
        text_font_size='10pt',
        text_font_style='bold',
        text_baseline='middle')
show(p)

第7章 Bokehを使いこなそう

5章と同様に、Bokeh の細かい設定についてこれでもかというくらいに盛り込んでいます。
Bokeh については 6章よりも 7章を特に読み込んでいただくことで、色々と応用が効くグラフが作れるようになります。

下記のようなツールチップを実装することができます。グラフ上の点にカーソルを当ててみてください。

In [9]:
from bokeh.models import HoverTool
import os
import pandas as pd

anime_master_csv = os.path.join(base_url, 'anime_master.csv')
df = pd.read_csv(anime_master_csv)
hover = HoverTool(tooltips=[
    ("index", "$index"),
    ("(x, y)", "($sx, $sy)"),
    ("name", "@name"),
    ("genre", "@genre"),
    ("members", "@members{0,0}"),  # カンマ区切り
    ("rating", "@rating"),
])
p = figure(tools=[hover])
p.circle('members', 'rating', source=df)
show(p)