如何在不使用save()函数的情况下实现Matplotlib动画透明背景?
实现PyQt6中Matplotlib动画的透明背景(无需保存)
问题需求
需要将Matplotlib音频可视化动画集成到PyQt6 GUI中,当前使用Windows10系统,必须设置mlp.use("TkAgg")才能显示内容,背景为黑色。目标是仅保留紫色曲线,实现实时透明背景,且无需使用save()函数。
解决方案
核心是切换到PyQt6对应的Matplotlib后端,直接在Qt窗口中嵌入画布并设置透明属性,无需依赖save()。
修改后的完整代码
import queue import sys from matplotlib.animation import FuncAnimation import PyQt6.QtWidgets as QtWidgets import PyQt6.QtCore import matplotlib as mlp # 使用PyQt6对应的后端 mlp.use("QtAgg") from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure import numpy as np import sounddevice as sd # 配置Matplotlib参数 mlp.rcParams['toolbar'] = 'None' # 音频相关变量 device = 0 # 默认音频设备ID window = 1000 # 数据窗口大小 downsample = 1 # 下采样比例 channels = [1] # 音频通道 interval = 40 # 绘图更新间隔(毫秒) q = queue.Queue() device_info = sd.query_devices(device, 'input') samplerate = device_info['default_samplerate'] length = int(window * samplerate / (1000 * downsample)) plotdata = np.zeros((length, len(channels))) class TransparentPlotWindow(QtWidgets.QMainWindow): def __init__(self): super().__init__() # 设置窗口透明 self.setAttribute(PyQt6.QtCore.Qt.WidgetAttribute.WA_TranslucentBackground) self.setWindowFlags(PyQt6.QtCore.Qt.WindowType.FramelessWindowHint) self.setGeometry(850, 450, 200, 100) # 创建Matplotlib画布 self.fig = Figure(figsize=(2, 1)) self.canvas = FigureCanvas(self.fig) self.setCentralWidget(self.canvas) # 设置画布和坐标轴透明 self.fig.patch.set_alpha(0) self.ax = self.fig.add_subplot(111) self.ax.patch.set_alpha(0) self.ax.axis("off") self.fig.subplots_adjust(0, 0, 1, 1) # 创建曲线 self.lines = self.ax.plot(plotdata, color="purple") # 初始化音频流 self.stream = sd.InputStream( device=device, channels=max(channels), samplerate=samplerate, callback=self.audio_callback ) # 创建动画 self.ani = FuncAnimation( self.fig, self.update_plot, interval=interval, blit=True ) def audio_callback(self, indata, frames, time, status): q.put(indata[::downsample, [0]]) def update_plot(self, frame): global plotdata while True: try: data = q.get_nowait() except queue.Empty: break shift = len(data) plotdata = np.roll(plotdata, -shift, axis=0) plotdata[-shift:, :] = data for column, line in enumerate(self.lines): line.set_ydata(plotdata[:, column]) return self.lines if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = TransparentPlotWindow() window.show() with window.stream: sys.exit(app.exec())
关键修改说明
- 后端切换:将
TkAgg改为QtAgg,适配PyQt6集成,解决Windows下无输出的问题 - 透明设置:
- 对Qt窗口设置
WA_TranslucentBackground和FramelessWindowHint实现整体透明 - 设置
fig.patch.set_alpha(0)和ax.patch.set_alpha(0)让Matplotlib画布和坐标轴背景透明
- 对Qt窗口设置
- 界面精简:移除标题、坐标轴元素,仅保留紫色曲线
- PyQt6集成:将Matplotlib画布嵌入Qt主窗口,替代原有的
plt.show(),实现GUI集成
内容的提问来源于stack exchange,提问作者Harun Harman
相关产品推荐
相关产品推荐

