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

ipywidgetsでグラフをインタラクティブにする

More than 1 year has passed since last update.

はじめに

データ分析作業をしていると、Jupyterでグラフを作成することがあります。分析の軸やパラメータが複数あると、パラメータごとにグラフを出力して流し見したいときがあります。しかし、データの探索段階ではしっかりグラフを作り込んだりするわけではないので、何度もパラメータを変えてグラフを出力してみる、ということをやります。Jupyterであっても何度もパラメータを変えて実行するのは手間です。

そんなときipywidgetsを使用して、グラフをインタラクティブに表示すると便利です。

参考

環境

  • Python 3.6.5 :: Anaconda, Inc.
  • anaconda==5.2.0
  • jupyter==1.0.0
  • ipywidgets==7.2.1

手順

ipywidgetsはJupyterインストール時に一緒に入っていた?ようです。
jupyterとipywidgetsはインストールされている前提とします。

基本的な使い方

%matplotlib inlineを記載しておきます。interactをインポートします。
グラフの表示部を関数化しておき、interactの第一引数に関数を、以降の引数に関数の引数を渡します。
この「関数の引数」に、一つの値ではなく値の範囲を渡します。するとその範囲のスライダーが生成され、インタラクティブなグラフになります。

下記の例では、k=(0.0,5.0,0.1)の部分で、0から5まで0.1刻みのFloatSliderを作成します。

%matplotlib inline
import matplotlib.pyplot as plt
from ipywidgets import interact
import numpy as np

def f(k):
    x = np.linspace(0, 10, num=1000)
    y = np.sin(k*x)
    plt.plot(x, y)
    plt.show()

interact(f, k=(0.0,5.0,0.1) )

スクリーンショット 2019-01-19 19.32.35.png

上の例では関数の中でデータを生成していますが、下記の例では予め作成した複数のデータをスライダーで切り替えて表示しています。
k=(0,param-1)の第三引数を省略すると整数単位のIntSliderになります。

%matplotlib inline
import matplotlib.pyplot as plt
from ipywidgets import interact
import numpy as np

x = np.linspace(0, 2*np.pi, num=5000)
y = []
param = 50

for i in range(1,param+1):
    y.append([np.sin(i*j) for j in x])

def f(k):
    plt.plot(x, y[k])
    plt.show()

interact(f, k=(0,param-1) )

スクリーンショット 2019-01-19 19.37.28.png

デコレータを使用した表示

グラフを表示する関数をinteractでデコレーションするだけでもグラフを表示できます。
Jupyterでは関数を呼び出さず、下記そのままを実行するとグラフが表示されます。

%matplotlib inline
import matplotlib.pyplot as plt
from ipywidgets import interact
import numpy as np

x = np.linspace(0, 2*np.pi, num=5000)
y = []
param = 50

for i in range(1,param+1):
    y.append([np.sin(i*j) for j in x])

@interact(k=(0,param-1))
def f(k):
    plt.plot(x, y[k])
    plt.show()

グラフを複数表示

単純に二回記載すればグラフを2個表示できます。

%matplotlib inline
import matplotlib.pyplot as plt
from ipywidgets import interact
import numpy as np

x = np.linspace(0, 2*np.pi, num=5000)
y1, y2 = [], []

param = 50

for i in range(1,param+1):
    y1.append([np.sin(i*j) for j in x])
    y2.append([np.cos(i*j)+np.cos(j) for j in x])

@interact(k=(0,param-1))
def f1(k):
    plt.plot(x, y1[k])
    plt.show()

@interact(k=(0,param-1))
def f2(k):
    plt.plot(x, y2[k])
    plt.show()

スクリーンショット 2019-01-19 19.43.40.png

選択肢の表示

関数の引数が数値でない場合はDropdown形式になります。

%matplotlib inline
import matplotlib.pyplot as plt
from ipywidgets import interact
import numpy as np

x = np.linspace(0, 2*np.pi, num=5000)
y1, y2 = [], []

param = 50

for i in range(1,param+1):
    y1.append([np.sin(i*j) for j in x])
    y2.append([np.cos(i*j)+np.cos(j) for j in x])

@interact(k=(0,param-1), mode=['A','B'])
def f(k,mode):
    if mode=='A':
        plt.plot(x, y1[k])   
    elif mode=='B':        
        plt.plot(x, y2[k])
    else:
        print('Error')

    plt.show()

スクリーンショット 2019-01-19 19.49.13.png

subplotを用いた表示

subplotでも使用できます。

%matplotlib inline
import matplotlib.pyplot as plt
from ipywidgets import interact
import numpy as np

x = np.linspace(0, 2*np.pi, num=5000)
y, y1, y2, y3 = [], [], [], []

param = 50

for i in range(1,param+1):
    y1.append([np.sin(i*j) for j in x])
    y2.append([np.cos(i*j)+np.cos(j) for j in x])
    y3.append([np.tan(i*j)+np.cos(j) for j in x])

y = [y1, y2, y3]

# グラフを作る
@interact(k=(0,param-1))
def f(k):
    fig = plt.figure(figsize=(17,4))

    # タイトルを配列に格納
    title=['title1','title2','title3']    

    # グラフ間の幅を調整
    plt.subplots_adjust(wspace=0.25, hspace=0.6)

    for i in range(3):
        ax = fig.add_subplot(1, 3, i+1)
        ax.plot(x, y[i][k])
        ax.set_xlabel('x-axis label') # x軸のラベル
        ax.set_ylabel('y-axis label') # y軸のラベル
        ax.set_title(title[i]) # タイトル

    plt.show()

スクリーンショット 2019-01-19 20.33.19.png

次のように書いても表示できます。

%matplotlib inline
import matplotlib.pyplot as plt
from ipywidgets import interact
import numpy as np

x = np.linspace(0, 2*np.pi, num=5000)
y, y1, y2, y3 = [], [], [], []

param = 50

for i in range(1,param+1):
    y1.append([np.sin(i*j) for j in x])
    y2.append([np.cos(i*j)+np.cos(j) for j in x])
    y3.append([np.tan(i*j)+np.cos(j) for j in x])

y = [y1, y2, y3]

# グラフを作る
@interact(k=(0,param-1))
def f(k):
    # 3つのグラフを配置する枠をつくる 
    fig,ax = plt.subplots(1,3,figsize=(17,4))

    # タイトルを配列に格納
    title=['title1','title2','title3']

    # グラフ間の幅を調整
    plt.subplots_adjust(wspace=0.25, hspace=0.6)

    for i in range(3):
        ax[i].plot(x, y[i][k])
        ax[i].set_title(title[i]) # タイトル
        ax[i].set_xlabel('x-axis label') # x軸のラベル
        ax[i].set_ylabel('y-axis label') # y軸のラベル

    plt.show()

スクリーンショット 2019-01-19 20.40.55.png

縦バージョン。

%matplotlib inline
import matplotlib.pyplot as plt
from ipywidgets import interact
import numpy as np

x = np.linspace(0, 2*np.pi, num=5000)
y, y1, y2, y3 = [], [], [], []

param = 50

for i in range(1,param+1):
    y1.append([np.sin(i*j) for j in x])
    y2.append([np.cos(i*j)+np.cos(j) for j in x])
    y3.append([np.tan(i*j)+np.cos(j) for j in x])

y = [y1, y2, y3]

# グラフを作る
@interact(k=(0,param-1))
def f(k):
    fig = plt.figure(figsize=(10,10))

    # タイトルを配列に格納
    title=['title1','title2','title3']    

    # グラフ間の幅を調整
    plt.subplots_adjust(wspace=0.2, hspace=0.6)

    for i in range(3):
        ax = fig.add_subplot(3, 1, i+1)
        ax.plot(x, y[i][k])
        ax.set_xlabel('x-axis label') # x軸のラベル
        ax.set_ylabel('y-axis label') # y軸のラベル
        ax.set_title(title[i]) # タイトル

    plt.show()

スクリーンショット 2019-01-19 20.47.26.png

おわりに

ipywidgetsを使用して、グラフをインタラクティブに表示できました。

ipywidgetsは他にもプログレスバーやチェックボックス、ラジオボタンなど様々なwidgetが用意されています。notebookをインタラクティブ化して効率的な可視化を行っていきましょう!

ground0state
「小さいネタでもoutput」をモットーに小ネタ投稿していきます。 統計検定準1級/G検定2018#2/IoTエキスパート/Signate/kaggle/AWS/Serverless
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
ユーザーは見つかりませんでした