2

I am trying to display an RGB numpy array in an ImageView() (or similar) within a Dock in pyqtgraph.

The general idea is something like this code:

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np

from pyqtgraph.dockarea import Dock, DockArea

class SimDock(Dock):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        #self.im1 = pg.image()
        self.im1 = pg.ImageView()

        self.im1.setImage(np.random.normal(size=(100, 100, 3)))
        self.addWidget(self.im1, row=0, col=0)

        self.im1.ui.histogram.hide()
        self.im1.ui.menuBtn.hide()
        self.im1.ui.roiBtn.hide()


app = QtGui.QApplication([])
win = QtGui.QMainWindow()
area = DockArea()
win.setCentralWidget(area)
win.resize(1500, 800)
win.setWindowTitle('pyqtgraph example: dockarea')

simdock = SimDock("Similar Images", size=(500, 500))
area.addDock(simdock, 'right')

win.show()

# Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        app.instance().exec_()

However, when I run the one above I get:

ValueError: could not broadcast input array from shape (100,100,3) into shape (100,100)

When I switch the self.im1 to be pg.image instead of pg.ImageView then an RGB image displays in the Dock, but I get a second empty window (which I assume comes from the pg.image()).

Based on this question, ImageView can accept (M, N, 3) RGB data, but I can't seem to get it to display an RGB image in a widget without the second window popping up.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
brechmos
  • 1,278
  • 1
  • 11
  • 22
  • Use `self.im1.setImage(np.random.normal(size=(100, 100, 3)).T)` – eyllanesc Jun 06 '18 at 21:44
  • That isn't what I am looking for... if you do a `.T` on a 3D image of that size it will give you an image of size (3, 100, 100) which is then interpreted as an image over time. (a slider is then shown on the bottom and the image is still gray scale) – brechmos Jun 07 '18 at 16:43

1 Answers1

2

Well, I found one way of doing it that seems reasonable. There is a post that suggests to subclass pg.ImageView in order to auto add a lookup table for the color. So, in the end I have:

class ColorImageView(pg.ImageView):
    """
    Wrapper around the ImageView to create a color lookup
    table automatically as there seem to be issues with displaying
    color images through pg.ImageView.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.lut = None

    def updateImage(self, autoHistogramRange=True):
        super().updateImage(autoHistogramRange)
        self.getImageItem().setLookupTable(self.lut)

then the call in my code becomes self.im1 = ColorImageView().

This works for me and seems reasonably simple.

brechmos
  • 1,278
  • 1
  • 11
  • 22
  • Very nice solution, I spent hours trying to figure this out and ended up just displaying a grayscale image by taking only one channel, but this fixed it for me immediately. Thanks! – adamconkey Jan 24 '20 at 00:37