EC2上にJupyterLab環境を作りグラフ描画とS3接続を行う

2021.02.22

はじめに

データアナリティクス事業本部のkobayashiです。

先日EC2上にJupyterLabの環境を作る機会が有りましたのでその作業内容をまとめたいと思います。

環境

  • Ubuntu Server 20.04 LTS (HVM), SSD Volume Type - ami-0f2dd5fc989207c82 (64 ビット x86)

EC2上にJupyterLab環境を構築する

今回作成するJupyterLabでは

  • matplotlibで描画したグラフをmatplotlib widgetでインタラクティブに操作する
  • S3上のファイルを扱うといった

要件がありましたのでJupyterLabのインストールに併せて必要なモジュールのインストールも行っていきます。

JupyterLab Documentation — JupyterLab 3.0.6 documentation

JupyterLabのインストールをする

初めにパッケージのアップデートを行い、pipをインストールします。

$ sudo apt update
$ sudo apt install -y python3-pip

次にJupyterLabと分析に必要な最低限のモジュール、matplotlib描画に必要なモジュール、s3への接続に必要なモジュールをインストールします。

$ pip3 install jupyterlab
$ pip3 install numpy pandas matplotlib seaborn scikit-learn ipympl fsspec s3fs

またjupyterをインストールした際にパスを通す必要があるので通します。

$ export PATH="$HOME/.local/bin:$PATH"

matplotlibでグラフ描画を行う際にJupyterのextensionをインストールする必要があります。またその際にversion12以上のNode.jsも要求されるのでインストールします。

aptでnodejsとnpmをインストールし、Nodeのパッケージ管理ツールのnをインストールしたあとに最新の安定版のnodejsを入れ、aptで初めインストールしたnodejsとnpmをアンインストールします。

$ sudo apt install -y nodejs npm
$ sudo npm install n -g
$ sudo n stable
$ sudo apt purge -y nodejs npm

Node.jsがインストールできたのでJupyterのextensionを入れます。

$ jupyter labextension install @jupyter-widgets/jupyterlab-manager
$ jupyter labextension install jupyter-matplotlib

これで必要なモジュールがJupyterLabで使えるようになりましたので次にJupyterLabの設定を行います。

JupyterLabの起動設定とサービス化を行う

JupyterLabを使う際に毎回トークン接続ですと大変ですのでPasswordを設定します。またJupyterLabをサービス化してsystemdで自動起動を行います。

パスワードをハッシュ化してjupyter_notebook_config.jsonに保存します。

$ jupyter notebook password
$ cat /home/ubuntu/.jupyter/jupyter_notebook_config.json
{
  "ServerApp": {
    "password": "sha1:2308c7b108ea:a0544527fddd3ba6baeed2000933333c13eb341a"
  }

パスワードのハッシュ値をJupyterLabの設定ファイルに書き込みます。また併せて起動時の設定を行います。

$ jupyter lab --generate-config
$ vi ~/.jupyter/jupyter_lab_config.py
# ファイルへ追記
c = get_config()
c.IPKernelApp.pylab = 'inline'
c.NotebookApp.ip = '0.0.0.0'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8888
c.NotebookApp.password = 'sha1:2308c7b108ea:a0544527fddd3ba6baeed2000933333c13eb341a'

上記で設定した内容は上から以下の通りになります。

  • matplotlibで描画したものがnotebook上で表示
  • すべてのIPから接続許可
  • JupyterLab起動時にブラウザを起動しない
  • 接続ポートを8888に設定
  • JupyterLabへのログインパスワードを設定

続けてJupterLabをサービス化してsystemdで自動起動を行います。

$ sudo vi /etc/systemd/system/jupyter.service

[Unit]
Description = Jupyter Lab

[Service]
Type=simple
PIDFile=/var/run/jupyter-lab.pid
ExecStart=/home/ubuntu/.local/bin/jupyter-lab
WorkingDirectory=/home/ubuntu
User=ubuntu
Group=ubuntu
Restart=always

[Install]
WantedBy = multi-user.target

$ sudo systemctl start jupyter.service
$ sudo systemctl enable jupyter.service

これで設定は終わりです。

では実際にJupyterLabでグラフの描画とS3への接続を試してみます。

JupyterLabでグラフ描画とS3接続を行う

matplotlibでグラフを描画する

extensionをインストールしてあるのでJupyterLab上でコードを書いて実行するだけです。 matplotlibのデモを実行してみます。

mplot3d example code: contourf3d_demo2.py — Matplotlib 1.2.1 documentation

%matplotlib widget

"""
.. versionadded:: 1.1.0
   This demo depends on new features added to contourf3d.
"""

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm

fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y, Z = axes3d.get_test_data(0.05)
ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3)
cset = ax.contourf(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm)
cset = ax.contourf(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm)
cset = ax.contourf(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm)

ax.set_xlabel('X')
ax.set_xlim(-40, 40)
ax.set_ylabel('Y')
ax.set_ylim(-40, 40)
ax.set_zlabel('Z')
ax.set_zlim(-100, 100)

plt.show()

matplotlib widgetで拡大・縮小・回転を行うなどインタラクティブに操作することができます。

S3上のファイルを扱う

S3上にあるcsvファイルをpandasのread_csvメソッドで読み込みます。

その際に対象となるファイルへのアクセス権を用意する必要がありますが、これはJupyterLabを動かしているEC2に対象となるファイルを扱えるようなロールを割り当てることでpandasのread_csvメソッドでS3上のファイルを扱えます。したがって事前準備としてIAMロールを作成しEC2に割り当てておきます。

準備が整ったらコードを書いて実行します。

import pandas as pd

df = pd.read_csv('s3://{バケット名}/13TOKYO_utf8.csv')
df

S3上のcsvファイルを取得できていることが確認できます。

まとめ

EC2上にJupyterLab環境を構築し、matplotlibでグラフを描画したり、 S3上のファイルを扱ってみました。特にハマる箇所もなくスムーズに環境構築が行えました。

最後まで読んで頂いてありがとうございました。