gif生成器_使用python中的FuncAnimation画Gif图#1

v2-b9a4bab180bf97c933bed66dadd77ed9_1440w.jpg?source=172ae18b

为了更好的表示物理过程,比如波,我们需要画出随时间变化的图像,这时就需要引用from matplotlib.animation中的FuncAnimation函数

函数解析

matplotlib.animation.FuncAnimation(fig, func, frames=None, 
init_func=None, fargs=None, save_count=None, *, cache_frame_data=True, **kwargs)
  • figFigure

The figure object that is used to get draw, resize, and any other needed events.[1]
也就是需要画动图的画布。

  • func callable

The function to call at each frame. The first argument will be the next value in frames. Any additional positional arguments can be supplied via the fargs parameter.

The required signature is:

def func(frame, *fargs) -> iterable_of_artists

If blit == True, func must return an iterable of all artists that were modified or created. This information is used by the blitting algorithm to determine which parts of the figure have to be updated. The return value is unused if blit == False and may be omitted in that case.
在每帧调用的函数。第一个参数将是帧中的下一个值。任何附加的位置参数都可以通过fargs参数提供。

所需函数格式为:

def func(frame, *fargs) -> iterable_of_artists

如果blit==True,func必须返回已修改或创建的所有artists的iterable。此信息由blitting算法用于确定图形的哪些部分必须更新。如果blit==False,则返回值未使用,在这种情况下可以省略。

  • frames iterable, int, generator function, or None, optional

Source of data to pass func and each frame of the animation

  • If an iterable, then simply use the values provided. If the iterable has a length, it will override the save_count kwarg.
  • If an integer, then equivalent to passing range(frames)
  • If a generator function, then must have the signature:def gen_function() -> obj
  • If None, then equivalent to passing itertools.count.

In all of these cases, the values in frames is simply passed through to the user-supplied func and thus can be of any type.

也就是说,frame的值会传递到func去改变line

  • init_func callable, optional
    初始值函数

A function used to draw a clear frame. If not given, the results of drawing from the first item in the frames sequence will be used. This function will be called once before the first frame.

The required signature is:

def init_func() -> iterable_of_artists

If blit == True, init_func must return an iterable of artists to be re-drawn. This information is used by the blitting algorithm to determine which parts of the figure have to be updated. The return value is unused if blit == False and may be omitted in that case.

  • fargs tuple or None, optional

Additional arguments to pass to each call to func.

  • save_count int, default: 100

Fallback for the number of values from frames to cache. This is only used if the number of frames cannot be inferred from frames, i.e. when it's an iterator without length or a generator.
保存计数,默认值:100

从帧到缓存的值数的回退。仅当无法从帧推断帧的数量时,即当它是一个没有长度的迭代器或生成器时,才使用此选项。

  • interval number, optional

Delay between frames in milliseconds. Defaults to 200.
每帧之间的间隔,可选

帧之间的延迟(毫秒)。默认为200。

  • repeat_delaynumber, optional

If the animation in repeated, adds a delay in milliseconds before repeating the animation. Defaults to None.
重复延迟数,可选

如果动画处于重复状态,则在重复动画之前以毫秒为单位添加延迟。默认为无。

  • repeat bool, optional

Controls whether the animation should repeat when the sequence of frames is completed. Defaults to True.
repeatbool,可选

控制帧序列完成时动画是否应重复。默认为True。

  • blit bool, optional

Controls whether blitting is used to optimize drawing. Note: when using blitting any animated artists will be drawn according to their zorder. However, they will be drawn on top of any previous artists, regardless of their zorder. Defaults to False.

非重要参数

  • cache_frame_data bool, optional

Controls whether frame data is cached. Defaults to True. Disabling cache might be helpful when frames contain large objects.
缓存帧数据池,可选

控制是否缓存帧数据。默认为True。当帧包含大型对象时,禁用缓存可能会有帮助。

实例

  • 画一条平行向上移动的直线

v2-f6bff86b7e6583be29915bb44eeaa8f9_b.gif
# 引用所需要的库
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# 定义画布
fig, ax = plt.subplots()
line, = ax.plot([], [])  # 返回的第一个值是update函数需要改变的


# 获取直线的数组
def line_space(B):
    x = np.linspace(0, 10, 100)
    return x, x + B


# 这里B就是frame
def update(B):
    ax.set_xlim(0, 10)
    ax.set_ylim(0, 20)
    x, y = line_space(B)
    line.set_data(x, y)
    return line

# 使用函数并保存保存会在下一篇文章讲
# 可以用plt.show()来代替一下
ani = FuncAnimation(fig, update, frames=np.linspace(0, 10, 100), interval=50)
ani.save('move1.gif', writer='imagemagick', fps=10)
  • 画一个围绕圆心转动的直线

v2-09f7e033b34161cb7cddd1222f3d8c68_b.gif
# 引用所需要的库
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
#
# # 定义画布
fig, ax = plt.subplots()
line, = ax.plot([], [])  # 返回的第一个值是update函数需要改变的
# 定义初始函数
def ini():
    ax.set_xlim(-1, 1)
    ax.set_ylim(-1, 1)
    return line


def update(theta):
    x, y = round(theta)
    line.set_data(x, y)
    ax.set_xlim(-1, 1)
    ax.set_ylim(-1, 1)
    return line


theta_ = np.linspace(0, np.pi * 2, 100)
x_round = np.cos(theta_)
y_round = np.sin(theta_)
ax.plot(x_round, y_round)
ax.grid()
ax.axis('scaled')
ani = FuncAnimation(fig, update, init_func=ini, frames=np.linspace(0, 2 * np.pi, 100), interval=10)
# 保存会在下一篇文章讲
ani.save('move.gif', writer='imagemagick', fps=10)

关于这个函数我想分三篇来写,第一篇讲基础使用,第二篇来进阶,第三篇讲3D绘图

参考

  1. ^官方doc https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.animation.FuncAnimation.html#matplotlib.animation.FuncAnimation
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现一个Python聊天室GIF,你需要使用Python的Socket库来建立客户端和服务器之间的连接。然后,你需要使用Python的Pillow库来处理GIF,以便将其发送到其他客户端。 以下是一个简单的Python聊天室实现GIF的示例: ```python import socket import threading from PIL import Image, ImageSequence # 客户端类 class ChatClient: def __init__(self, host, port): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((host, port)) self.gif_data = b'' # 接收消息 def receive(self): while True: data = self.sock.recv(1024).decode() if data.startswith('GIF'): # 如果接收到的数据是GIF self.gif_data += data.encode() # 将数据添加到GIF缓冲区 if data.endswith('\r\n'): # 如果数据以\r\n结尾,说明GIF接收完毕 self.show_gif() # 显示GIF self.gif_data = b'' # 清空GIF缓冲区 else: print(data) # 发送消息 def send(self, msg): self.sock.send(msg.encode()) # 显示GIF def show_gif(self): img = Image.open(BytesIO(self.gif_data)) for frame in ImageSequence.Iterator(img): frame.show() # 服务器类 class ChatServer: def __init__(self, host, port): self.clients = [] self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.bind((host, port)) self.sock.listen(1) # 接收连接 def accept_clients(self): while True: client_sock, client_addr = self.sock.accept() client = ChatClient(client_sock) self.clients.append(client) client_thread = threading.Thread(target=self.handle_client, args=(client,)) client_thread.start() # 处理客户端 def handle_client(self, client): while True: data = client.sock.recv(1024).decode() if data: if data.startswith('/gif'): # 如果客户端发送的消息是GIF self.send_gif(client, data) #GIF广播给其他客户端 else: self.broadcast(client, data) # 广播消息给其他客户端 # 广播消息 def broadcast(self, client, msg): for c in self.clients: if c != client: c.sock.send(msg.encode()) # 广播GIF def send_gif(self, client, data): for c in self.clients: if c != client: c.sock.send(data.encode()) # 主函数 if __name__ == '__main__': server = ChatServer('localhost', 9999) server_thread = threading.Thread(target=server.accept_clients) server_thread.start() while True: name = input('Enter your name: ') if name: break client = ChatClient('localhost', 9999) receive_thread = threading.Thread(target=client.receive) receive_thread.start() while True: msg = input() if msg.startswith('/gif'): # 如果发送的消息是GIF with open('animated.gif', 'rb') as f: gif_data = f.read() client.send(gif_data) # 发送GIF数据 else: client.send(f'{name}: {msg}') ``` 这个示例,客户端和服务器之间使用Socket库建立连接。当客户端收到GIF时,它会将数据添加到GIF缓冲区,直到接收完毕。当接收完毕后,它会使用Pillow库将GIF显示在屏幕上。当客户端发送GIF时,它会将GIF数据发送到服务器,并广播给其他客户端。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值