46
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-01-19

はじめに

データ分析作業をしていると、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をインタラクティブ化して効率的な可視化を行っていきましょう!

46
35
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?