Issue 1:
Bug report

When plotting and saving a lot of spectrograms in a loop, there seems to be a memory leek. I'm aware that this is some kind of a common problem and I tried already all kind of combinations of plotting the figure new every step, reusing the figure, using plt.close(), plt.close('fig'), gc.collect(), plt.clf(), plt.cla(), but nothing really worked.

Interestingly, I could pinpoint that the leak does not appear or at least gets negligible when the yscale is not 'log'. Can someone give me a work around or has an idea how to set the axis to log without suffering the memory leak?

Code for reproduction

import gc
import psutil
import os
import matplotlib.pyplot as plt
import numpy as np

process = psutil.Process(os.getpid())
# initial memory usage
bytes_used_start = process.memory_info().rss

# generate 10 min data
fs = 20000
x = np.random.rand(fs*600)

for i in range(10):

# create figure
fig = plt.figure(figsize=(10,6))
ax = fig.add_axes([0, 0, 1, 1])

# plot spectrogram
spectro, freqs, t, im = ax.specgram(
x=x,
NFFT=2**13,
Fs=fs
)

ax.axes.set_ylim((9.8,10000))
#ax.axes.set_yscale('log') # -> comment this line in for memory leak

fig.savefig('C:/Temp/spectro_{}.jpg'.format(i))

# clean up
plt.close(fig)
gc.collect()

# show memory usage
bytes_used_cur = process.memory_info().rss - bytes_used_start
print('bytes used currently at step {} : {}'.format(i, bytes_used_cur))

Outcome yscale linear

bytes used currently at step 0 : 256192512
bytes used currently at step 1 : 257204224
bytes used currently at step 2 : 257437696
bytes used currently at step 3 : 257343488
bytes used currently at step 4 : 257519616
bytes used currently at step 5 : 257581056
bytes used currently at step 6 : 257515520
bytes used currently at step 7 : 257581056
bytes used currently at step 8 : 257449984
bytes used currently at step 9 : 257585152

Outcome yscale log

bytes used currently at step 0 : 42557440
bytes used currently at step 1 : 83501056
bytes used currently at step 2 : 122126336
bytes used currently at step 3 : 161177600
bytes used currently at step 4 : 199602176
bytes used currently at step 5 : 238022656
bytes used currently at step 6 : 276516864
bytes used currently at step 7 : 314994688
bytes used currently at step 8 : 353480704
bytes used currently at step 9 : 391954432

Matplotlib version

Operating system: Windows 7

Matplotlib version: '3.1.3'

Matplotlib backend: Qt5Agg

Python version: 3.7.4

Issue 2:
matplotlib seems to leak memory when I switch to log scale on the Y axis, for the functions pcolorfast, pcolormesh, imshow and specgram

Please consider the following spectrogram animation (sorry for the extra dependencies to scipy)

from scipy.signal.spectral import spectrogram
from scipy.signal.waveforms import chirp

import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np

fs = 8000 # sampling rate
t = np.arange(0, 5.0, 1/fs) # 5 seconds of time

fig, axes = plt.subplots(nrows=1)

def signal(t): # generates a "chirp" signal
return chirp(t = t, f0 = 100.0, f1 = 3000.0, t1 = 10.0)

def spect(x): # computes spectrogram
freq, time, Sxx = spectrogram(x, fs = fs, nfft = 1024, noverlap = 512, nperseg = 1024)
Z = 10 * np.log10(Sxx)
return freq, time, Z

y = signal(t)
freq, time, Z = spect(y)
im = axes.pcolorfast(time, freq, Z)
axes.set_xlabel('t [s]')
axes.set_ylabel('f [Hz]')
axes.set_yscale('log') # <-- exposes the leak
axes.set_ylim(0, fs/2)

def animate(i):
y = signal(t + i/30.0) # sliding temporal window
freq, time, Z = spect(y)
im.set_data(Z)
return [ im ]

ani = animation.FuncAnimation(fig, animate, np.arange(1, 200),
interval=0, blit=True)
plt.show()

Everything stays stable if I stick to linear scale on the Y axis, commenting out the line

axes.set_yscale('log')

I can reproduce it with matplotlib 3.1.1 (via pip) and previous versions (tested with 3.0.2 from system-wide Debian testing package). Also I am using Qt5Agg backend and python 3.7.5rc1