Python 在使用 PyQt 和 matplotlib 时泄漏内存
我在 Python 中创建了一个基于 PyQt 的小型实用程序,当用户单击按钮时,它使用 matplotlib 创建 PNG 图形。 在最初的几次点击中,一切都运行良好,但是每次创建图像时,应用程序的内存占用量都会增加约 120 MB,最终使 Python 完全崩溃。
创建图表后如何恢复该内存? 我在这里包含了代码的简化版本:
import datetime as dt
from datetime import datetime
import os
import gc
# For Graphing
import matplotlib
from pylab import figure, show, savefig
from matplotlib import figure as matfigure
from matplotlib.dates import MonthLocator, WeekdayLocator, DateFormatter, DayLocator
from matplotlib.ticker import MultipleLocator
import matplotlib.pyplot as plot
import matplotlib.ticker as ticker
# For GUI
import sys
from PyQt4 import QtGui, QtCore
class HyperGraph(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowTitle('Title')
self.create_widgets()
def create_widgets(self):
grid = QtGui.QGridLayout()
self.generate_button = QtGui.QPushButton("Generate Graph", self)
grid.addWidget(self.generate_button, 1, 1)
QtCore.QObject.connect(self.generate_button, QtCore.SIGNAL("clicked()"), self.generate_graph)
def generate_graph(self):
try:
fig = figure()
ax = fig.add_axes([1,1,1,1])
# set title
ax.set_title('Title')
# configure x axis
plot.xlim(dt.date.today() - dt.timedelta(days=180), dt.date.today())
ax.set_xlabel('Date')
fig.set_figwidth(100)
# configure y axis
plot.ylim(0, 200)
ax.set_ylabel('Price')
fig.set_figheight(30)
# export the graph to a png file
plot.savefig('graph.png')
except:
print 'Error'
plot.close(fig)
gc.collect()
app = QtGui.QApplication(sys.argv)
hyper_graph = HyperGraph()
hyper_graph.show()
sys.exit(app.exec_())
plot.savefig('graph.png') 命令似乎是占用内存的。
我将非常感谢任何帮助!
I've created a small PyQt based utility in Python that creates PNG graphs using matplotlib when a user clicks a button. Everything works well during the first few clicks, however each time an image is created, the application's memory footprint grows about 120 MB, eventually crashing Python altogether.
How can I recover this memory after a graph is created? I've included a simplified version of my code here:
import datetime as dt
from datetime import datetime
import os
import gc
# For Graphing
import matplotlib
from pylab import figure, show, savefig
from matplotlib import figure as matfigure
from matplotlib.dates import MonthLocator, WeekdayLocator, DateFormatter, DayLocator
from matplotlib.ticker import MultipleLocator
import matplotlib.pyplot as plot
import matplotlib.ticker as ticker
# For GUI
import sys
from PyQt4 import QtGui, QtCore
class HyperGraph(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowTitle('Title')
self.create_widgets()
def create_widgets(self):
grid = QtGui.QGridLayout()
self.generate_button = QtGui.QPushButton("Generate Graph", self)
grid.addWidget(self.generate_button, 1, 1)
QtCore.QObject.connect(self.generate_button, QtCore.SIGNAL("clicked()"), self.generate_graph)
def generate_graph(self):
try:
fig = figure()
ax = fig.add_axes([1,1,1,1])
# set title
ax.set_title('Title')
# configure x axis
plot.xlim(dt.date.today() - dt.timedelta(days=180), dt.date.today())
ax.set_xlabel('Date')
fig.set_figwidth(100)
# configure y axis
plot.ylim(0, 200)
ax.set_ylabel('Price')
fig.set_figheight(30)
# export the graph to a png file
plot.savefig('graph.png')
except:
print 'Error'
plot.close(fig)
gc.collect()
app = QtGui.QApplication(sys.argv)
hyper_graph = HyperGraph()
hyper_graph.show()
sys.exit(app.exec_())
The plot.savefig('graph.png') command seems to be what's gobbling up the memory.
I'd greatly appreciate any help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
似乎某些后端正在泄漏内存。 尝试明确设置您的后端,例如
It seems that some backends are leaking memory. Try setting your backend explicitly, e.g.
pyplot 接口旨在轻松交互使用,但对于嵌入应用程序,面向对象的 API 更好。 例如,pyplot 会跟踪您创建的所有图形。 你的plot.close(figure)应该摆脱它们,但也许它没有被执行 - 尝试将它放入
finally
或重复使用相同的图形对象。请参阅使用面向对象 API 在 PyQt4 应用程序中嵌入 matplotlib 的此示例。 这是更多的工作,但由于一切都是明确的,因此您不应该从 pyplot 所做的幕后自动化中获得内存泄漏。
The pyplot interface is meant for easy interactive use, but for embedding in an application the object-oriented API is better. For example, pyplot keeps track of all figures you have created. Your
plot.close(figure)
should get rid of them, but maybe it doesn't get executed -- try putting it insidefinally
or reusing the same figure object.See this example of embedding matplotlib in a PyQt4 application using the object-oriented API. It's more work, but since everything is explicit, you shouldn't get memory leaks from the behind-the-scenes automation that pyplot does.