예제 #1
0
    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
예제 #2
0
def render(command_frames, config=None, audio_srcpath=None, duration=None):
    # command_frames: [[{'type':'circle', 'args': { radius: '5', xy: ['32',
    # '33'], fill: [1,0,0] } }, ...commands], ...frames]

    if (hasattr(command_frames, 'next')
            and callable(getattr(command_frames, 'next', None))) or\
        (hasattr(command_frames, '__next__')
            and callable(getattr(command_frames, '__next__', None))):
        frame_is_gen = True
    elif type(command_frames) is list:
        frame_is_gen = False
    else:
        raise TypeError('command_frames must be a list or have __next__ function')

    video_w, video_h = config['width'], config['height']
    video_fps = config['speed']

    named_shapes = dict()

    def make_frame(t):
        surface = gizeh.Surface(video_w, video_h, bg_color=(1, 1, 1))

        # draw all shapes in named_shapes (they are removed when hidden via
        # hide command)
        for _, shape in named_shapes.items():
            shape.draw(surface)

        commands = []
        try:
            if frame_is_gen:
                commands = next(command_frames)  # each video frame is 1-to-1 with a rnd frame
            else:
                num_frame = int(video_fps * t)
                commands = command_frames[num_frame]
        except (StopIteration, IndexError):
            pass

        for command in commands:
            # if there is a hide key, this command is a hide command
            if 'hide' in command:
                del named_shapes[command['hide']]

            # if there is not a hide key, this command is a draw command
            # (and a register command if it provides a name)
            else:
                # make args keys non-unicode-flagged strings for easy access
                shape_args = {
                    str(key): utils.simplify_type_for_gizeh(val)
                    for key, val in command['args'].items()
                }
                shape_method = command['type']

                gizeh_fn = getattr(gizeh, shape_method)
                shape = gizeh_fn(**shape_args)

                if 'name' in command:
                    named_shapes[command['name']] = shape

                shape.draw(surface)

        return surface.get_npimage()

    if duration is None:
        duration = int(config['num_frames']) / float(config['speed'])
    else:
        duration = int(duration)

    video = VideoClip(make_frame=make_frame, duration=duration)
    video.fps = video_fps

    if audio_srcpath is not None:
        video.audio = AudioFileClip(audio_srcpath)

    return video