Some Simple Illustrations of Plotting with Matplotlib

In [1]:
from __future__ import print_function
%matplotlib inline

import numpy as np
from matplotlib import pyplot as plt

First, the wave equation:

In [2]:
def wave(x, t):
    return 0.8*np.sin(4*np.pi*(x - t))
In [3]:
fig = plt.figure(1, (4,4))
axes = fig.gca()

x = np.linspace(0, 2, 100)

axes.plot(x, wave(x, 0))
Out[3]:
[<matplotlib.lines.Line2D at 0x1084b61d0>]
In [4]:
from matplotlib import animation
from matplotlib.patches import Circle


frames = 100
axes.cla()
axes.set_ylim(-1, 1)
axes.set_xlim(0, 2)

ball_r = 0.05
ball_x = 0.3

def init():
    global p, b
    [p] = axes.plot(x, wave(x, 0))
    b = Circle((ball_x, wave(ball_x, 0)), radius=ball_r, facecolor='green')
    axes.add_patch(b)
    return [p, b]

def animate(i):
    t = i / 120.0
    p.set_ydata(wave(x, t))
    b.center = ball_x, wave(ball_x, t)
    return [p, b]

anim = animation.FuncAnimation(fig, animate, 
                               init_func=init,
                               frames=frames, 
                               blit=True)

Some code so that we can dislpay the video inline.

In [5]:
from IPython.display import HTML
from tempfile import NamedTemporaryFile

VIDEO_TAG = """<video controls>
 <source src="data:video/x-m4v;base64,{0}" type="video/mp4">
 Your browser does not support the video tag.
</video>"""

def display_anim(anim, fps=20):
    if not hasattr(anim, '_encoded_video'):
        with NamedTemporaryFile(suffix='.mp4') as f:
            anim.save(f.name, fps=10, extra_args=['-vcodec', 'libx264', '-pix_fmt','yuv420p'])
            video = open(f.name, "rb").read()
        anim._encoded_video = video.encode("base64")
    return HTML(VIDEO_TAG.format(anim._encoded_video))

And here we go.

In [6]:
display_anim(anim, fps=30)
Out[6]:

Now, a clock

In [7]:
fig = plt.figure(1, (4,4))
axes = fig.gca()
axes.set_frame_on(False)
axes.get_xaxis().set_visible(False)
axes.get_yaxis().set_visible(False)
axes.set_xlim(-1.2, 1.2)
axes.set_ylim(-1.2, 1.2)
for i in range(1, 13):
    theta = np.pi/2 - i * np.pi / 6
    x = np.cos(theta)
    y = np.sin(theta)
    axes.text(x, y, str(i), horizontalalignment='center', verticalalignment='center')
In [8]:
from matplotlib.lines import Line2D
from matplotlib import animation

frames = 240
hour_radius = 0.6
minute_radius = 0.9

def init():
    global hour_hand, minute_hand
    hour_hand = Line2D([0, 0], [0, hour_radius], linewidth=4, color="black")
    minute_hand = Line2D([0, 0], [0, minute_radius], linewidth=2, color="grey")
    axes.add_line(hour_hand)
    axes.add_line(minute_hand)
    return hour_hand, minute_hand

def animate(i):
    theta0 = i * 2 * np.pi / 60
    theta = np.pi/2 - theta0 / 12
    x = hour_radius * np.cos(theta)
    y = hour_radius * np.sin(theta)
    hour_hand.set_xdata([0, x])
    hour_hand.set_ydata([0, y])
    
    theta = np.pi/2 - theta0
    x = minute_radius * np.cos(theta)
    y = minute_radius * np.sin(theta)
    minute_hand.set_xdata([0, x])
    minute_hand.set_ydata([0, y]) 
    return hour_hand, minute_hand
    

anim = animation.FuncAnimation(fig, animate, 
                               init_func=init,
                               frames=frames, 
                               blit=True)
In [9]:
display_anim(anim)
Out[9]: