问题描述
使用实时绘图的时候不能看到图像
示例的问题代码:
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
# 创建一个图形窗口和一个子图对象
fig, ax = plt.subplots()
plt.ion() # 打开交互模式,允许在图形窗口中实时更新数据
# 创建一个空白的线条对象
line, = ax.plot([], [])
# 设置子图的属性
# ax.set_xlim(0, 1000)
# ax.set_ylim(0, 1000)
ax.set_title('Random Number')
ax.set_xlabel('Time')
ax.set_ylabel('Value')
rand_list=[]
rand_num=0
# 开始循环
while rand_num<1000:
# 生成一个随机数
rand_num +=1
rand_list.append(rand_num)
ax.set_xlim(0, rand_num)
ax.set_ylim(0, rand_num)
# 更新线条对象的数据
line.set_data(np.arange(len(rand_list)), np.array(rand_list))
# 更新图形窗口
fig.canvas.draw()
plt.pause(0.1)
print(f'yes!{rand_num}')
解决方法
添加一行代码,就可以跑起来了
matplotlib.use('macosx')
完整代码如下
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
matplotlib.use('macosx')
# 你用TkAgg也是可以绘制的
# matplotlib.use('TkAgg')
# 创建一个图形窗口和一个子图对象
fig, ax = plt.subplots()
plt.ion() # 打开交互模式,允许在图形窗口中实时更新数据
# 创建一个空白的线条对象
line, = ax.plot([], [])
# 设置子图的属性
# ax.set_xlim(0, 1000)
# ax.set_ylim(0, 1000)
ax.set_title('Random Number')
ax.set_xlabel('Time')
ax.set_ylabel('Value')
rand_list=[]
rand_num=0
# 开始循环
while rand_num<1000:
# 生成一个随机数
rand_num +=1
rand_list.append(rand_num)
ax.set_xlim(0, rand_num)
ax.set_ylim(0, rand_num)
# 更新线条对象的数据
line.set_data(np.arange(len(rand_list)), np.array(rand_list))
# 更新图形窗口
fig.canvas.draw()
plt.pause(0.1)
print(f'yes!{rand_num}')
效果
问题原因
这里实时显示图形的问题是因为Matplotlib后端设置不正确,可能一般windows上不会有这个问题,因为其默认使用的agg后端在windows上兼容。但是mac上使用agg就会出问题。
常见的几种后端如下
Agg:Anti-Grain Geometry (AGG)是一个用于生成高质量矢量图形的C++库,Agg后端利用该库来生成PNG、PS和PDF格式的图像。由于该后端不支持交互式绘图,因此常用于生成静态图像。
Cairo:Cairo是一个用于生成高质量矢量图形的开源库,它支持生成PNG、PS、PDF和SVG格式的图像。Cairo后端通过调用Cairo库来实现图像的绘制,生成的图像质量很高,而且支持各种字体和线型,但在绘制大量数据时可能会比较慢。
QtAgg:该后端基于Qt GUI框架,可以实现交互式绘图。使用该后端,可以在Matplotlib窗口中进行缩放、平移和旋转等操作,并且可以在图形中添加按钮、菜单和文本框等组件。需要安装Qt库和Python Qt绑定,如PyQt5或PySide2等。
GTKAgg:该后端基于GTK GUI框架,可以实现交互式绘图。使用该后端,可以在Matplotlib窗口中进行缩放、平移和旋转等操作,并且可以在图形中添加按钮、菜单和文本框等组件。需要安装GTK+库和Python GTK绑定,如PyGObject等。
WXAgg:该后端基于WX GUI框架,可以实现交互式绘图。使用该后端,可以在Matplotlib窗口中进行缩放、平移和旋转等操作,并且可以在图形中添加按钮、菜单和文本框等组件。需要安装wxWidgets库和Python WX绑定,如wxPython等。
TkAgg:该后端基于Tkinter GUI框架,提供了实时绘图和交互式GUI的功能。使用该后端,可以在Matplotlib窗口中进行缩放、平移和旋转等操作,并且可以在图形中添加按钮、菜单和文本框等组件。由于Tkinter库是Python自带的,因此该后端是Matplotlib默认的后端。
MacOSX:该后端是适用于MacOS X平台的后端,可以实现交互式的绘图。使用该后端,可以在Matplotlib窗口中进行缩放、平移和旋转等操作,并且可以在图形中添加按钮、菜单和文本框等组件。该后端支持Retina显示,并且可以使用苹果电脑自带的字体。
WebAgg:该后端可以将绘图输出到Web浏览器中,支持HTML5和WebSocket技术。使用该后端,可以将Matplotlib图形嵌入到wxPython应用程序中。
用代码查看具体的后端模块
更具体地,你可以到matplotlib.backends模块中去查看各种不同后端的具体实现
# 使用如下代码打印你的后端模块
import matplotlib.backends as be
import os
be_dir = be.__path__[0]
print(be_dir)
for root, dirs, files in os.walk(be_dir):
level = root.replace(be_dir, '').count(os.sep)
indent = ' ' * 4 * (level)
print(f"{indent}{os.path.basename(root)}/")
subindent = ' ' * 4 * (level + 1)
for f in files:
print(f"{subindent}{f}")