问题
I ran into a python error that i have been trying to solve for several days now. My program creates figures, saves and closes them which works fine except for this error. Usually it does not hinder the saving process but sometimes a picture is missing the lower part when saved. The odd thing is that this only happens every second time the loop reaches the savefig method, here is my code:
for num in np.arange(file_number):
plt.figure('abc' + str(num),figsize=(22,12),dpi=100)
#some plots are added to the figure
print 1
plt.savefig(os.path.join(savepath,filename),dpi=100)
print 2
plt.close()
print 3
I use the print commands to see where the error occurs. Here is the console output of spyder:
Reading file1.file
1
2
3
Reading file2.file
1
Traceback (most recent call last):
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_qt4.py", line 151, in <lambda>
lambda: self.close_event())
File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1564, in close_event
self.callbacks.process(s, event)
RuntimeError: underlying C/C++ object has been deleted
2
3
Reading file3.file
1
2
3
Reading file4.file
1
Traceback (most recent call last):
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_qt4.py", line 151, in <lambda>
lambda: self.close_event())
File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1564, in close_event
self.callbacks.process(s, event)
RuntimeError: underlying C/C++ object has been deleted
2
3
To my understanding, the error already occurs while saving the figure (every second time), although it works fine if i omit the close() command. In that case, my RAM is filled after about 70 files and sometimes i need to evaluate a couple of hundreds. That's why i need to include the close() command or something similar. If you solve this (or improve my programing, i guess the way i did this saving and closing might be considered ugly) please help me.
回答1:
How about change the backend to other options? For example:
import matplotlib as mpl
mpl.use( "agg" )
from matplotlib import pyplot as plt
import numpy as np
print plt.get_backend()
file_number = 100
for num in np.arange(file_number):
plt.figure('abc' + str(num),figsize=(22,12),dpi=100)
#some plots are added to the figure
print 1
plt.savefig("%d.png" % num,dpi=100)
print 2
plt.close()
print 3
回答2:
I can't replicate your problem (partially because your example is not self contained), but I think you could look at going about solving the problem slightly different.
Since your figure definition (size, dpi, etc.) stays the same throughout the loop (and even if it didn't) you could look at producing just one figure, and updating it inside the loop:
import matplotlib as mpl
mpl.use( "tkagg" )
from matplotlib import pyplot as plt
import numpy as np
file_number = 1000
fig = plt.figure('abc', figsize=(22,12), dpi=100)
plt.show(block=False)
for num in np.arange(file_number):
fig.set_label('abc%s' % num)
# add an axes to the figure
ax = plt.axes()
#some plots are added to the figure (I just plotted a line)
plt.plot(range(num))
plt.savefig("%d.png" % num, dpi=100)
# draw the latest changes to the gui
plt.draw()
# remove the axes now that we have done what we want with it.
fig.delaxes(ax)
# put in a blocking show to wait for user interaction / closure.
plt.show()
Typically this isn't how you would do things (I would normally update the axes rather than add/remove one each time) but perhaps you have a good reason for doing it this way.
That should improve the performance significantly.
来源:https://stackoverflow.com/questions/11670495/runtimeerror-underlying-c-c-object-has-been-deleted-when-saving-and-afterward