1""" 2=============== 3Rain simulation 4=============== 5 6Simulates rain drops on a surface by animating the scale and opacity 7of 50 scatter points. 8 9Author: Nicolas P. Rougier 10""" 11 12import numpy as np 13import matplotlib.pyplot as plt 14from matplotlib.animation import FuncAnimation 15 16# Fixing random state for reproducibility 17np.random.seed(19680801) 18 19 20# Create new Figure and an Axes which fills it. 21fig = plt.figure(figsize=(7, 7)) 22ax = fig.add_axes([0, 0, 1, 1], frameon=False) 23ax.set_xlim(0, 1), ax.set_xticks([]) 24ax.set_ylim(0, 1), ax.set_yticks([]) 25 26# Create rain data 27n_drops = 50 28rain_drops = np.zeros(n_drops, dtype=[('position', float, 2), 29 ('size', float, 1), 30 ('growth', float, 1), 31 ('color', float, 4)]) 32 33# Initialize the raindrops in random positions and with 34# random growth rates. 35rain_drops['position'] = np.random.uniform(0, 1, (n_drops, 2)) 36rain_drops['growth'] = np.random.uniform(50, 200, n_drops) 37 38# Construct the scatter which we will update during animation 39# as the raindrops develop. 40scat = ax.scatter(rain_drops['position'][:, 0], rain_drops['position'][:, 1], 41 s=rain_drops['size'], lw=0.5, edgecolors=rain_drops['color'], 42 facecolors='none') 43 44 45def update(frame_number): 46 # Get an index which we can use to re-spawn the oldest raindrop. 47 current_index = frame_number % n_drops 48 49 # Make all colors more transparent as time progresses. 50 rain_drops['color'][:, 3] -= 1.0/len(rain_drops) 51 rain_drops['color'][:, 3] = np.clip(rain_drops['color'][:, 3], 0, 1) 52 53 # Make all circles bigger. 54 rain_drops['size'] += rain_drops['growth'] 55 56 # Pick a new position for oldest rain drop, resetting its size, 57 # color and growth factor. 58 rain_drops['position'][current_index] = np.random.uniform(0, 1, 2) 59 rain_drops['size'][current_index] = 5 60 rain_drops['color'][current_index] = (0, 0, 0, 1) 61 rain_drops['growth'][current_index] = np.random.uniform(50, 200) 62 63 # Update the scatter collection, with the new colors, sizes and positions. 64 scat.set_edgecolors(rain_drops['color']) 65 scat.set_sizes(rain_drops['size']) 66 scat.set_offsets(rain_drops['position']) 67 68 69# Construct the animation, using the update function as the animation director. 70animation = FuncAnimation(fig, update, interval=10) 71plt.show() 72