Efficient interactive Matplotlib plots in Jupyter notebooks


In [ ]:
%matplotlib notebook

In [ ]:
%matplotlib notebook

In [ ]:
import numpy as np
import matplotlib.pyplot as plt

import time

import ipywidgets
from ipywidgets import interact

The simplest and slowest solution

This solution drop everything between each update.


In [ ]:
@interact(t=(0, 100, 1))
def plot(t):
    fig = plt.figure()
    ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))
    
    x = np.linspace(0, 2, 100)
    y = np.sin(2. * np.pi * (x - 0.01 * t))
    ax.plot(x, y, lw=2)

Better but still slow...

In this solution, the figure is kept, only the Axes is dropped.


In [ ]:
fig = plt.figure()
ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))
    
@interact(t=(0, 100, 1))
def plot(t):
    plt.cla()
    
    x = np.linspace(0, 2, 100)
    y = np.sin(2. * np.pi * (x - 0.01 * t))
    ax.plot(x, y, lw=2)

The complicated but fastest solution

In this solution, artists are kept (Line2d here), only their data is changed (like in Matplotlib animations).


In [ ]:
fig = plt.figure()
ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))
line, = ax.plot([], [], lw=2)

def init():
    line.set_data([], [])
    return line,

def update(frame):
    x = np.linspace(0, 2, 100)
    y = np.sin(2. * np.pi * (x - 0.01 * frame))
    line.set_data(x, y)
    return line,

@interact(t=(0, 100, 1))
def plot(t):
    update(t)
    
    fig.canvas.draw()
    fig.canvas.flush_events()