【python】matplotlib(animation)

在这里插入图片描述

文章目录

  • 1、matplotlib.animation
    • 1.1、FuncAnimation
    • 1.2、修改 matplotlib 背景
  • 2、matplotlib + imageio
    • 2.1、折线图
    • 2.2、条形图
    • 2.3、散点图
  • 3、参考

1、matplotlib.animation

1.1、FuncAnimation

matplotlib.animation.FuncAnimation 是 Matplotlib 库中用于创建动画的一个类。它允许你通过循环调用一个函数来更新图表,从而生成动画效果。这个函数通常被称为“更新函数”,它决定了每一帧图表的样子。FuncAnimation 类提供了一种灵活而强大的方式来创建和展示动画,使得数据可视化更加生动和直观。

(1)基本用法

使用 FuncAnimation 创建动画的基本步骤如下:

  • 准备数据:首先,你需要准备好用于动画的数据。这可能包括一系列的X和Y坐标点、颜色、大小等,具体取决于你要制作的动画类型。
  • 创建图形和轴:使用 Matplotlib 创建图形(Figure)和轴(Axes)对象,这些对象将作为动画的画布。
  • 定义更新函数:编写一个函数,这个函数接受当前的帧号(或其他参数)作为输入,并返回一个更新后的图形元素状态。例如,如果你正在制作一个点的移动动画,这个函数可能会更新点的位置。
  • 创建 FuncAnimation 对象:使用 FuncAnimation 类创建一个动画对象。你需要指定图形对象、轴对象、更新函数、帧数(或时间间隔)、以及其他可选参数(如重复次数、初始延迟等)。
  • 显示或保存动画:最后,你可以使用 Matplotlib 的显示功能(如 plt.show())来查看动画,或者将其保存为文件(如GIF、MP4等)。

(2)示例代码

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation# 准备数据
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)# 创建图形和轴
fig, ax = plt.subplots()
line, = ax.plot([], [], 'r-')  # 初始化一个空线条对象
ax.set_xlim(0, 2 * np.pi)      # 设置X轴范围
ax.set_ylim(-1.5, 1.5)         # 设置Y轴范围# 定义更新函数
def update(frame):line.set_data(x[:frame], y[:frame])  # 更新线条数据return line,# 创建 FuncAnimation 对象
ani = FuncAnimation(fig, update, frames=len(x), interval=50, blit=True)# 显示动画
plt.show()

在这里插入图片描述

在这个例子中,update 函数根据当前的帧号(frame)更新线条的数据,使得线条逐渐变长,模拟了一个点沿正弦曲线移动的动画效果。

再看一个例子

#coding=utf-8
import sysimport numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animationfig, ax = plt.subplots()x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x, np.sin(x))def animate(i):line.set_ydata(np.sin(x + i/10.0))return line,def init():line.set_ydata(np.ma.array(x, mask=True))return line,ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init,interval=25, blit=True)
ani.save("animation.gif", writer="imagemagick", fps=30)
plt.show()

在这里插入图片描述

(3)matplotlib.animation.FuncAnimation

class matplotlib.animation.FuncAnimation(fig, func, frames=None, init_func=None, fargs=None, save_count=None, *, cache_frame_data=True, **kwargs)
def __init__(self,fig: Figure,func: (...) -> Iterable[Artist],frames: Iterable | int | () -> Generator | None = ...,init_func: () -> Iterable[Artist] | None = ...,fargs: tuple[Any, ...] | None = ...,save_count: int | None = ...,*,cache_frame_data: bool = ...,**kwargs: Any) -> None
`TimedAnimation` subclass that makes an animation by repeatedly calling a function *func*.  .. note::  You must store the created Animation in a variable that lives as long as the animation should run. Otherwise, the Animation object will be garbage-collected and the animation stops.  Parameters ---------- fig : `~matplotlib.figure.Figure` The figure object used to get needed events, such as draw or resize.  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 using `functools.partial` or via the *fargs* parameter.  The required signature is::  def func(frame, *fargs) -> iterable_of_artists  It is often more convenient to provide the arguments using `functools.partial`. In this way it is also possible to pass keyword arguments. To pass a function with both positional and keyword arguments, set all arguments as keyword arguments, just leaving the *frame* argument unset::  def func(frame, art, *, y=None): ...  ani = FuncAnimation(fig, partial(func, art=ln, y='foo'))  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.  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.  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*. Note: the use of `functools.partial` is preferred over *fargs*. See *func* for details.  save_count : int, optional 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.  interval : int, default: 200 Delay between frames in milliseconds.  repeat_delay : int, default: 0 The delay in milliseconds between consecutive animation runs, if *repeat* is True.  repeat : bool, default: True Whether the animation repeats when the sequence of frames is completed.  blit : bool, default: False 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.  cache_frame_data : bool, default: True Whether frame data is cached. Disabling cache might be helpful when frames contain large objects.
Params:
fig – The figure object used to get needed events, such as draw or resize.
func – The function to call at each frame. The first argument will be the next value in *frames*. Any additional positional arguments can be supplied using `functools.partial` or via the *fargs* parameter. The required signature is:: def func(frame, *fargs) -> iterable_of_artists It is often more convenient to provide the arguments using `functools.partial`. In this way it is also possible to pass keyword arguments. To pass a function with both positional and keyword arguments, set all arguments as keyword arguments, just leaving the *frame* argument unset:: def func(frame, art, *, y=None): ... ani = FuncAnimation(fig, partial(func, art=ln, y='foo')) 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.
frames – 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.
init_func – 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 – Additional arguments to pass to each call to *func*. Note: the use of `functools.partial` is preferred over *fargs*. See *func* for details.
save_count – 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.
cache_frame_data – Whether frame data is cached. Disabling cache might be helpful when frames contain large objects.
  • fig:图形对象(Figure),用于获取绘制、调整大小等事件。这是动画的画布。
  • func:可调用对象(函数),每帧调用的函数。该函数的第一个参数将是 frames 中的下一个值。任何其他的位置参数可以通过 fargs 参数提供。如果 blit 为 True,则该函数必须返回一个被修改或创建的所有图形元素(artists)的可迭代对象。
  • frames:可迭代对象、整数、生成器函数或 None,可选。用于传递给 func 和动画的每一帧的数据源。如果是可迭代对象,则直接使用提供的值。如果是一个整数,则相当于传递 range(frames)。如果是一个生成器函数,则必须具有特定的签名。如果为 None,则相当于传递 itertools.count。
  • init_func:可调用对象(函数),可选。用于绘制清空画面的函数。如果未提供,则将使用 frames 序列中的第一个项目的绘图结果。此函数将在第一帧之前被调用一次。如果 blit 为 True,则 init_func 必须返回一个将被重新绘制的图形元素(artists)的可迭代对象。
  • fargs:元组或 None,可选。传递给每次调用 func 的附加参数。
  • save_count:整数,可选。要缓存的 frames 中的值的数量。
  • interval:数字,可选。帧之间的延迟时间(以毫秒为单位)。默认为 200。
  • blit:布尔值,可选。控制是否使用 blitting 来优化绘制。当使用 blitting 时,只有变化的图形元素会被重新绘制,从而提高性能。
  • cache_frame_data:布尔值,可选。控制是否缓存帧数据。默认为 True。

方法说明

  • save:将动画保存为电影文件。
  • to_html5_video:将动画转换为 HTML5 视频。
  • to_jshtml:生成动画的 HTML 表示形式。

(4)注意事项

  • 性能:对于复杂的动画,可能需要优化性能,比如通过减少每次更新的数据量(使用 blit=True 参数)或调整帧的更新间隔。
  • 兼容性:保存动画时,不同的文件格式(如GIF、MP4)可能需要不同的编解码器支持。确保你的环境中安装了必要的编解码器。
  • 交互性:动画在Jupyter Notebook等交互式环境中可能表现不同,需要根据具体环境调整显示方式。

1.2、修改 matplotlib 背景

在上述示例代码的情况下,我们引入一些修改颜色的配置,

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation# 准备数据
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)# 创建图形和轴
fig, ax = plt.subplots()
line, = ax.plot([], [], 'r-')  # 初始化一个空线条对象
ax.set_xlim(0, 2 * np.pi)  # 设置X轴范围
ax.set_ylim(-1.5, 1.5)  # 设置Y轴范围# 修改轴背景颜色
ax.set_facecolor("orange")  
# OR
# ax.set(facecolor = "orange")# 修改绘图背景颜色
fig.patch.set_facecolor('yellow')   
fig.patch.set_alpha(1.0)# 移除图表的上边框和右边框
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)# 设置虚线网格线
ax.set_axisbelow(True)
ax.yaxis.grid(color='gray', linestyle='dashed', alpha=0.7)# 定义更新函数
def update(frame):line.set_data(x[:frame], y[:frame])  # 更新线条数据return line,# 创建 FuncAnimation 对象
ani = FuncAnimation(fig, update, frames=len(x), interval=50, blit=True)# ani.save("animation.gif", writer="imagemagick", fps=30)# 显示动画
plt.show()

修改前

在这里插入图片描述

修改后
在这里插入图片描述
换个背景图试试

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation# 准备数据
x = np.linspace(0, 20 * np.pi, 100)
y = 9* np.sin(x)# 创建图形和轴
fig, ax = plt.subplots()
line, = ax.plot([], [], 'r-')  # 初始化一个空线条对象img = plt.imread("123.jpg")
ax.imshow(img, extent=[0, 65, -10, 10])  # 横纵坐标范围# 定义更新函数
def update(frame):line.set_data(x[:frame], y[:frame])  # 更新线条数据return line,# 创建 FuncAnimation 对象
ani = FuncAnimation(fig, update, frames=len(x), interval=50, blit=True)ani.save("animation.gif", writer="imagemagick", fps=30)# 显示动画
plt.show()

原始图片

在这里插入图片描述

添加之后的效果
在这里插入图片描述

2、matplotlib + imageio

2.1、折线图

先画个简单的折线图

import os
import numpy as np
import matplotlib.pyplot as plt
import imageionp.random.seed(1234)# 生成40个取值在30-40的数
y = np.random.randint(30, 40, size=(40))
print(y)
"""
[33 36 35 34 38 39 31 37 39 36 38 30 35 30 39 36 32 30 35 32 36 33 37 3039 30 33 32 33 31 33 31 33 37 31 37 34 30 35 31]
"""
# 绘制折线
plt.plot(y)
# 设置y轴最小值和最大值
plt.ylim(20, 50)# 显示
plt.show()

在这里插入图片描述

保存最后几个点的数据,然后绘制成 gif

import os
import numpy as np
import matplotlib.pyplot as plt
import imageionp.random.seed(1234)# 生成40个取值在30-40的数
y = np.random.randint(30, 40, size=(40))
print(y)
"""
[33 36 35 34 38 39 31 37 39 36 38 30 35 30 39 36 32 30 35 32 36 33 37 3039 30 33 32 33 31 33 31 33 37 31 37 34 30 35 31]
"""
# 绘制折线
plt.plot(y)
# 设置y轴最小值和最大值
plt.ylim(20, 50)# 显示
plt.show()# 第一张图
plt.plot(y[:-3])
plt.ylim(20, 50)
plt.savefig('1.png')
plt.show()# 第二张图
plt.plot(y[:-2])
plt.ylim(20, 50)
plt.savefig('2.png')
plt.show()# 第三张图
plt.plot(y[:-1])
plt.ylim(20, 50)
plt.savefig('3.png')
plt.show()# 第四张图
plt.plot(y)
plt.ylim(20, 50)
plt.savefig('4.png')
plt.show()# 生成Gif
with imageio.get_writer('mygif.gif', mode='I') as writer:for filename in ['1.png', '2.png', '3.png', '4.png']:image = imageio.imread(filename)writer.append_data(image)

横坐标 0 至 36
在这里插入图片描述

横坐标 0 至 37

在这里插入图片描述

横坐标 0 至 38

在这里插入图片描述

横坐标 0 至 39

在这里插入图片描述

合并成为 gif(仅播放一次)

请添加图片描述

下面把所有点都保存下来,绘制动态图(仅播放一次)

import os
import numpy as np
import matplotlib.pyplot as plt
import imageionp.random.seed(1234)# 生成40个取值在30-40的数
y = np.random.randint(30, 40, size=(40))
print(y)
"""
[33 36 35 34 38 39 31 37 39 36 38 30 35 30 39 36 32 30 35 32 36 33 37 3039 30 33 32 33 31 33 31 33 37 31 37 34 30 35 31]
"""
# 绘制折线
plt.plot(y)
# 设置y轴最小值和最大值
plt.ylim(20, 50)# 显示
plt.show()filenames = []
num = 0
for i in y:num += 1# 绘制40张折线图plt.plot(y[:num])plt.ylim(20, 50)# 保存图片文件filename = f'{num}.png'filenames.append(filename)plt.savefig(filename)plt.close()# 生成gif
with imageio.get_writer('mygif.gif', mode='I') as writer:for filename in filenames:image = imageio.imread(filename)writer.append_data(image)# 删除40张折线图
for filename in set(filenames):os.remove(filename)

在这里插入图片描述

2.2、条形图

import os
import numpy as np
import matplotlib.pyplot as plt
import imageionp.random.seed(1234)x = [1, 2, 3, 4, 5]
coordinates_lists = [[0, 0, 0, 0, 0],[10, 30, 60, 30, 10],[70, 40, 20, 40, 70],[10, 20, 30, 40, 50],[50, 40, 30, 20, 10],[75, 0, 75, 0, 75],[0, 0, 0, 0, 0]]
filenames = []
for index, y in enumerate(coordinates_lists):# 条形图plt.bar(x, y)plt.ylim(0, 80)# 保存图片文件filename = f'{index}.png'filenames.append(filename)# 重复最后一张图形15帧(数值都为0),15张图片if (index == len(coordinates_lists) - 1):for i in range(15):filenames.append(filename)# 保存plt.savefig(filename)plt.close()# 生成gif
with imageio.get_writer('mygif.gif', mode='I') as writer:for filename in filenames:image = imageio.imread(filename)writer.append_data(image)# 删除20张柱状图
for filename in set(filenames):os.remove(filename)

生成的图片

在这里插入图片描述

生成的 gif(播放一次)

在这里插入图片描述

看起来太快了,优化代码使其平滑

import os
import numpy as np
import matplotlib.pyplot as plt
import imageionp.random.seed(1234)n_frames = 10  # 怕内存不够的话可以设置小一些
x = [1, 2, 3, 4, 5]
coordinates_lists = [[0, 0, 0, 0, 0],[10, 30, 60, 30, 10],[70, 40, 20, 40, 70],[10, 20, 30, 40, 50],[50, 40, 30, 20, 10],[75, 0, 75, 0, 75],[0, 0, 0, 0, 0]]
print('生成图表\n')
filenames = []
for index in np.arange(0, len(coordinates_lists) - 1):# 获取当前图像及下一图像的y轴坐标值y = coordinates_lists[index]y1 = coordinates_lists[index + 1]# 计算当前图像与下一图像y轴坐标差值y_path = np.array(y1) - np.array(y)for i in np.arange(0, n_frames + 1):# 分配每帧的y轴移动距离# 逐帧增加y轴的坐标值y_temp = (y + (y_path / n_frames) * i)# 绘制条形图plt.bar(x, y_temp)plt.ylim(0, 80)# 保存每一帧的图像filename = f'frame_{index}_{i}.png'filenames.append(filename)# 最后一帧重复,画面停留一会if (i == n_frames):for i in range(5):filenames.append(filename)# 保存图片plt.savefig(filename)plt.close()
print('保存图表\n')# 生成GIF
print('生成GIF\n')
with imageio.get_writer('mybars.gif', mode='I') as writer:for filename in filenames:image = imageio.imread(filename)writer.append_data(image)
print('保存GIF\n')print('删除图片\n')
# 删除图片
for filename in set(filenames):os.remove(filename)
print('完成')

原理解释统计柱状图当前帧和下一帧的差值,然后插帧平滑过去,这里插帧数量配置为了 n_frames = 10

最终生成的 gif 如下(仅播放一次),可以观察到平滑了很多
在这里插入图片描述

接下来美化下界面

import os
import numpy as np
import matplotlib.pyplot as plt
import imageionp.random.seed(1234)n_frames = 5
bg_color = '#95A4AD'
bar_color = '#283F4E'
gif_name = 'bars'
x = [1, 2, 3, 4, 5]
coordinates_lists = [[0, 0, 0, 0, 0],[10, 30, 60, 30, 10],[70, 40, 20, 40, 70],[10, 20, 30, 40, 50],[50, 40, 30, 20, 10],[75, 0, 75, 0, 75],[0, 0, 0, 0, 0]]
print('生成图表\n')
filenames = []
for index in np.arange(0, len(coordinates_lists) - 1):y = coordinates_lists[index]y1 = coordinates_lists[index + 1]y_path = np.array(y1) - np.array(y)for i in np.arange(0, n_frames + 1):y_temp = (y + (y_path / n_frames) * i)# 绘制条形图fig, ax = plt.subplots(figsize=(8, 4))ax.set_facecolor(bg_color)plt.bar(x, y_temp, width=0.4, color=bar_color)plt.ylim(0, 80)# 移除图表的上边框和右边框ax.spines['right'].set_visible(False)ax.spines['top'].set_visible(False)# 设置虚线网格线ax.set_axisbelow(True)ax.yaxis.grid(color='gray', linestyle='dashed', alpha=0.7)# 保存每一帧的图像filename = f'images/frame_{index}_{i}.png'filenames.append(filename)# 最后一帧重复,画面停留一会if (i == n_frames):for i in range(5):filenames.append(filename)# 保存图片plt.savefig(filename, dpi=96, facecolor=bg_color)plt.close()
print('保存图表\n')# 生成GIF
print('生成GIF\n')
with imageio.get_writer(f'{gif_name}.gif', mode='I') as writer:for filename in filenames:image = imageio.imread(filename)writer.append_data(image)
print('保存GIF\n')print('删除图片\n')
# 删除图片
for filename in set(filenames):os.remove(filename)
print('完成')

看看生成的 gif 效果(仅播放一次)

在这里插入图片描述
给图表添加了背景色、条形图上色、去除边框、增加网格线等。

2.3、散点图

import os
import numpy as np
import matplotlib.pyplot as plt
import imageionp.random.seed(1234)coordinates_lists = [[[0], [0]],[[100, 200, 300], [100, 200, 300]],[[400, 500, 600], [400, 500, 600]],[[400, 500, 600, 400, 500, 600], [400, 500, 600, 600, 500, 400]],[[500], [500]],[[0], [0]]]
gif_name = 'movie'
n_frames = 5
bg_color = '#95A4AD'
marker_color = '#283F4E'
marker_size = 25print('生成图表\n')
filenames = []
for index in np.arange(0, len(coordinates_lists) - 1):# 获取当前图像及下一图像的x与y轴坐标值x = coordinates_lists[index][0]  # 当前帧y = coordinates_lists[index][1]x1 = coordinates_lists[index + 1][0]  # 下一帧y1 = coordinates_lists[index + 1][1]# 查看两点差值while len(x) < len(x1):diff = len(x1) - len(x)x = x + x[:diff]y = y + y[:diff]while len(x1) < len(x):diff = len(x) - len(x1)x1 = x1 + x1[:diff]y1 = y1 + y1[:diff]# 计算路径x_path = np.array(x1) - np.array(x)y_path = np.array(y1) - np.array(y)for i in np.arange(0, n_frames + 1):# 计算当前位置x_temp = (x + (x_path / n_frames) * i)y_temp = (y + (y_path / n_frames) * i)# 绘制图表fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(aspect="equal"))ax.set_facecolor(bg_color)plt.scatter(x_temp, y_temp, c=marker_color, s=marker_size)plt.xlim(0, 1000)plt.ylim(0, 1000)# 移除边框线ax.spines['right'].set_visible(False)ax.spines['top'].set_visible(False)# 网格线ax.set_axisbelow(True)ax.yaxis.grid(color='gray', linestyle='dashed', alpha=0.7)ax.xaxis.grid(color='gray', linestyle='dashed', alpha=0.7)# 保存图片filename = f'images/frame_{index}_{i}.png'filenames.append(filename)if (i == n_frames):for i in range(5):filenames.append(filename)# 保存plt.savefig(filename, dpi=96, facecolor=bg_color)plt.close()
print('保存图表\n')# 生成GIF
print('生成GIF\n')
with imageio.get_writer(f'{gif_name}.gif', mode='I') as writer:for filename in filenames:image = imageio.imread(filename)writer.append_data(image)
print('保存GIF\n')print('删除图片\n')
# 删除图片
for filename in set(filenames):os.remove(filename)
print('完成')

思路,计算前后帧坐标点数量的差 diff ,然后 while 循环来复制以实现数量平衡 x = x + x[:diff],最后插帧平滑移动 x_temp = (x + (x_path / n_frames) * i)

在这里插入图片描述

3、参考

  • 太强了,用 Matplotlib+Imageio 制作动画!
  • 如何在 Matplotlib 中更改绘图背景

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15559.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网络安全】服务器安装Docker及拉取镜像教程

文章目录 1. 安装 Docker2. 拉取镜像3. 运行 Ubuntu 容器4. 执行相关操作5. 退出并停止容器1. 安装 Docker # 更新软件包索引 sudo apt update# 安装必要的依赖 sudo apt install -y ca-certificates curl gnupg

Python应用指南:一个库解决常见的国内坐标系转换需求

在地理信息系统&#xff08;GIS&#xff09;和位置服务开发中&#xff0c;坐标转换是一项基础且至关重要的任务&#xff0c;不同坐标系统间的精确转换对于确保地图显示的准确性和提升基于地理位置的服务质量至关重要。coord-convert 库专为解决这一系列坐标转换问题而设计&…

win32汇编环境,对线程的创建与操作示例一

;运行效果 ;win32汇编环境,对线程的创建与操作示例一 ;线程是主进程之外并行运行着的过程&#xff0c;很多的时候&#xff0c;我们需要一些运算保持运行&#xff0c;但又不能影响进程&#xff0c;这个时候就需要线程 ;比如&#xff0c;在游戏外挂之中&#xff0c;需要每隔几秒判…

用 DeepSeek + Kimi 自动做 PPT,效率起飞

以下是使用 DeepSeek Kimi 自动做 PPT 的详细操作步骤&#xff1a; 利用 DeepSeek 生成 PPT 内容&#xff1a; 访问 DeepSeek 官网&#xff0c;完成注册/登录后进入对话界面。输入指令&#xff0c;例如“请用 Markdown 格式生成一份关于[具体主题]的 PPT 大纲&#xff0c;需包…

学习总结二十九

公路维修问题 这里首先先明白题意&#xff0c;就是一段路分为m段&#xff0c;只需要分m-1次。我们先要解决的的问题是如何在合适的地方截断。案例给出&#xff0c;发现第一段的末与第二段的头的位置相差很大&#xff0c;而每一段的每个坑位相差不是很大 。&#xff0c;所以就知…

C语言预处理艺术:编译前的魔法之旅

&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文一、预处理的作用与流程&#xff08;1&…

【go】交叉编译

发现go像是c&#xff0c;做后台还是比较好的 使用的是goland编辑器&#xff0c;可以在windows编译在linux上运行&#xff0c;配置如下&#xff1a; Goland中导入包标红但是能用解决办法 复制了一份项目代码task为task_bk&#xff0c;但是原来的task删除了&#xff0c;再次 把t…

防御综合实验

需求一 配置vlan [SW2]int g 0/0/2 [SW2-GigabitEthernet0/0/2]port link-type access [SW2-GigabitEthernet0/0/2]port default vlan 10 [SW2-GigabitEthernet0/0/2]int g0/0/3 [SW2-GigabitEthernet0/0/3]port link-type access [SW2-GigabitEthernet0/0/3]port default vl…

数据库高安全—数据保护:数据动态脱敏

书接上文数据库高安全—审计追踪&#xff1a;传统审计&统一审计&#xff0c;从传统审计和统一审计两方面对高斯数据库的审计追踪技术进行解读&#xff0c;本篇将从数据动态脱敏方面对高斯数据库的数据保护技术进行解读。 5.1 数据动态脱敏 数据脱敏&#xff0c;顾名思义就…

《艾尔登法环》运行时弹窗“由于找不到vcruntime140.dll,无法继续执行代码”要怎么解决?

宝子们&#xff0c;是不是在玩《艾尔登法环》的时候&#xff0c;突然弹出一个提示&#xff1a;“由于找不到vcruntime140.dll&#xff0c;无法继续执行代码”&#xff1f;这可真是让人着急上火&#xff01;别慌&#xff0c;今天就给大家唠唠这个文件为啥会丢&#xff0c;还有怎…

【Git】Failed to connect to github.com port 443: Timed out

由于DNS污染国内访问github经常会超时&#xff0c;参考网上的方法修改host文件绑定ip过段时间就失效了&#xff0c;这里介绍一个修改工具&#xff0c;通过修改本地host来绕过国内DNS解析实现连接 UsbEAm Hosts Editor UsbEAm Hosts Editor [多平台hosts修改] V3.63 – Dogfigh…

qml RoundButton详解

1、概述 RoundButton是QML&#xff08;Qt Modeling Language&#xff09;中的一种按钮控件&#xff0c;它继承自Button控件&#xff0c;并增加了一个特殊的属性——radius&#xff0c;用于设置按钮圆角的半径。这使得RoundButton能够呈现为带有圆角的形状&#xff0c;而不仅仅…

Django在终端创建项目(pycharm Windows)

1.选择目录 选择或新建一个文件夹&#xff0c;作为项目保存的地方 2.右键在终端打开 3.确定django-admin.exe安装位置 找到自己安装django时&#xff0c;django-admin.exe安装的位置&#xff0c;例如 4.运行命令 使用django-admin.exe的绝对路径&#xff0c;在刚才打开的终端…

Visual Studio 2022 中使用 Google Test

要在 Visual Studio 2022 中使用 Google Test (gtest)&#xff0c;可以按照以下步骤进行&#xff1a; 安装 Google Test&#xff1a;确保你已经安装了 Google Test。如果没有安装&#xff0c;可以通过 Visual Studio Installer 安装。在安装程序中&#xff0c;找到并选择 Googl…

Unity-Mirror网络框架-从入门到精通之LagCompensation示例

文章目录 前言什么是滞后补偿Lag Compensation示例延迟补偿原理ServerCubeClientCubeCapture2DSnapshot3D补充LagCompensation.cs 独立算法滞后补偿器组件注意:算法最小示例前言 在现代游戏开发中,网络功能日益成为提升游戏体验的关键组成部分。本系列文章将为读者提供对Mir…

数据集成实例分享:金蝶云星空对接旺店通实现库存管理自动化

拆卸父项出库&#xff1a;金蝶云星空数据集成到旺店通企业奇门 在现代企业的运营过程中&#xff0c;数据的高效流动和准确处理至关重要。本文将分享一个实际案例&#xff0c;展示如何通过轻易云数据集成平台&#xff0c;将金蝶云星空的数据无缝对接到旺店通企业奇门&#xff0…

Git、Github和Gitee完整讲解:丛基础到进阶功能

第一部分&#xff1a;Git 是什么&#xff1f; 比喻&#xff1a;Git就像是一本“时光机日记本” 每一段代码的改动&#xff0c;Git都会帮你记录下来&#xff0c;像是在写日记。如果出现问题或者想查看之前的版本&#xff0c;Git可以带你“穿越回过去”&#xff0c;找到任意时间…

解锁 DeepSeek 模型高效部署密码:蓝耘平台深度剖析与实战应用

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

autMan奥特曼机器人-对接deepseek教程

一、安装插件ChatGPT 符合openai api协议的大模型均可使用此插件&#xff0c;包括chatgpt-4/chatgpt-3.5-turbo&#xff0c;可自定义服务地址和模型&#xff0c;指令&#xff1a;gpt&#xff0c;要求Python3.7以上&#xff0c;使用官方库https://github.com/openai/openai-pyt…

循环神经网络学习01——transformer:输入部分-嵌入层位置编码

一、介绍 1、核心思想 利用自注意力机制来捕获输入序列中各元素之间的全局依赖关系&#xff0c;无论这些元素之间的实际距离有多远。 自注意力机制&#xff1a;允许模型在处理序列的每个元素时&#xff0c;考虑到序列中的所有其他元素&#xff0c;从而捕捉它们之间的关系和依…