Skip to content

Commit

Permalink
Tidied up the rain animation.
Browse files Browse the repository at this point in the history
  • Loading branch information
pelson committed May 12, 2014
1 parent aa4f317 commit 0b26ad3
Showing 1 changed file with 46 additions and 38 deletions.
84 changes: 46 additions & 38 deletions examples/animation/rain.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,66 @@
# -----------------------------------------------------------------------------
# Rain simulation
# Author: Nicolas P. Rougier
# -----------------------------------------------------------------------------
import matplotlib
"""
Rain simulation
Simulates rain drops on a surface by animating the scale and opacity
of 50 scatter points.
Author: Nicolas P. Rougier
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation


# Create new figure
# Create new Figure and an Axes which fills it.
fig = plt.figure(figsize=(7,7))
ax = fig.add_axes([0,0,1,1], frameon=False, aspect=1)

# Create rain data
P = np.zeros(50, dtype=[('position', float, 2),
('size', float, 1),
('growth', float, 1),
('color', float, 4)])

# Scatter plot is used to animate rain drops
scat = ax.scatter(P['position'][:,0], P['position'][:,1], P['size'],
lw=0.5, edgecolors = P['color'], facecolors='none')
ax = fig.add_axes([0, 0, 1, 1], frameon=False)
ax.set_xlim(0,1), ax.set_xticks([])
ax.set_ylim(0,1), ax.set_yticks([])

# Create rain data
n_drops = 50
rain_drops = np.zeros(n_drops, dtype=[('position', float, 2),
('size', float, 1),
('growth', float, 1),
('color', float, 4)])

def update(frame):
i = frame % len(P)

# Make all colors more transparent
P['color'][:,3] -= 1.0/len(P)
P['color'][:,3] = np.clip(P['color'][:,3], 0, 1)
# Initialize the raindrops in random positions and with
# random growth rates.
rain_drops['position'] = np.random.uniform(0, 1, (n_drops, 2))
rain_drops['growth'] = np.random.uniform(50, 200, n_drops)

# Make all circles bigger
P['size'] += P['growth']
# Construct the scatter which we will update during animation
# as the raindrops develop.
scat = ax.scatter(rain_drops['position'][:,0], rain_drops['position'][:,1],
s=rain_drops['size'], lw=0.5, edgecolors=rain_drops['color'],
facecolors='none')

# Pick a new position for oldest rain drop
P['position'][i] = np.random.uniform(0, 1, 2)

# Reset size
P['size'][i] = 5
def update(frame_number):
# Get an index which we can use to re-spawn the oldest raindrop.
current_index = frame_number % n_drops

# Reset color
P['color'][i] = (0, 0, 0, 1)
# Make all colors more transparent as time progresses.
rain_drops['color'][:, 3] -= 1.0/len(rain_drops)
rain_drops['color'][:,3] = np.clip(rain_drops['color'][:,3], 0, 1)

# Choose a random growth factor
P['growth'][i] = np.random.uniform(50, 200)
# Make all circles bigger.
rain_drops['size'] += rain_drops['growth']

# Update scatter plot
scat.set_edgecolors(P['color'])
scat.set_sizes(P['size'])
scat.set_offsets(P['position'])
# Pick a new position for oldest rain drop, resetting its size,
# color and growth factor.
rain_drops['position'][current_index] = np.random.uniform(0, 1, 2)
rain_drops['size'][current_index] = 5
rain_drops['color'][current_index] = (0, 0, 0, 1)
rain_drops['growth'][current_index] = np.random.uniform(50, 200)

return scat,
# Update the scatter collection, with the new colors, sizes and positions.
scat.set_edgecolors(rain_drops['color'])
scat.set_sizes(rain_drops['size'])
scat.set_offsets(rain_drops['position'])


# Construct the animation, using the update function as the animation
# director.
animation = FuncAnimation(fig, update, interval=10)
plt.show()

0 comments on commit 0b26ad3

Please sign in to comment.