2021-02-06 Python genera animación gif a través del paquete matplotlib y el paquete gif

Python genera animación gif a través del paquete matplotlib y el paquete gif

Uso matplotlibHay muchas formas de generar gif animados, generalmente usados ​​convencionalmente matplotliben la implementación de la función del animationmódulo FuncAnimation. matplotlibVi la gifintroducción del paquete de animación de terceros en el sitio web oficial .

gifDescripción general del paquete

gifEl paquete es una extensión de animación que los apoyos  Altairmatplotliby Plotly.
gifDependencia PIL, es decir pillow, requisito Pillow>=7.1.2. Paquete de
instalación gif,pip install gif

Principio de animación

Todo 动画está compuesto 帧(frame), un fotograma es una imagen fija y los sucesivos fotogramas forman una animación. Por lo general, decimos el número de fotogramas. En pocas palabras, es el número de fotogramas de una imagen transmitida en 1 segundo. También se puede entender que el procesador gráfico puede actualizar varias veces por segundo, lo que generalmente se fps(Frames Per Second)expresa. La clave para hacer animaciones: cómo generar fotogramas y cuántos fotogramas por segundo.

gifInterpretación del paquete

gifEl paquete es muy conciso, hay un solo archivo gif.py, el archivo contiene principalmente optionsclases framesy savedos funciones.

optionsclase

Proporcionar una versión condensada Altairmatplotliby Plotlyguardar o ajustes de exportación. Como matplotlibejemplo, proporcione la siguiente configuración.

  • ppp (int): la resolución en puntos por pulgada

  • facecolor (colorspec): el color de la cara de la figura

  • edgecolor (colorspec): el color del borde de la figura

  • transparente (bool): si es True, los parches de los ejes serán todos transparentes

Método de configuración: gif.options.matplotlib["dpi"] = 300
Principio: optionscree un matplotlibdiccionario en el constructor para guardar la configuración y luego páselo al matplotlibpaquete subyacente .

framesfunción

Función de decorador, a través del paquete correspondiente para escribir una función de dibujo personalizado para generar una imagen de un solo cuadro.

savefunción

Genere animación basada en la secuencia de cuadros.

def save(frames, path, duration=100, unit="milliseconds", between="frames", loop=True):    """Save decorated frames to an animated gif.    - frames (list): collection of frames built with the gif.frame decorator    - path (str): filename with relative/absolute path    - duration (int/float): time (with reference to unit and between)    - unit {"ms" or "milliseconds", "s" or "seconds"}: time unit value    - between {"frames", "startend"}: duration between "frames" or the entire gif ("startend")    - loop (bool): infinitely loop the animation

framesEs decir @gif.frame, la secuencia de fotogramas generada según la función de dibujo decorado, que se personaliza aquí según sea necesario.
durationLa duración está determinada por la unidad unity el modo between, y el valor predeterminado es framesel intervalo de tiempo entre fotogramas.
unitEs decir, la unidad de duración, que admite milisegundos y segundos, y el valor predeterminado es milisegundos.
betweenEse modo de cálculo de duración, predeterminado, frameses decir, durationel intervalo de tiempo entre cuadros, startendun modo duration=duration /len(frames), es decir, durationtodos los cuadros, la duración de toda la animación.

gifPráctica de animación gif de generación de paquetes

 

import randomfrom matplotlib import pyplot as pltimport gif
# 构造数据x = [random.randint(0, 100) for _ in range(100)]y = [random.randint(0, 100) for _ in range(100)]# 设置选项gif.options.matplotlib["dpi"] = 300

# 使用gif.frame装饰器构造绘图函数,即如何生成静态的帧@gif.framedef plot(i):    xi = x[i * 10:(i + 1) * 10]    yi = y[i * 10:(i + 1) * 10]    plt.scatter(xi, yi)    plt.xlim((0, 100))    plt.ylim((0, 100))

# 构造帧序列frames,即把生成动画的所有帧按顺序放在列表中frames = []for i in range(10):    frame = plot(i)    frames.append(frame)# 根据帧序列frames,动画持续时间duration,生成gif动画gif.save(frames, 'example.gif', duration=3.5, unit="s", between="startend")

imagen

Tome la curva en forma de corazón como ejemplo para comparar la diferencia entre el gifpaquete y el animationmódulo para lograr la animación.

Dibujo de curva en forma de corazón

from matplotlib import pyplot as pltimport numpy as np
t = np.linspace(0, 6, 100)x = 16 * np.sin(t) ** 3y = 13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(4 * t)fig = plt.figure(figsize=(5, 3), dpi=100)plt.scatter(x, y)plt.show()

imagen

gifCómo se implementa el paquete

import numpy as npimport giffrom matplotlib import pyplot as plt
t = np.linspace(0, 6, 100)x = 16 * np.sin(t) ** 3y = 13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(4 * t)
@gif.framedef plot_love(x, y):    plt.figure(figsize=(5, 3), dpi=100)    plt.scatter(x, y, 60, c="r", alpha=0.7, marker=r"$\heartsuit$")    plt.axis("off")    frames = []for i in range(1, len(x)):    of = plot_love(x[:i], y[:i])    frames.append(of)
gif.save(frames, "love.gif", duration=80)

imagen

matplotlibFuncAnimationImplementación de funciones  convencionales

​​​​​​​

from matplotlib import pyplot as pltimport matplotlib.animation as animationimport numpy as np
t = np.linspace(0, 6, 100)x = 16 * np.sin(t) ** 3y = 13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(4 * t)data=[i for i in zip(x,y)]
def plot_love(data):    x, y = data    plt.scatter(x, y, 60, c="r", alpha=0.7, marker=r"$\heartsuit$")
fig=plt.figure(figsize=(5, 3), dpi=100)plt.axis("off")animator = animation.FuncAnimation(fig, plot_love, frames=data, interval=80)animator.save("love.gif", writer='pillow')

matplotlibPillowWriterImplementación de clases de bajo nivel

from matplotlib import pyplot as pltimport matplotlib.animation as animationimport numpy as np
t = np.linspace(0, 6, 100)x = 16 * np.sin(t) ** 3y = 13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(4 * t)

def plot_love(x, y):    plt.scatter(x, y, 60, c="r", alpha=0.7, marker=r"$\heartsuit$")

fig = plt.figure(figsize=(5, 3), dpi=100)plt.axis("off")
writer = animation.PillowWriter(fps=15)with writer.saving(fig, "love21.gif", dpi=100):    for i in range(1, len(x)):        plot_love(x[i], y[i])        writer.grab_frame()

A través de la comparación, se puede ver que gifla implementación del paquete es similar a la implementación de la matplotlibutilización media PillowWriter, y es de nivel más bajo, por lo que es más flexible cuando se encuentra con dibujos más complicados.

Supongo que te gusta

Origin blog.csdn.net/qingfengxd1/article/details/113725721
Recomendado
Clasificación