Как построить 2D-данные (изображение) с координатами x и y

#python #pyqt5 #pyqtgraph

#python #pyqt5 #pyqtgraph

Вопрос:

Я хотел бы построить 2D-спектр, где координата x — это спектральное измерение (длина волны), а координата y — это пространственное измерение (в угловых секундах неба), используя pyqtgraph.

Я смог сделать это с помощью 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 показывают значение индекса, тогда как я хотел бы показать соответствующие значения длины волны и угловой секунды.

2D-спектр, нанесенный на график, но без координат по осям x и y

Есть ли простой способ сделать это, который я просто грубо упустил из виду в документации?

Ответ №1:

Вы можете использовать setRect метод ImageItem класса для установки объема данных. Смотрите мой пример ниже.

Обратите внимание, что я переместил изображение на половину пикселя, чтобы центры пикселей соответствовали точным координатам. В противном случае координаты будут совпадать с одной из угловых точек пикселя.

 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()