将pyplots保存到循环列表中

时间:2019-01-08 07:39:17

标签: python matplotlib animation

我想制作以下情节的动画,使其从左到右绘制。

x = np.arange(1,10,1)
y = x * 2 - 1 + np.random.normal(0,1,9)
z = y / x
df = pd.DataFrame({'x':x, 'y':y, 'z':z})
df.set_index('x', drop=True, inplace=True)

fig, (ax1, ax2) = plt.subplots(nrows=2)
ax1.plot(df['y'], color='darkred')
ax2.bar(x=df.index, height=df['z'])
ax1.margins(0)
ax2.margins(0)

我正在寻找一种通用解决方案,以便可以创建1)以数据为输入的绘图函数,或2)具有绘图函数并将1或2传递给我的LcAnimation类的类。下面给出了具有单个子图的图的示例。 我如何最好地将绘图函数传递给我的LcAnimation类(下面的代码仅适用于简单的绘图,但不适用于多个子图)。

import matplotlib.animation as anim
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

class LcAnimation:
    def __init__(self, data, fig):
        '''
        :param data: A data frame containing the desired data for plotting
        :param fig: A matplotlib.pyplot figure on which the plot is drawn
        '''
        self.data = data.copy()
        self.fig = fig
        self.plots = []

    def create_animation(self, plot_class):
        '''
        :return: A list with the animated plots
        '''
        for i in range(0, len(self.data)):
            data_temp = self.data.loc[:i, ].copy()
            plt_im = plot_class.plot(data_temp)
            self.plots.append(plt_im)

    def save_animation(self, filename, fps = 10):
        '''

        :param filename: Destination at which the animation should be saved
        :return: Saves the animation
        '''
        animation_art = anim.ArtistAnimation(self.fig, self.plots)
        animation_art.save(filename, writer='pillow', fps=fps)

class MyPlot:

    def plot(self, data):
        plt_im = plt.plot(data['x'], data['y'], color='darkred')
        return plt_im


x = np.arange(1,10,1)
y = x * 2 - 1 + np.random.normal(0,1,9)
df = pd.DataFrame({'x':x, 'y':y})

fig = plt.figure()

# Test the module
my_plot = MyPlot()
MyFirstAnimation = LcAnimation(df, fig)
MyFirstAnimation.create_animation(my_plot)
MyFirstAnimation.save_animation('path', fps=5)

一个示例,说明我希望动画如何用于多个子图,而不仅仅是1: Animation of y for each x

1 个答案:

答案 0 :(得分:1)

无需更改LcAnimation类中的任何内容,就可以在绘图函数中使用ax1ax2

x = np.arange(1,10,1)
y = x * 2 - 1 + np.random.normal(0,1,9)
z = y / x
df = pd.DataFrame({'x':x, 'y':y, 'z':z})
df.set_index('x', drop=True, inplace=True)

fig, (ax1, ax2) = plt.subplots(nrows=2)
ax1.margins(0)
ax2.margins(0)

class MyPlot:

    def plot(self, data):
        line, = ax1.plot(data['y'], color='darkred')
        bars = ax2.bar(x=data.index, height=data['z'], color='darkred')
        return [line,*bars]

# Test the module
my_plot = MyPlot()
MyFirstAnimation = LcAnimation(df, fig)
MyFirstAnimation.create_animation(my_plot)
MyFirstAnimation.save_animation('path.gif', fps=5)

enter image description here