ImageItem with log scale on y-axis...

142 views
Skip to first unread message

jweb...@gmail.com

unread,
Jan 23, 2023, 2:14:34 PM1/23/23
to pyqtgraph
(pyqtgraph vers 0.13.1) 

I have an application that generates a spectrogram.  I use scipys spectrogram method, and generate the plot with...

my_plotitem = pg.PlotItem()

f, t, Sxx = scipy.signal.spectrogram( data, Fs=fs)
my_transform = QtGui.QTransform()
yscale = f[-1]/Sxx.shape[1]
xscale = t[-1]/Sxx.shape[0]
my_transform.scale(xscale, yscale)

my_image = pg.ImageItem()
my_image.setTransform(my_transform)

my_image.setImage(Sxx)
my_plotitem.addItem(my_image)

my_plotitem.setLogMode(x=False, y=True)

This works great, but I would like to have the y-axis (the frequencies) to be a log scale.  I tried using the plotitems setLogMode method... but it just changes the tick labels (incorrectly) and doesn't change the plot at all.  the image on the left is with a linear y-axis, the one on the right is after setting same image to setLogMode(x=False, y=True).  Note that the correct range for the y-axis is 0 to 50.

linear.pnglog.png

I've searched around and can't find anything. What is the correct way to do this?

J

Patrick

unread,
Jan 23, 2023, 9:16:53 PM1/23/23
to pyqtgraph
Hi,

I might be wrong, but I don't think ImageItems work with logarithmic axes. They are simple a bitmap image that gets drawn over a rectangular area, and the QTransform (https://doc.qt.io/qtforpython/PySide6/QtGui/QTransform.html) which is applied is a simple affine transform that won't apply logarithmic stretching.
Perhaps you could try rendering with a PColorMeshItem (https://pyqtgraph.readthedocs.io/en/latest/api_reference/graphicsItems/pcolormeshitem.html) instead? It might be a little more complex and slower to render, but since it renders as a series of polygons, I think it may respect the logarithmic coordinates.

Patrick

jim.v...@gmail.com

unread,
Jan 24, 2023, 8:20:49 AM1/24/23
to pyqtgraph
I just had a quick look at the PColorMeshItem, and I don't think it deals with nonlinear transforms either.

jim.v...@gmail.com

unread,
Jan 24, 2023, 8:22:21 AM1/24/23
to pyqtgraph
Sorry, meant to say I had a look at the PColorMeshItem *source code*...

Ognyan Moore

unread,
Jan 24, 2023, 10:38:49 AM1/24/23
to pyqt...@googlegroups.com
Only PlotCurveItem and ScatterPlotItem (maybe a few other GraphicsItems) support stretching/repositioning for log mode.  None of the suggestions here will support stretching out image-like data. In all cases you will need to compute the respective coordinates in log-space yourself.  

PColorMeahItem and NonUniformImage will effectively do the same thing in this case, but with different kinds of input arguments. Easiest would likely be to rescale the spectrogram in log-space, but you will no doubt lose resolution in higher frequencies.  The other solutions will likely work better if you want to be able to zoom in/out and don’t want to lose the detail/resolution from the spectrogram calculation (but more complicated to implement).

--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/779632c0-591a-4ce2-96ee-1f003c1ffc69n%40googlegroups.com.

jweb...@gmail.com

unread,
Jan 24, 2023, 8:01:35 PM1/24/23
to pyqtgraph
Thanks everyone

This is surprisingly difficult.   I played around with matplotlib's pcolormesh, and it does work with log scales, but of course it's slow.

I'll have to think about how to "rescale the spectrogram in log-space", seems like the best solution, but it's not immediately obvious to me how to do that.

jim.v...@gmail.com

unread,
Jan 25, 2023, 8:01:19 AM1/25/23
to pyqtgraph
It would be fairly easy using a vertex shader in vispy...but I don't know if they've made any progress in integrating that with QUI toolkits...

-Jim

jim.v...@gmail.com

unread,
Jan 25, 2023, 8:07:24 AM1/25/23
to pyqtgraph
I should have asked--is this a real-time application, i.e. how fast does the display need to be? If it's a one-and-done, then you can just re-map the image...though if your algorithm is outputting spectral density in linear space, are you sure you should be plotting it on a log axis?

Ognyan Moore

unread,
Jan 25, 2023, 11:04:06 AM1/25/23
to pyqt...@googlegroups.com
Vispy may indeed have some relevant offerings and is likely worth examining; there are other consequences of using it, but it may fit the bill nicely here.

J, if you can provide a representative matrix of the spectrogram and associated frequencies, I may be able to try and tinker with rescaling and send the code back (no promises!).

Ogi

Reply all
Reply to author
Forward
Message has been deleted
0 new messages