我有一种感觉,我在这里遗漏了一些明显的东西,但我在互联网上没有找到任何有用的东西。
我有一个使用 pyqtgraph 显示信号的应用程序。该信号有 1000 个样本,代表 0 - 0.5 范围内的值。 使用正确的 X 轴值绘制它很简单 - 我只是制作一个具有正确范围和元素数量的
linspace
并将其用作 x
中的 plot
。
但是如何对
ImageItem
内的 PlotWidget
执行相同操作呢?它使用元素数量作为 X 轴,但我无法弄清楚如何告诉它使用正确的值。
看一下屏幕截图 - 我需要对图像使用与下图相同的 X 轴值。
相关代码:
首先,我创建我的 X 值:
self.xval_h = numpy.linspace(0, 0.5, len(self.spectrum_h[-1]))
self.xval_v = numpy.linspace(0, 0.5, len(self.spectrum_v[-1]))
更新绘图和图像:
def update_spectrum(self):
self.HSpectrum.plot(self.xval_h, self.spectrum_h[-1], clear=True)
self.VSpectrum.plot(self.xval_v, self.spectrum_v[-1], clear=True)
def update_trace(self):
self.image_h.setImage(numpy.array(self.spectrum_h).T)
self.image_v.setImage(numpy.array(self.spectrum_v).T)
所以,问题归结为我如何将我的
xval
与ImageItem
(或包含PlotWidget
的ImageItem
)一起使用?
非常感谢您的帮助!
您可以使用“setRect”定义图像的坐标并传递“QRectF(x,y,width,height)”(如果pg.setConfigOptions(imageAxisOrder="row,则x,y为左上角或左下角) -主要”)已启用):
image_width = abs(self.xval_h[0]-self.xval_h[0])
image_height = abs(self.xval_h[0]-self.xval_h[0]) # if x and y-scales are the same
pixel_size = image_width/(self.xval_h.size-1)
self.image_h.setRect(QRectF(self.xval_h[0]-pixel_size/2, self.xval_h[0]-pixel_size/2, image_width, image_height))
这是一个具体的、最小的可重现示例,说明如何使用
setRect
调整 PyQtGraph ImageItem
上的 X 轴范围。这是取自我正在开发的信号处理应用程序的片段,因此存在值/常量。人们应该能够通过不同值的反复试验将代码推断到其他上下文。
示例,前后展示效果:
示例代码片段
import numpy as np
import pyqtgraph as pg
from PySide6.QtGui import QTransform
from PySide6.QtWidgets import QApplication
FFT_MAX_BIN_FREQ = 24000
CHUNKS_TO_DISP = 187
NUM_FFT_FREQ_BINS = 257
SAMPLE_FREQ = 48000
HALF_SAMPLE_FREQ = 24000
CHUNK_SIZE = 512
class SpectrogramWidget(pg.PlotWidget):
def __init__(self):
super().__init__()
self.img = pg.ImageItem() # Create image item
self.addItem(self.img) # Add image item to PlotWidget's ViewBox
self.setTitle("Sound Pressure Spectrogram") # Set title
self.setLabel("bottom", "Time", units="s") # Set x-axis label
self.setLabel("left", "Frequency", units="Hz") # Set y-axis label
self.setYRange(0, FFT_MAX_BIN_FREQ) # Set y-axis range
self.img_array = np.zeros( # Initialise image array
(CHUNKS_TO_DISP, NUM_FFT_FREQ_BINS),
dtype=np.float32,
)
# Setup false colouring of monochrome image using colour map and corresponding LUT
cm = pg.colormap.get("CET-D1A")
lut = cm.getLookupTable(nPts=256)
self.black_white_lvls = [-50, 50] # Define black white levels for use with LUT
self.img.setLookupTable(lut) # Set LUT for false colouring of monochrome image
self.img.setLevels(self.black_white_lvls) # Set levels for use with LUT
# Calculate scales for transformation matrix to scale image
# e.g. (horizontally, vertically) (0.010666, 93.385214)
self.yscale = 1 / (NUM_FFT_FREQ_BINS / HALF_SAMPLE_FREQ)
self.xscale = (1 / SAMPLE_FREQ) * CHUNK_SIZE
transform = QTransform.fromScale(self.xscale, self.yscale)
self.img.setTransform(transform)
# Set data the data to be displayed
self.img.setImage(self.img_array, autoLevels=False)
# ****
# This is where the magic happens
# Shift the ViewBox to display X-axis range from -CHUNKS_TO_DISP*self.xscale to 0
self.img.setRect(
-CHUNKS_TO_DISP * self.xscale,
0,
CHUNKS_TO_DISP * self.xscale,
NUM_FFT_FREQ_BINS * self.yscale,
)
if __name__ == "__main__":
app = QApplication([])
i = SpectrogramWidget()
i.show()
app.exec()