def export(self, path): """Export mp4-video of animation to path. This requires FFMPEG.""" currentTimeIndex = self.currentTimeIndex # Index to jump back to ffmpegWriter = FFMpegFileWriter() with ffmpegWriter.saving(self.figure, path, dpi=100): for t_i in range(self.maxTimeIndex): self.time_changed(t_i) ffmpegWriter.grab_frame() self.time_changed(currentTimeIndex)
def main(): """ Entry point for rendering the plot """ anim_file_path = Path("./test.mp4") figure = plt.figure(figsize=(19.2, 10.8)) file_writer = FFMpegFileWriter(fps=FRAME_RATE) with file_writer.saving(figure, anim_file_path, dpi=100): intro_text = Scene( 0, 169, 1, draw_text( sentence="I've seen things you people wouldn't believe", text_pos_list=[16, 44], alpha_transitions=60, persist_frames=0, fade_out_frames=24, font_size=48, left_offset=0.12, bottom_offset=0.0, ), ) eye = Scene( intro_text.start_frame, intro_text.end_frame, 0, draw_eye(axes_dims=[0, 0.22, 1.0, 0.8], persist_frames=24, fade_out_frames=24), ) heatmap = Scene( intro_text.end_frame - 47, intro_text.end_frame + 145, 2, draw_fire_automata( axes_dims=[0.2, 0.35, 0.6, 0.6], fade_in_frames=24, update_frames=144, fade_out_frames=24, ), ) gaussian = Scene( intro_text.end_frame + 1, intro_text.end_frame + 145, 1, draw_gaussian( axes_dims=[0.05, 0.1, 0.9, 0.25], fade_in_frames=24, update_frames=72, persist_frames=24, fade_out_frames=24, ), ) heatmaps_text = Scene( 145, 313, 1, draw_text( sentence="Heat maps on fire off the shoulder of a Gaussian", text_pos_list=[17, 48], alpha_transitions=60, persist_frames=24, fade_out_frames=24, font_size=48, left_offset=0.08, bottom_offset=0.0, ), ) learning_curve = Scene( heatmaps_text.end_frame + 1, heatmaps_text.end_frame + 277, 1, draw_learning_curve( topo_axes_dims=[0.01, 0.15, 0.5, 0.8], learning_curve_axes_dims=[0.54, 0.15, 0.44, 0.8], fade_in_frames=24, update_frames=156, persist_frames=72, fade_out_frames=24, ), ) residuals_text = Scene( heatmaps_text.end_frame + 1, heatmaps_text.end_frame + 277, 2, draw_text( sentence= "I watched residuals diminish down the arc of ten thousand weights", text_pos_list=[10, 41, 65], alpha_transitions=60, persist_frames=72, fade_out_frames=24, font_size=40, left_offset=0.015, bottom_offset=0.0, ), ) fade_text_1 = Scene( residuals_text.end_frame + 1, residuals_text.end_frame + 193, 2, draw_text( sentence="All these visuals", text_pos_list=[17], alpha_transitions=60, persist_frames=84, fade_out_frames=48, font_size=100, left_offset=0.2, bottom_offset=0.53, ), ) fade_text_2 = Scene( residuals_text.end_frame + 60, residuals_text.end_frame + 193, 2, draw_text( sentence="will fade in time", text_pos_list=[17], alpha_transitions=60, persist_frames=24, fade_out_frames=48, font_size=100, left_offset=0.2, bottom_offset=0.37, ), ) terrain = Scene( fade_text_2.end_frame + 49, fade_text_2.end_frame + 169, 1, draw_terrain( axes_dims=[0.05, 0.2, 0.9, 0.8], fade_in_frames=24, update_frames=72, fade_out_frames=24, frame_jiggle=0.01, ), ) tears_text = Scene( fade_text_2.end_frame + 1, fade_text_2.end_frame + 169, 2, draw_text( sentence="Like tears in terrain", text_pos_list=[11, 21], alpha_transitions=48, persist_frames=48, fade_out_frames=24, font_size=60, left_offset=0.3, bottom_offset=0, ), ) pi_text_1 = Scene( tears_text.end_frame + 1, tears_text.end_frame + 217, 2, draw_text( sentence="Time to pi", text_pos_list=[4, 10], alpha_transitions=72, persist_frames=72, fade_out_frames=0, font_size=80, left_offset=0.08, bottom_offset=0.8, ), ) pi_text_2 = Scene( tears_text.end_frame + 169, tears_text.end_frame + 217, 1, draw_text( sentence="Time to pip install matplotlib", text_pos_list=[30], alpha_transitions=24, persist_frames=100, fade_out_frames=0, font_size=80, left_offset=0.08, bottom_offset=0.8, ), ) smiley = Scene( tears_text.end_frame + 169, tears_text.end_frame + 217, 2, draw_smiley(fade_in_frames=24, pos_x=0, pos_y=0), ) active_scenes_list: List[Scene] = [ intro_text, eye, heatmap, gaussian, heatmaps_text, learning_curve, residuals_text, fade_text_1, fade_text_2, terrain, tears_text, pi_text_1, pi_text_2, smiley, ] active_scenes_list.sort(key=lambda scene: scene.zorder, reverse=True) for frame_number in itertools.count(): figure.clear() render_axes = figure.add_axes([0.0, 0.0, 1.0, 1.0]) render_axes.axis("off") active_scene_count = len(active_scenes_list) if active_scene_count <= 0: break rendered_scene: bool = False for scene_index in range(active_scene_count - 1, -1, -1): scene = active_scenes_list[scene_index] if frame_number >= scene.start_frame: if frame_number > scene.end_frame: del active_scenes_list[scene_index] else: render_axes.imshow(next(scene.render_frame)) rendered_scene = True if rendered_scene is True: file_writer.grab_frame(facecolor=BACKGROUND_COLOUR)