【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.pswp.cn/news/895100.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895100.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895100.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【東莞常平】戴爾R710服務器不開機維修分享

1&#xff1a;2025-02-06一位老客戶的朋友剛開工公司ERP服務器一臺戴爾老服務器故障無法開機&#xff0c;于是經老客戶介紹找到我們。 2&#xff1a;服務器型號是DELL PowerEdge R710 這個服務器至少也有15年以上的使用年限了。 3&#xff1a;客戶反饋的故障問題為&#xff1a;…

Spring AI -使用Spring快速開發ChatGPT應用

前言 Spring在Java生態中一直占據大半江山。最近我發現Spring社區推出了一個Spring AI項目&#xff0c;目前該項目還屬于Spring實驗性項目&#xff0c;但是我們可以通過該項目&#xff0c;可以非常快速的開發出GPT對話應用。 本篇文章將會對SpringAI進行簡單的介紹和使用&#…

經典排序算法復習----C語言

經典排序算法復習 分類 交換類 冒泡快排 分配類 計數排序基數排序 選擇類 選擇排序 堆排序 歸并類 歸并排序 插入類 直接插入排序 希爾排序 折半插入排序 冒泡排序 基于交換。每一輪找最大值放到數組尾部 //冒泡排序 void bubSort(int* arr,int size){bool sorte…

BFS解決拓撲排序(3題)

目錄 拓撲排序 1.如何排序&#xff1f; 2.如何形成拓撲排序 3.如何建圖 1.看數據稠密度 2. 根據算法流程靈活建圖 1.課程表 2.課程表2 3.火星詞典 拓撲排序 找到做事情的先后順序&#xff0c;拓撲排序的結果可能不是唯一的 1.如何排序&#xff1f; 1.找出圖中入度為…

kafka 3.5.0 raft協議安裝

前言 最近做項目&#xff0c;需要使用kafka進行通信&#xff0c;且只能使用kafka&#xff0c;筆者沒有測試集群&#xff0c;就自己搭建了kafka集群&#xff0c;實際上筆者在很早之前就搭建了&#xff0c;因為當時還是zookeeper&#xff08;簡稱ZK&#xff09;注冊元數據&#…

Unity項目接入xLua的一種流程

1. 導入xlua 首先導入xlua&#xff0c;這個不用多說 2. 編寫C#和Lua交互腳本 基礎版本&#xff0c;即xlua自帶的版本 using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; using System; using System.IO;[Serializable] public…

四次揮手詳解

文章目錄 一、四次揮手各狀態FIN_WAIT_1CLOSE_WAITFIN_WAIT_2LAST_ACKTIME_WAITCLOSE 二、雙方同時調用close()&#xff0c;FIN_WAIT_1狀態后進入CLOSING狀態CLOSING狀態 三、TIME_WAIT狀態詳解(1) TIME_WAIT狀態下的2MSL是什么MSL &#xff08;報文最大生存時間&#xff09;為…

【嵌入式 Linux 音視頻+ AI 實戰項目】瑞芯微 Rockchip 系列 RK3588-基于深度學習的人臉門禁+ IPC 智能安防監控系統

前言 本文主要介紹我最近開發的一個個人實戰項目&#xff0c;“基于深度學習的人臉門禁 IPC 智能安防監控系統”&#xff0c;全程滿幀流暢運行。這個項目我目前全網搜了一圈&#xff0c;還沒發現有相關類型的開源項目。這個項目只要稍微改進下&#xff0c;就可以變成市面上目前…

java: framework from BLL、DAL、IDAL、MODEL、Factory using oracle

oracel 21c sql: -- 創建 School 表 CREATE TABLE School (SchoolId CHAR(5) NOT NULL,SchoolName NVARCHAR2(500) NOT NULL,SchoolTelNo VARCHAR2(8) NULL,PRIMARY KEY (SchoolId) );CREATE OR REPLACE PROCEDURE addschool(p_school_id IN CHAR,p_school_name IN NVARCHAR2,p…

解決錯誤:CondaHTTPError: HTTP 000 CONNECTION FAILED for url

解決錯誤&#xff1a;CondaHTTPError: HTTP 000 CONNECTION FAILED for url 查看channels:vim ~/.condarcshow_channel_urls: true channels:- http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/- http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/…

Apache APISIX 快速入門

文章目錄 apisix 快速入門什么是apisix有了 NGINX 和 Kong&#xff0c;為什么還需要 Apache APISIX&#xff1f;軟件架構基于 Nginx 開源版本&#xff0c;而 Nginx 并不支持動態配置&#xff0c;為什么 Apache APISIX 聲稱自己可以實現動態配置&#xff1f; 安裝配置 APISIX配置…

2025嵌入式高頻面試題解析

一、概述 到了年初&#xff0c;是求職者最活躍的時間。本文梳理了嵌入式高頻面試題&#xff0c;幫助求職者更好地準備面試&#xff0c;同時也為技術愛好者提供深入學習嵌入式知識的參考。 二、C 語言基礎 2.1 指針與數組 問題 1&#xff1a;指針和數組的區別是什么&#xf…

1.攻防世界 baby_web

題目描述這里有提示&#xff0c;初始頁面 進入題目頁面如下 很簡潔的頁面只有一行HELLO WORLD ctrlu查看了源碼也沒有信息 用burp suite抓包&#xff0c;并發送到重放器 根據提示&#xff08;初始頁面&#xff09;修改訪問index.php文件 index.php index.php 是一種常見的…

什么是三層交換技術?與二層有什么區別?

什么是三層交換技術&#xff1f;讓你的網絡飛起來&#xff01; 一. 什么是三層交換技術&#xff1f;二. 工作原理三. 優點四. 應用場景五. 總結 前言 點個免費的贊和關注&#xff0c;有錯誤的地方請指出&#xff0c;看個人主頁有驚喜。 作者&#xff1a;神的孩子都在歌唱 大家好…

【機器學習】數據預處理之數據歸一化

數據預處理之數據歸一化 一、摘要二、數據歸一化概念三、數據歸一化實現方法3.1 最值歸一化方法3.2 均值方差歸一化方法 一、摘要 本文主要講述了數據歸一化&#xff08;Feature Scaling&#xff09;的重要性及其方法。首先通過腫瘤大小和發現時間的例子&#xff0c;說明了不同…

【AIGC】語言模型的發展歷程:從統計方法到大規模預訓練模型的演化

博客主頁&#xff1a; [小????????] 本文專欄: AIGC | ChatGPT 文章目錄 &#x1f4af;前言&#x1f4af;語言模型的發展歷程&#xff1a;從統計方法到大規模預訓練模型的演化1 統計語言模型&#xff08;Statistical Language Model, SLM&#xff09;&#xff1a;統…

高效知識管理與分類優化指南:從目錄設計到實踐應用

摘要 本文旨在幫助讀者在信息爆炸時代構建高效的知識管理體系&#xff0c;提供了知識收藏目錄、瀏覽器書簽和電腦文件夾的優化分類方案。知識收藏目錄方案包括工作與項目、記錄與日常、知識管理等八大類&#xff0c;具有邊界清晰、擴展靈活、貼合實際場景等優勢。瀏覽器書簽分類…

OpenAI 實戰進階教程 - 第十二節 : 多模態任務開發(文本、圖像、音頻)

適用讀者與目標 適用讀者&#xff1a;已經熟悉基礎的 OpenAI API 調用方式&#xff0c;對文本生成或數據處理有一定經驗的計算機從業人員。目標&#xff1a;在本節中&#xff0c;你將學會如何使用 OpenAI 提供的多模態接口&#xff08;圖像生成、語音轉錄等&#xff09;開發更…

Java面試題2025-JVM

JVM 1.為什么需要JVM&#xff0c;不要JVM可以嗎&#xff1f; 1.JVM可以幫助我們屏蔽底層的操作系統 一次編譯&#xff0c;到處運行 2.JVM可以運行Class文件 2.JDK&#xff0c;JRE以及JVM的關系 3.我們的編譯器到底干了什么事&#xff1f; 僅僅是將我們的 .java 文件轉換成了…

Deepseek的MLA技術原理介紹

DeepSeek的MLA(Multi-head Latent Attention)技術是一種創新的注意力機制,旨在優化Transformer模型的計算效率和內存使用,同時保持模型性能。以下是MLA技術的詳細原理和特點: 1. 核心思想 MLA技術通過低秩聯合壓縮技術,將多個注意力頭的鍵(Key)和值(Value)映射到一…