如何使用 x 和 y 坐标绘制二维数据(图像)

How to plot 2D data (image) with x and y coordinates

我想使用 pyqtgraph 绘制一个二维光谱,其中 x 坐标是光谱维度(波长),y 坐标是空间维度(以天空的角秒为单位)。

我已经能够使用 ImageItem() 执行此操作,但我似乎无法弄清楚如何在正确的坐标中显示 x 轴和 y 轴。 我不想只更改标签或刻度,而是更改绘图的坐标,因为我稍后需要使用这些值(波长和弧秒)执行操作。

这是一个最小的工作示例:

import pyqtgraph as pg
import numpy as np


# The fake data
wvlg = np.linspace(300, 600, 5000)
arcsec = np.linspace(-5, 5, 100)
flux = np.ones((wvlg.shape[0], arcsec.shape[0])) * np.exp(-(arcsec)**2/0.1)
flux += np.random.normal(0, 0.1, size=(wvlg.shape[0], arcsec.shape[0]))

# The plotting
win = pg.GraphicsLayoutWidget(show=True)
ax2D = win.addPlot(title='2D spectrum', row=0, col=0)
img = pg.ImageItem()
img.setImage(flux)
ax2D.addItem(img)
# Some line converting the x and y values to wvlg and arcsec

这给出了一个图像,其中 x 轴和 y 轴显示索引值,而我想显示相应的波长和弧秒值。

是否有一种我在文档中严重忽略的简单方法可以做到这一点?

可以使用ImageItemclass的setRect方法来设置数据的范围。请参阅下面的示例。

请注意,我将图像移动了半个像素,以便像素中心与精确坐标匹配。否则坐标将与像素的角点之一对齐。

import pyqtgraph as pg
import numpy as np

from PyQt5 import QtCore, QtWidgets


def main():
    app = QtWidgets.QApplication([])
    
    # The fake data
    wvlg = np.linspace(300, 600, 5000)
    arcsec = np.linspace(-5, 5, 100)
    flux = np.ones((wvlg.shape[0], arcsec.shape[0])) * np.exp(-(arcsec)**2/0.1)
    flux += np.random.normal(0, 0.1, size=(wvlg.shape[0], arcsec.shape[0]))

    # The plotting
    win = pg.GraphicsLayoutWidget()
    ax2D = win.addPlot(title='2D spectrum', row=0, col=0)
    img = pg.ImageItem()
    img.setImage(flux)
    ax2D.addItem(img)
    
    print(flux.shape)

    # Move the image by half a pixel so that the center of the pixels are
    # located at the coordinate values
    dx = wvlg[1]-wvlg[0]
    dy = arcsec[1]-arcsec[0]
    print("pixel size x: {}, pixel size y: {}".format(dx, dy))
    
    rect = QtCore.QRectF(wvlg[0] - dx/2, arcsec[0] - dy/2, 
                         wvlg[-1] - wvlg[0], arcsec[-1] - arcsec[0])
    print(rect)
    img.setRect(rect)

    ax2D.setLabels(left='arcsec', bottom='wvlg')
    
    win.show()
    win.raise_()
    app.exec_()
    
if __name__ == "__main__":
    main()