getting memory error while plotting multiple plots - python

plt.clf()
plt.figure().clear()
plt.close()
plt.close(fig)
plt.close('all')
None of these lines which are solutions that I find in stack overflow like this one When to use cla(), clf() or close() for clearing a plot in matplotlib? work for me and I constantly get MemoryError: or tkinter.TclError: not enough free memory for image buffer
I used them at the end of my loop which plotted figures.
for i in range(1000):
fig, axs = plt.subplots(2,figsize=(12, 8), dpi=400, facecolor='w', edgecolor='k')
axs[0].plot([0,1],[2,3])
axs[1].plot([0,1],[2,3])
plt.savefig("a.png")
plt.clf()
plt.figure().clear()
plt.close()
plt.close(fig)
plt.close('all')
What else can I do?
And can you tell me is it a bug so it's gonna be debugged later which it doesn't seem to. so how my problem can be described (you may think why I'm asking you??!), cause there are really none possibilities that I had written those lines wrong or put it wrong where.

Related

How to save a pyplot figure in its maximized state

I am trying to save a pyplot figure in its maximized form as displayed when I call plt.show() because maximizing the graph correctly displays the data, while a smaller 'windowed' version of the plot that is currently getting saved has the data incorrectly shifted/formatted.
Current code:
mng = plt.get_current_fig_manager()
mng.window.showMaximized()
plt.savefig(path + '.png', dpi=fig.dpi)
plt.show()
I use the current_fig_manager to force plot.show() to show in its maximized state which it does correctly, but plt.savefig() still saves the fig in the smaller format.
I am looking into ways to grab the dimensions of mng.window.showMaximized() in inches and then plugging that into savefig() but was wondering if there is a better approach?
Try to config the figure size before starting the code with plt.figure(figsize=(width, height)). See bellow a example:
plt.figure(figsize=(10,6)) #10,6 is the figure dimensions
plt.plot(...)
...
plt.savefig(...)
Doing that the savefig function will use the defined dimensions.
Solution is create a figure and set the size in inches there, then save the figure instead of the plot.
fig = matplotlib.pyplot.gcf()
fig.set_size_inches(18.5, 10.5)
fig.savefig('test2png.png', dpi=100)

How to save a figure without the borders/margins in matplotlib.pyplot?

I know there is a very similar question here. However, I tried all of the possible solutions posted there and absolutely none of them worked for me. This is why I'm creating this question.
This is what I have:
import matplotlib.pyplot as plt
from scipy.io import wavfile
sample_rate, samples = wavfile.read('audio-mono-70.wav')
fig = plt.figure(figsize=(6,1), dpi=500, frameon=False)
ax = plt.Axes(fig, [0,0,1,1])
ax.set_facecolor((0.169,0.169,0.169))
ax.set_xlim(left=0, right=700000)
fig.add_axes(ax)
plt.tick_params(axis='both', which='both', bottom=False,
top=False, left=False, right=False,
labelbottom=False, labeltop=False,
labelright=False, labelleft=False)
plt.plot(samples)
plt.savefig('samples.png')
With this, I'm getting everything I want, except for the presence of those margins. Here it is.
And what I want is something like this. I modified this image manually just to show you what I need. I need the image to not have those small margins. I am setting the x limits because I want the plot to reach the left and right borders of the image, but that black margin is getting in the way.
Using bbox_inches='tight' and pad_inches=0, seems to not work in newer versions of matplotlib, and using plt.savefig(fname, bbox_inches='tight', transparent=True, pad_inches=0) didn't work for me either. I get the exact same result. Also tried extent = mpl.transforms.Bbox(((0, 0), (width, height))) and then bbox_inches=extent, but still nothing. None of those in that post.
How can I do this?
Thanks in advance.
EDIT 1
Added code to create the exact same array with which the plot was created.
Find the exact same audio here
EDIT 2
The rgb values for the ax.set_facecolor() originally set it to black, but the images had gray facecolor. Fixed in this edit.
I got help somewhere else and these borders/margins are called spines.
They are deleted in the following way, in my case:
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_visible(False)

Matplotlib/Latex issues when using \odot as marker

I'm trying to use the latex symbol \odot as a marker in a scatter plot but I also need latex style ticks, but for some reason these two are not playing well together. I can successfully use marker=$\\odot$ with usetex=False, like this, but when I set it equal to true (to get the tick font right), I get ! LaTeX Error: File 'type1cm.sty' not found. I've already gone through to make sure I have the sty file installed and in the correct directory and that I have all the dependencies installed (as suggested here). Plus, I can still have usetex=True and use any of the normal pyplot markers, just not anything involving math font, but can I can have \odot in the label for the legend. Ive also already tried appending the rc params with amsmath but still keep getting the type1cm error. I've also tried using the raw string literal to no avail.
So basically when usetex=True, I can use math symbols in the label for the legend, just not as the actual marker. Has anyone experienced this issue before?
My current work around involves just plotting a large unfilled circle and overplotting a small filled circle (basically simulating the odot). Then I run into an issue with the legend so I basically have to create a transparent legend showing the large unfilled circles and then plot the smaller filled circles behind it by hand like this which ends up wonky, but this has the axes tick font I need. This becomes very frustrating if I have to change axes limits though, because I have to repeat the process of figuring out where to plot the small filled circles all over again.
Does anyone know if there is a better work around than this? Would it be possible to use the overplotting scheme like I have been, but then create a custom proxy artist to display the \odot symbol (in the different colors/sizes) in the legend?
Mac OSX, matplotlib 1.4.2, python 2.7, matplotlib is using pdfTeX thru TeX Live 2017/Mac Ports 2017
Edit: Here is my code
plt.rc('text', usetex=True)
plt.rc('font', family='serif')
f, ax1 = plt.subplots(1,1)
x = np.arange(20)
y = x
ax1.scatter(x, y, marker='$\\odot$', edgecolors='b', s=200, label = 'Test') #used with usetex=False
#ax1.scatter(x, y, marker='o', edgecolors='b', s=200, label = 'Test') #used with usetex=True
ax1.tick_params(labelsize=24)
leg = ax1.legend(scatterpoints=1, loc='lower right', borderaxespad=0., handletextpad=0.)#, fontsize=18) # borderpad=0.,)
I'm not sure how much I can help without seeing your code, but this worked for me:
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
x1 = [1,2]; x2 = [1,2]
y1 = [1,1]; y2 = [2,2]
mpl.rc('text', usetex = True)
fig, ax = plt.subplots(1,1)
ax.scatter(x1,y1, label='A1', marker=r'$\odot$',s=150, c='b')
ax.scatter(x2,y2, label='A2', marker=r'$\odot$',s=50, c='b')
ax.set_xlim(0,3)
ax.set_ylim(0,3)
ax.legend()
fig.show()
If this doesn't help let me know!

setting up figure handle for basemap

I don't really understand how to use properly figure handles, for example in setting up a figure and clearing and/or closing it. Here, I am plotting using basemap in a for loop.
I fixed the overlapping problem of my colorbars appearing in my plots produced by the for loop, by adding the lines fig=plt.figure() and plt.clf() but I do not understand why or how I can use the 'fig' handle below in my script (is it the same as the 'cs' handle for the m.pcolor?)
I also get an error message that there are too many open figures when I have the below code in the for loop, and so added the line plt.close(fig)
fig=plt.figure()
cs = m.pcolor(LON_subset,LAT_subset,ma.masked_where(land_mask_subset,data))
# add colorbar
cbar = m.colorbar(cs,location='bottom', pad="3%")
cbar.set_label('J/m$^2$',size=17)
cbar.ax.tick_params(labelsize=16)
plt.clf()
plt.close(fig)
#plt.show()

How to save plot after the plot is zoomed

Last few days I have been facing a problem in saving the matplotlib figure, three days before the code was working fine and saves the plot with changes made through the code, but now the changes (zoomed plot) is not saving rather it saves as it is when the plot is shown any changes made after does not reflects using the save command, don't know why?
ax = pd.rolling_mean(dataToPlot_plot[startTime:endTime][['plotValue']],mar).plot(linestyle='-', linewidth=3, markersize=9, color='#FECB00')
ax.legend().set_visible(False)
plt.show()#showing the plot
fig = ax.get_figure()
fig.set_size_inches(12, 6)#setting the size of the plot, to fix in the PDF file
fig.savefig('graph1.jpg')#saving the plot
even if I call a function, the new changed plot is not saved...
def callmeto_plot()
ax = pd.rolling_mean(dataToPlot_plot[startTime:endTime][['plotValue']],mar).plot(linestyle='-', linewidth=3, markersize=9, color='#FECB00')
ax.legend().set_visible(False)
plt.show()#showing the plot
fig = ax.get_figure()
return fig
fig = callmeto_plot()
fig.set_size_inches(12, 6)
fig.savefig('graph1.jpg')
How do I save the plot (zoomed one with changes) through code? Note: I have noticed that the plot window appearance is also changed, 1 Plot window appearance before 2 Plot window appearance now all the plot window configuration buttons are shifted from bottom to top, does this change affects only in the plot or affects the coding as well?. Please help me to fix this... Thanks in advance.
You could move all the plot changing code above the plt.show() and then save the figure manually from the pop-up window. The right most icon at the bottom left saves the current figure as is currently displayed
Even better you could use plt.axis([xStart, xFinish, yBottom, yTop]) or ax.set_xlim(), ax.set_ylim

Categories