如何在Matplotlib中生成图像但不显示绘图
如何在Matplotlib中生成图像但不显示绘图
嘿,我完全懂你的烦恼——每次调用这个函数都弹出绘图窗口,要是频繁调用的话确实太干扰了!别担心,这里有几个实用的方法能让你悄悄生成图像,完全不会显示绘图:
方法一:切换到非交互式后端
Matplotlib的后端决定了图像的显示方式,Agg是专门用于离线生成图像的后端,不会弹出任何显示窗口。你只需要在导入pyplot之前切换后端就行:import matplotlib matplotlib.use('Agg') # 一定要放在导入plt之前 import matplotlib.pyplot as plt from matplotlib.backends.backend_agg import FigureCanvasAgg import numpy as np注意:如果之后你还需要显示其他绘图,记得切换回原来的后端(比如在Colab里用
matplotlib.use('inline'))。方法二:生成后立即关闭绘图
这个方法更灵活,不需要修改全局后端,只需要在函数里生成图像后关闭对应的figure就行。修改你的函数,在canvas.draw()之后加上plt.close(figure):def DrawKernel(x = 0.5, y = 0.5, radius = 0.49, dimension = 256): '''Make a solid circle and return a numpy array of it''' DPI = 100 figure, axes = plt.subplots(figsize=(dimension/DPI, dimension/DPI), dpi=DPI) canvas = FigureCanvas(figure) Drawing_colored_circle = plt.Circle(( x, y ), radius, color='k') axes.set_aspect( 1 ) axes.axis("off") axes.add_artist( Drawing_colored_circle ) canvas.draw() # 关闭当前figure,避免显示 plt.close(figure) # Convert figure into an numpy array img = np.frombuffer(canvas.tostring_rgb(), dtype='uint8') img = img.reshape(dimension, dimension, 3) return img这个方式不会影响你后续用Matplotlib显示其他图像,非常适合只需要隐藏当前函数生成的图的场景。
方法三:直接创建底层Figure对象
如果你想彻底绕开pyplot的交互式机制,可以直接创建Figure和FigureCanvasAgg对象,完全不依赖plt.subplots,从根源上避免显示:from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg import numpy as np def DrawKernel(x = 0.5, y = 0.5, radius = 0.49, dimension = 256): '''Make a solid circle and return a numpy array of it''' DPI = 100 # 直接创建Figure实例,不通过pyplot figure = Figure(figsize=(dimension/DPI, dimension/DPI), dpi=DPI) canvas = FigureCanvasAgg(figure) axes = figure.add_subplot() Drawing_colored_circle = plt.Circle(( x, y ), radius, color='k') axes.set_aspect( 1 ) axes.axis("off") axes.add_artist( Drawing_colored_circle ) canvas.draw() # Convert figure into an numpy array img = np.frombuffer(canvas.tostring_rgb(), dtype='uint8') img = img.reshape(dimension, dimension, 3) return img这种方式适合批量生成大量图像的场景,完全不会有意外的显示窗口弹出。
在Google Colab环境下,方法二应该是最简单直接的,你可以先试试这个!
备注:内容来源于stack exchange,提问作者Amarth Gûl




