I'm using PySide. Inside a QMainWindow
, I have an ImageItem
displayed inside a PlotWidget
.
Suppose I have a function generateImage(r, np)
that can dynamically generate an image. The function returns a np
x np
array of pixels, for the image located inside the (-r, -r)-(r, r)
square (in real coordinates). I want the axis to display the real coordinates, not the pixel coordinates.
- If I zoom in / zoom out, I'd like to generate the same number of pixels, but within a smaller / larger square (in real coordinates);
- If I translate the image, I need to generate an image with a larger square and with a larger number of pixels, to display the region of interrest using the same resolution;
- If I resize the window, I need to generate a different number of pixels, to keep the resolution of the displayed image the same.
The code I have actually looks like this:
graph = PlotWidget()
image = ImageItem()
graph.addItem(image)
graph.setAspectLocked(True) # to keep the pixels square
r = 10e-6 # 10 µm
np = 101 # but should be related to number of pixels in the window
image.setImage(generateImage(r, np))
image.setRect(QRectF(-r, -r, 2*r, 2*r))
My guess is to use the sigRangeChanged
signal to detect a change in the view. However, I'm not sure how to detect the size and the resolution of the window, and how to correctly update the image.
I naively tried to do something like this:
graph.sigRangeChanged.connect(updateRange)
def updateRange(view, rng):
r = max(abs(rng[0][0]), abs(rng[0][1]),
abs(rng[1][0]), abs(rng[1][1]))
image.setImage(generateImage(r, np))
image.setRect(QRectF(-r, -r, 2*r, 2*r))
However, it does not work because the range returned by the signal is slightly larger than r
itself. Therefore, I see the image becoming smaller and smaller...
- How can I determine the number of pixels I need to fill the window?
- How can I determine the size of the image I need to generate (in real coordinates)
- How can I update what is displayed without recursively updating the image range?
- How can I display only a part of the generated image? Do I need to slice the array before giving it to
setImage()
, or can I give the entire array and let pyqtgraph display only the region I need? - More generally, what is the relation between the coordinates of the different elements and transformations (
graph.viewRect()
,image.viewRect()
,image.boundingRect()
,image.sceneBoundingRect()
, ...)