使用Matplotlib Animation出现MatplotlibDeprecationWarning的解决求助
我在开发Arduino实时数据绘图脚本时,运行代码后出现了以下Matplotlib弃用警告:
MatplotlibDeprecationWarning: Support for FigureCanvases without a required_interactive_framework attribute was deprecated in Matplotlib 3.6 and will be removed two minor releases later.
使用的脚本代码如下:
import time import serial import comport as com import matplotlib.pyplot as plt import matplotlib.animation as animation def animate(i, dataList, ser): arduinoData_string = ser.readline().decode('ascii') # Decode receive Arduino data as a formatted string # print(i) # 'i' is a incrementing variable based upon frames = x argument try: arduinoData_float = float(arduinoData_string) # Convert to float dataList.append(arduinoData_float) # Add to the list holding the fixed number of points to animate except: # Pass if data point is bad pass dataList = dataList[-50:] # Fix the list size so that the animation plot 'window' is x number of points ax.clear() # Clear last data frame ax.plot(dataList) # Plot new data frame ax.set_ylim([0, 1200]) # Set Y axis limit of plot ax.set_title("Arduino Data") # Set title of figure ax.set_ylabel("Value") # Set title of y axis dataList = [] # Create empty list variable for later use fig = plt.gcf() # Create Matplotlib plots fig is the 'higher level' plot window ax = fig.add_subplot(111) # Add subplot to main fig window ser = com.ini('COM2') time.sleep(2) # Time delay for Arduino Serial initialization # Matplotlib Animation Fuction that takes takes care of real time plot. # Note that 'fargs' parameter is where we pass in our dataList and Serial object. # ani = FuncAnimation(fig, animate, frames=100, fargs=(dataList, ser), interval=100) ani = animation.FuncAnimation(fig, animate, frames=100, fargs=(dataList, ser), interval=100) plt.show() # Keep Matplotlib plot persistent on screen until it is closed ser.close()
环境配置:PyCharm最新版本,Matplotlib 3.7.1
解决方法
这个警告的核心原因是Matplotlib 3.6及以上版本要求交互式画布必须明确指定框架,以下是几种可行的解决方式:
显式指定Matplotlib交互式后端
在脚本最开头添加代码,指定一个兼容的交互式后端(比如Qt5Agg、TkAgg),注意要放在导入matplotlib.pyplot之前:import matplotlib matplotlib.use('Qt5Agg')替换
plt.gcf()为显式创建Figure对象
原代码中fig = plt.gcf()可能导致画布初始化不规范,改为直接创建Figure和Axes对象,既简化代码又能确保画布正确初始化:fig, ax = plt.subplots()修改PyCharm的绘图显示设置
打开PyCharm的Settings → Tools → Python Scientific,取消勾选Show plots in tool window。这样Matplotlib会使用系统默认的交互式窗口显示绘图,避免内嵌工具窗口带来的后端兼容问题。
修改后的完整脚本示例
结合前两种解决方法,修改后的代码如下:
import matplotlib matplotlib.use('Qt5Agg') # 先指定交互式后端 import time import serial import comport as com import matplotlib.pyplot as plt import matplotlib.animation as animation def animate(i, dataList, ser): arduinoData_string = ser.readline().decode('ascii') try: arduinoData_float = float(arduinoData_string) dataList.append(arduinoData_float) except: pass dataList = dataList[-50:] ax.clear() ax.plot(dataList) ax.set_ylim([0, 1200]) ax.set_title("Arduino Data") ax.set_ylabel("Value") dataList = [] fig, ax = plt.subplots() # 显式创建Figure和Axes ser = com.ini('COM2') time.sleep(2) ani = animation.FuncAnimation(fig, animate, frames=100, fargs=(dataList, ser), interval=100) plt.show() ser.close()
内容的提问来源于stack exchange,提问作者Valery Utukin

