Сохранение pyplots в список в цикле - PullRequest
0 голосов
/ 08 января 2019

Я хотел бы сделать анимацию следующего графика таким образом, чтобы он рисовал слева направо.

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. Пример сюжета с одним подзаговором приведен ниже. Как лучше всего передать функцию plot моему классу 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: Анимация y для каждого x

1 Ответ

0 голосов
/ 08 января 2019

Не изменяя ничего в классе LcAnimation, вы можете просто использовать ax1 и ax2 в функции построения графиков.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...