How to plot an image with non-linear y-axis with Matplotlib using imshow?

前端 未结 4 815
猫巷女王i
猫巷女王i 2020-12-09 19:58

How can I plot an 2D array as an image with Matplotlib having the y scale relative to the power of two of the y value?

For instance the first row of my array will ha

4条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-09 20:47

    The best way I've found to make a scalogram using matplotlib is to use imshow, similar to the implementation of specgram. Using rectangles is slow, because you're having to make a separate glyph for each value. Similarly, you don't want to have to bake things into a uniform NumPy array, because you'll probably run out of memory fast, since your highest level is going to be about as long as half your signal.

    Here's an example using SciPy and PyWavelets:

    from pylab import *
    import pywt
    import scipy.io.wavfile as wavfile
    
    # Find the highest power of two less than or equal to the input.
    def lepow2(x):
        return 2 ** floor(log2(x))
    
    # Make a scalogram given an MRA tree.
    def scalogram(data):
        bottom = 0
    
        vmin = min(map(lambda x: min(abs(x)), data))
        vmax = max(map(lambda x: max(abs(x)), data))
    
        gca().set_autoscale_on(False)
    
        for row in range(0, len(data)):
            scale = 2.0 ** (row - len(data))
    
            imshow(
                array([abs(data[row])]),
                interpolation = 'nearest',
                vmin = vmin,
                vmax = vmax,
                extent = [0, 1, bottom, bottom + scale])
    
            bottom += scale
    
    # Load the signal, take the first channel, limit length to a power of 2 for simplicity.
    rate, signal = wavfile.read('kitten.wav')
    signal = signal[0:lepow2(len(signal)),0]
    tree = pywt.wavedec(signal, 'db5')
    
    # Plotting.
    gray()
    scalogram(tree)
    show()
    

    You may also want to scale values adaptively per-level.

    This works pretty well for me. The only problem I have is that matplotlib creates a hairline-thin space between levels. I'm still looking for a way to fix this.

    P.S. - Even though this question is pretty old now, I figured I'd respond here, because this page came up on Google when I was looking for a method of creating scalograms using MPL.

提交回复
热议问题