Re peated calls to Specgram for animation, memory leaking

Hello,

First thanks for the great library, recently came across it and seems quite
useful for what i'm doing.

What i'm trying to do is create an animated specgram(). I'm feeding in
audio data from a microphone at the moment, although the ultimate use is to
chart data that will be input via the line in audio port from an FMCW radar
front end for basic visualization.

I've attached simplified code below based from one of your animation
examples that shows my problem. Initially i get fine performance given the
timeout i've set. After about a second or two, performance goes down hill
and progressively gets worse and memory use continues to grow as if each
call to specgram creates a new instance in memory or worse is drawing a new
instance over the old. Is there another way to call specgram to avoid this?
It seems the other plot types generally give the ability to update the data
for an already created graph, i haven't seen a way to do this with specgram,
perhaps this is what i'm missing? Ultimately i would like to get the graph
image out of specgram and append them properly to get a smoother scrolling
effect but i need to get the data out of specgram fast enough first.

thanks in advance for any pointers.

import gobject
import numpy as np
import matplotlib
import array
matplotlib.use('GTKAgg')

import matplotlib.pyplot as plt
import ossaudiodev as oss

audio = oss.open('/dev/dsp','r')

print audio.setfmt(oss.AFMT_S16_LE)
print audio.channels(1)
print audio.speed(44100)

fig = plt.figure()
ax = fig.add_subplot(111)
data = array.array('H',audio.read(5880))
img = ax.specgram(data, NFFT=1024,Fs=44100, Fc=0,noverlap=64)

def update():
    data = array.array('H',audio.read(5880))
    img = plt.specgram(data, NFFT=1024,Fs=44100, Fc=0,noverlap=64)
    fig.canvas.draw_idle()
    return True

gobject.timeout_add(100, update)
plt.show()

···

--
View this message in context: http://www.nabble.com/Repeated-calls-to-Specgram-for-animation%2C-memory-leaking-tp24814391p24814391.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

Images added to an axes get added to the axes' "images" member, so you can simply remove it from there.

I've attached a modified version of your script that does this. It uses a global variable which is probably not best practice, but it should be enough to give you the idea.

Cheers,
Mike

xianthax wrote:

repeat_specgram.py (746 Bytes)

···

Hello,

First thanks for the great library, recently came across it and seems quite
useful for what i'm doing.

What i'm trying to do is create an animated specgram(). I'm feeding in
audio data from a microphone at the moment, although the ultimate use is to
chart data that will be input via the line in audio port from an FMCW radar
front end for basic visualization.

I've attached simplified code below based from one of your animation
examples that shows my problem. Initially i get fine performance given the
timeout i've set. After about a second or two, performance goes down hill
and progressively gets worse and memory use continues to grow as if each
call to specgram creates a new instance in memory or worse is drawing a new
instance over the old. Is there another way to call specgram to avoid this? It seems the other plot types generally give the ability to update the data
for an already created graph, i haven't seen a way to do this with specgram,
perhaps this is what i'm missing? Ultimately i would like to get the graph
image out of specgram and append them properly to get a smoother scrolling
effect but i need to get the data out of specgram fast enough first.

thanks in advance for any pointers.

import gobject
import numpy as np
import matplotlib
import array
matplotlib.use('GTKAgg')

import matplotlib.pyplot as plt
import ossaudiodev as oss

audio = oss.open('/dev/dsp','r')

print audio.setfmt(oss.AFMT_S16_LE)
print audio.channels(1)
print audio.speed(44100)

fig = plt.figure()
ax = fig.add_subplot(111)
data = array.array('H',audio.read(5880))
img = ax.specgram(data, NFFT=1024,Fs=44100, Fc=0,noverlap=64)

def update():
    data = array.array('H',audio.read(5880))
    img = plt.specgram(data, NFFT=1024,Fs=44100, Fc=0,noverlap=64) fig.canvas.draw_idle()
    return True

gobject.timeout_add(100, update) plt.show()

--
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA

It may be more efficient to call im.set_array(newdata) rather than
creating a new image each time. Eg

http://matplotlib.sourceforge.net/examples/animation/dynamic_image_gtkagg.html

JDH

···

On Wed, Aug 5, 2009 at 8:08 AM, Michael Droettboom<mdroe@...86...> wrote:

Images added to an axes get added to the axes' "images" member, so you can
simply remove it from there.

It should be noted, though, that in that case, newdata should be new specgram data, not the original data. matplotlib.mlab has a specgram() function that performs the actual computation performed for the pyplot plotting function of the same name.

Ryan

···

On Wed, Aug 5, 2009 at 8:23 AM, John Hunter <jdh2358@…287…> wrote:

On Wed, Aug 5, 2009 at 8:08 AM, Michael Droettboom<mdroe@…86…> wrote:

Images added to an axes get added to the axes’ “images” member, so you can

simply remove it from there.

It may be more efficient to call im.set_array(newdata) rather than

creating a new image each time. Eg

http://matplotlib.sourceforge.net/examples/animation/dynamic_image_gtkagg.html


Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma
Sent from Norman, Oklahoma, United States