def show_animation( self, a_function_which_returns_an_image_according_to_a_time_variable, duration=3, fps=24, saving_path=None): """ the function looks like `func(t)`. t is a float variable in seconds, for example, 1.2 = 1 second + 0.2 second """ def wrap_function(t): array = a_function_which_returns_an_image_according_to_a_time_variable( t) assert isinstance( array, np.ndarray), "this function should return an numpy array" if array.shape[2] == 4: array = array[:, :, 0:3] return array animation = VideoClip(wrap_function, duration=duration) if self._notebook: result = animation.ipython_display(fps=fps, loop=True, autoplay=True) self._IPython.display.display(result) else: animation.preview(fps=fps) if saving_path != None: if len(saving_path.split(".")) > 0: extension = saving_path.split(".")[-1] if extension.lower() == "gif": animation.write_gif(saving_path, fps=fps) elif extension.lower() == "mp4": animation.write_videofile(saving_path, fps=fps) else: print("you can only save gif or mp4!") exit()
def animate_reactors(self, time, fps=30): ''' Plot the reactors and their mole fractions up to the given time in an animation Parameters ----------- time : int The number of seconds until which to animate. fps : float, optional The frames per second of the resulting animation. ''' fig = plt.figure() ax = fig.gca() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) self._reset() layout = self._layout_graph() self._step(0) duration = time / fps + 3 def draw(t): if t > 1 and duration - t > 2: #last 2 seconds and first sceond are filler self._step() ax.clear() self._plot_fracs(layout, ax, radius=25) self._plot_graph(layout, ax) ax.legend(LEGEND) ax.set_title('$t = {:.2f}$'.format(self.system.graph_time / 3.25)) return mplfig_to_npimage(fig) animation = VideoClip(draw, duration=duration) animation.fps = fps result = animation.ipython_display(loop=True, autoplay=True) plt.close() return result
ax.plot(t[arg], wavetable[arg], 'o', color=color) points.append(wavetable[arg]) ax.set_xlim(0, 1) ax.legend(loc='lower left') ax2 = axes[1] ax2.clear() ax2.plot(points1, '-or') ax2.plot(points2, '-ob') ax2.set_xlim(0, 41) ax2.set_ylim(-1, 1) return mplfig_to_npimage(fig) animation = VideoClip(make_frame, duration=duration) plt.close(fig) animation.ipython_display(fps=20, loop=True, autoplay=True) # As we can see from the above diagram, the fast pointer goes trough the waveform twice as fast as the original pointer. However, as it reaches the end of the wave, it starts over at the beginning. Using this method, we can easily derive several new waveforms from the original wavetable by looping over the wavetable and going back to the beginning when we reach the end of the wavetable. Fun fact, this is how a [Gameboy generates sounds](http://flothesof.github.io/gameboy-sounds-in-python.html). # # Let's write a function that implements the wavetable synthesis principle. # In[5]: def synthesize(sampling_speed, wavetable, n_samples): """Synthesizes a new waveform from an existing wavetable.""" samples = [] current_sample = 0 while len(samples) < n_samples: current_sample += sampling_speed