Is there an easy way to plot a log-frequency spectrogram?

Hi all!

I have a quick newbie question.
matplotlib’s specgram() by default plots a spectrogram with a linear y-axis (frequency).
However, for many applications, it’s better to look at a log-frequency spectrogram.

Is there an easy way to plot a spectrogram using a logarithmic frequency axis?

Thanks for your help!

–David Ho

Just as an illustration, I’m looking for a nice way to plot something like this:
http://labrosa.ee.columbia.edu/matlab/sgram/

I don’t necessarily need a weighting matrix to convert the Pxx array,
which is what Dan Ellis’ code does; I just need to visualize the
spectrogram on a logarithmic axis.

Is there any built-in way to do this?

I’d just like to be able to call specgram(), and then call something like yscale(‘log’, basey=10), to change the y-axis to be logarithmic, stretching or compressing different areas of the image appropriately. The equivalent code would work in MATLAB. However, this doesn’t seem to work with matplotlib (I just get an empty figure).

Similarly, I couldn’t get matplotlib.pyplot.semilogy() to work; I get the warning: “Images are not supported on non-linear axes.”

Does anyone have any ideas?
Thanks!

–David Ho

···

On Thu, Apr 15, 2010 at 12:27 PM, David Ho <itsdho@…2722…> wrote:

Hi all!

I have a quick newbie question.
matplotlib’s specgram() by default plots a spectrogram with a linear y-axis (frequency).
However, for many applications, it’s better to look at a log-frequency spectrogram.

Is there an easy way to plot a spectrogram using a logarithmic frequency axis?

Thanks for your help!

–David Ho

David Ho wrote:

Just as an illustration, I'm looking for a nice way to plot something like this:
http://labrosa.ee.columbia.edu/matlab/sgram/

I don't necessarily need a weighting matrix to convert the Pxx array, which is what Dan Ellis' code does; I just need to visualize the spectrogram on a logarithmic axis.

Is there any built-in way to do this?

David,

The components exist, but they have not been assembled. One approach would be to use the NonUniformImage class in place of image to handle the log axis case. A variation would be to use pcolorfast. Evidently we need to add a log scale option to the existing specgram. I can't do it right now--maybe someone else will.

Eric

···

I'd just like to be able to call specgram(), and then call something like yscale('log', basey=10), to change the y-axis to be logarithmic, stretching or compressing different areas of the image appropriately. The equivalent code would work in MATLAB. However, this doesn't seem to work with matplotlib (I just get an empty figure).
Similarly, I couldn't get matplotlib.pyplot.semilogy() to work; I get the warning: "Images are not supported on non-linear axes."

Does anyone have any ideas?
Thanks!

--David Ho

On Thu, Apr 15, 2010 at 12:27 PM, David Ho <itsdho@…2722… > <mailto:itsdho@…2722…>> wrote:

    Hi all!

    I have a quick newbie question.
    matplotlib's specgram() by default plots a spectrogram with a linear
    y-axis (frequency).
    However, for many applications, it's better to look at a
    log-frequency spectrogram.

    Is there an easy way to plot a spectrogram using a logarithmic
    frequency axis?

    Thanks for your help!

    --David Ho

2010/4/19 Eric Firing <efiring@...202...>:

David Ho wrote:

Just as an illustration, I'm looking for a nice way to plot something
like this:
http://labrosa.ee.columbia.edu/matlab/sgram/

I don't necessarily need a weighting matrix to convert the Pxx array,
which is what Dan Ellis' code does; I just need to visualize the
spectrogram on a logarithmic axis.

Is there any built-in way to do this?

David,

The components exist, but they have not been assembled. One approach
would be to use the NonUniformImage class in place of image to handle
the log axis case. A variation would be to use pcolorfast. Evidently
we need to add a log scale option to the existing specgram. I can't do
it right now--maybe someone else will.

Eric

Hello David,

You asked for a builtin solution, and I think this question has been
answered by Eric, but maybe you want also a more elaborate solution.

As a workaround, do you think you can do the spectrogram
transformation on your own using the functions matplotlib uses to
generate the data, and use pcolor() to plot it with a logarithmic
mesh?

Friedrich

Friedrich Romstedt wrote:

2010/4/19 Eric Firing <efiring@...202...>:

David Ho wrote:

Just as an illustration, I'm looking for a nice way to plot something
like this:
http://labrosa.ee.columbia.edu/matlab/sgram/

I don't necessarily need a weighting matrix to convert the Pxx array,
which is what Dan Ellis' code does; I just need to visualize the
spectrogram on a logarithmic axis.

Is there any built-in way to do this?

David,

The components exist, but they have not been assembled. One approach
would be to use the NonUniformImage class in place of image to handle
the log axis case. A variation would be to use pcolorfast. Evidently
we need to add a log scale option to the existing specgram. I can't do
it right now--maybe someone else will.

Eric

Hello David,

You asked for a builtin solution, and I think this question has been
answered by Eric, but maybe you want also a more elaborate solution.

As a workaround, do you think you can do the spectrogram
transformation on your own using the functions matplotlib uses to
generate the data, and use pcolor() to plot it with a logarithmic
mesh?

Use pcolormesh or Axes.pcolorfast--pcolor will take forever.

Eric

···

Friedrich