Пример #1
0
 def __init__(self, *args, **kwargs):
     super(PyQtGraphImagePlot, self).__init__(*args, **kwargs)
     self.ui.histogram.hide()
     self.ui.roiBtn.hide()
     self.ui.normBtn.hide()
     self.line1 = InfiniteLine(pos=0, angle=0, movable=False)
     self.line2 = InfiniteLine(pos=0, angle=90, movable=False)
     self.addItem(self.line1)
     self.addItem(self.line2)
Пример #2
0
 def __init__(self):
     super(MyImageView, self).__init__()
     self.ui.histogram.gradient.restoreState(
         {"ticks": [(0.0, (255, 0, 0)), (0.5, (255, 255, 255)), (1.0, (0, 0, 255))], "mode": "rgb"}
     )
     self.h_line = InfiniteLine(pos=0, angle=0)
     self.v_line = InfiniteLine(pos=0, angle=90)
     self.view.addItem(self.h_line)
     self.view.addItem(self.v_line)
     win.time_slider.valueChanged.connect(self.set_time)
Пример #3
0
class PyQtGraphImagePlot(ImageView):
    def __init__(self, *args, **kwargs):
        super(PyQtGraphImagePlot, self).__init__(*args, **kwargs)
        self.ui.histogram.hide()
        self.ui.roiBtn.hide()
        self.ui.normBtn.hide()
        self.line1 = InfiniteLine(pos=0, angle=0, movable=False)
        self.line2 = InfiniteLine(pos=0, angle=90, movable=False)
        self.addItem(self.line1)
        self.addItem(self.line2)

    def plot(self, arr):
        self.setImage(np.array(arr))
        self.line1.setPos(arr.shape[0]/2.)
        self.line2.setPos(arr.shape[1]/2.)
    def update_data(self, x_attr, y_attr, i, j):
        """
        Update graph
        :param x_attr: x attributes
        :param y_attr: y attributes
        :return: None
        """
        OWScatterPlotGraph.update_data(self, x_attr, y_attr)

        x_index, y_index = i, j

        X = self.original_data[x_index]
        Y = self.original_data[y_index]

        valid = self.get_valid_list([x_index, y_index])

        X = X[valid]
        Y = Y[valid]
        x_min, x_max = self.attr_values[x_attr]

        X = numpy.array([numpy.ones_like(X), X]).T
        try:
            beta, _, _, _ = numpy.linalg.lstsq(X, Y)
        except numpy.linalg.LinAlgError:
            beta = [0, 0]

        angle = atan2(beta[1], 1) * 180 / pi
        ti = InfiniteLine((-999, beta[0] + -999 * beta[1]),
                          angle=angle,
                          pen='r')  # TODO FIX
        self.plot_widget.addItem(ti)
        if self.last_line is not None:
            self.plot_widget.removeItem(self.last_line)
        self.last_line = ti
        self.plot_widget.replot()
Пример #5
0
 def draw_regression_line(self, x_data, y_data, min_x, max_x):
     if self.show_reg_line and self.can_draw_regresssion_line():
         slope, intercept, rvalue, _, _ = linregress(x_data, y_data)
         start_y = min_x * slope + intercept
         end_y = max_x * slope + intercept
         angle = np.degrees(np.arctan((end_y - start_y) / (max_x - min_x)))
         rotate = ((angle + 45) % 180) - 45 > 90
         color = QColor("#505050")
         l_opts = dict(
             color=color,
             position=abs(int(rotate) - 0.85),
             rotateAxis=(1, 0),
             movable=True,
         )
         self.reg_line_item = InfiniteLine(
             pos=QPointF(min_x, start_y),
             pen=pg.mkPen(color=color, width=1),
             angle=angle,
             label="r = {:.2f}".format(rvalue),
             labelOpts=l_opts,
         )
         if rotate:
             self.reg_line_item.label.angle = 180
             self.reg_line_item.label.updateTransform()
         self.plot_widget.addItem(self.reg_line_item)
Пример #6
0
class TimePlot(PlotWidget):
    def __init__(self, *args, **kwargs):
        super(TimePlot, self).__init__(*args, **kwargs)
        self.add_line()
        win.time_slider.valueChanged.connect(self.set_time)

    def add_line(self):
        self.time_vline = InfiniteLine(angle=90)
        self.addItem(self.time_vline)

    def plot(self, x, *args, **kwargs):
        self.time_pts = x
        win.time_slider.setMaximum(len(self.time_pts)-1)
        self.plotItem.plot(x, *args, **kwargs)

    def set_time(self, time_idx):
        pos = self.time_pts[time_idx]
        self.time_vline.setPos(pos)
Пример #7
0
class MyImageView(ImageView):
    def __init__(self):
        super(MyImageView, self).__init__()
        self.ui.histogram.gradient.restoreState(
            {"ticks": [(0.0, (255, 0, 0)), (0.5, (255, 255, 255)), (1.0, (0, 0, 255))], "mode": "rgb"}
        )
        self.h_line = InfiniteLine(pos=0, angle=0)
        self.v_line = InfiniteLine(pos=0, angle=90)
        self.view.addItem(self.h_line)
        self.view.addItem(self.v_line)
        win.time_slider.valueChanged.connect(self.set_time)

    def setImage(self, img, **kwargs):
        super(MyImageView, self).setImage(img, **kwargs)
        self.v_line.setPos(img.shape[1]/2.)
        self.h_line.setPos(img.shape[2]/2.)
        max_value = abs(img).max()
        self.setLevels(-max_value, max_value)
        win.time_slider.setMaximum(len(kwargs['xvals'])-1)

    def set_time(self, time_idx):
        self.setCurrentIndex(time_idx)
Пример #8
0
    def test_update_line(self, init_prog):
        prog = init_prog

        IL = InfiniteLine()

        prog.update_line(IL)
Пример #9
0
 def add_line(self):
     self.time_vline = InfiniteLine(angle=90)
     self.addItem(self.time_vline)
Пример #10
0
    def __init__(self,
                 parent=None,
                 name="ImageView",
                 view=None,
                 imageItem=None,
                 *args):
        QtGui.QWidget.__init__(self, parent, *args)
        self.levelMax = 4096
        self.levelMin = 0
        self.name = name
        self.image = None
        self.axes = {}
        self.imageDisp = None
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.scene = self.ui.graphicsView.scene()

        self.ignoreTimeLine = False

        self.wcsAxes = WCSAxes()
        if view is None:
            self.view = self.wcsAxes.plotItem
        else:
            self.view = view
        self.ui.graphicsView.setCentralItem(self.view)
        self.view.setAspectLocked(True)
        self.view.invertY()

        if imageItem is None:
            self.imageItem = ImageItem()
        else:
            self.imageItem = imageItem
        self.view.addItem(self.imageItem)
        self.currentIndex = 0

        self.ui.histogram.setImageItem(self.imageItem)

        self.menu = None

        self._hideSlider()

        self.roiEnabled = False
        self.roi = MultiROI()
        self.roi.setZValue(20)
        self.view.addItem(self.roi)
        self.roi.hide()
        self.normRoi = MultiROI()
        self.normRoi.setPen('y')
        self.normRoi.setZValue(20)
        self.view.addItem(self.normRoi)
        self.normRoi.hide()
        self.roiCurve = self.ui.roiPlot.plot()
        self.timeLine = InfiniteLine(0, movable=True)
        self.timeLine.setPen((255, 255, 0, 200))
        self.timeLine.setZValue(1)
        self.ui.roiPlot.addItem(self.timeLine)
        self.ui.splitter.setSizes([self.height() - 35, 35])
        self.ui.roiPlot.hideAxis('left')

        self.keysPressed = {}
        self.playTimer = QtCore.QTimer()
        self.playRate = 0
        self.lastPlayTime = 0

        self.normRgn = LinearRegionItem()
        self.normRgn.setZValue(0)
        self.ui.roiPlot.addItem(self.normRgn)
        self.normRgn.hide()

        # wrap functions from view box
        for fn in ['addItem', 'removeItem']:
            setattr(self, fn, getattr(self.view, fn))

        # wrap functions from histogram
        for fn in [
                'setHistogramRange', 'autoHistogramRange', 'getLookupTable',
                'getLevels'
        ]:
            setattr(self, fn, getattr(self.ui.histogram, fn))

        self.ui.horizontalSlider.valueChanged.connect(self._sliderValueChanged)
        self.ui.sliderValueSpinBox.valueChanged.connect(self._spinBoxChanged)
        self.timeLine.sigPositionChanged.connect(self.timeLineChanged)
        self.roi.sigRegionChanged.connect(self.roiChanged)

        self.playTimer.timeout.connect(self.timeout)

        self.normProxy = pg.SignalProxy(self.normRgn.sigRegionChanged,
                                        slot=self.updateNorm)
        self.normRoi.sigRegionChangeFinished.connect(self.updateNorm)

        self.ui.roiPlot.registerPlot(self.name + '_ROI')
        self.view.register(self.name)

        self.noRepeatKeys = [
            QtCore.Qt.Key_Right, QtCore.Qt.Key_Left, QtCore.Qt.Key_Up,
            QtCore.Qt.Key_Down, QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown
        ]

        # initialize roi plot to correct shape / visibility
        self.setROIType(None)
Пример #11
0
class AstroImageView(pg.ImageView):
    """
    Extends ImageView class.
     - Replace default HistogramLUTWidget with our AstroHistogramLUTWidget.
     - Replace PlotWidget for roiPlot (defined inside UI class) by
       AstroWaveFormPlotWidget
     - Delete roiBtn
    """
    def __init__(self,
                 parent=None,
                 name="ImageView",
                 view=None,
                 imageItem=None,
                 *args):
        QtGui.QWidget.__init__(self, parent, *args)
        self.levelMax = 4096
        self.levelMin = 0
        self.name = name
        self.image = None
        self.axes = {}
        self.imageDisp = None
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.scene = self.ui.graphicsView.scene()

        self.ignoreTimeLine = False

        self.wcsAxes = WCSAxes()
        if view is None:
            self.view = self.wcsAxes.plotItem
        else:
            self.view = view
        self.ui.graphicsView.setCentralItem(self.view)
        self.view.setAspectLocked(True)
        self.view.invertY()

        if imageItem is None:
            self.imageItem = ImageItem()
        else:
            self.imageItem = imageItem
        self.view.addItem(self.imageItem)
        self.currentIndex = 0

        self.ui.histogram.setImageItem(self.imageItem)

        self.menu = None

        self._hideSlider()

        self.roiEnabled = False
        self.roi = MultiROI()
        self.roi.setZValue(20)
        self.view.addItem(self.roi)
        self.roi.hide()
        self.normRoi = MultiROI()
        self.normRoi.setPen('y')
        self.normRoi.setZValue(20)
        self.view.addItem(self.normRoi)
        self.normRoi.hide()
        self.roiCurve = self.ui.roiPlot.plot()
        self.timeLine = InfiniteLine(0, movable=True)
        self.timeLine.setPen((255, 255, 0, 200))
        self.timeLine.setZValue(1)
        self.ui.roiPlot.addItem(self.timeLine)
        self.ui.splitter.setSizes([self.height() - 35, 35])
        self.ui.roiPlot.hideAxis('left')

        self.keysPressed = {}
        self.playTimer = QtCore.QTimer()
        self.playRate = 0
        self.lastPlayTime = 0

        self.normRgn = LinearRegionItem()
        self.normRgn.setZValue(0)
        self.ui.roiPlot.addItem(self.normRgn)
        self.normRgn.hide()

        # wrap functions from view box
        for fn in ['addItem', 'removeItem']:
            setattr(self, fn, getattr(self.view, fn))

        # wrap functions from histogram
        for fn in [
                'setHistogramRange', 'autoHistogramRange', 'getLookupTable',
                'getLevels'
        ]:
            setattr(self, fn, getattr(self.ui.histogram, fn))

        self.ui.horizontalSlider.valueChanged.connect(self._sliderValueChanged)
        self.ui.sliderValueSpinBox.valueChanged.connect(self._spinBoxChanged)
        self.timeLine.sigPositionChanged.connect(self.timeLineChanged)
        self.roi.sigRegionChanged.connect(self.roiChanged)

        self.playTimer.timeout.connect(self.timeout)

        self.normProxy = pg.SignalProxy(self.normRgn.sigRegionChanged,
                                        slot=self.updateNorm)
        self.normRoi.sigRegionChangeFinished.connect(self.updateNorm)

        self.ui.roiPlot.registerPlot(self.name + '_ROI')
        self.view.register(self.name)

        self.noRepeatKeys = [
            QtCore.Qt.Key_Right, QtCore.Qt.Key_Left, QtCore.Qt.Key_Up,
            QtCore.Qt.Key_Down, QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown
        ]

        # initialize roi plot to correct shape / visibility
        self.setROIType(None)

    def set_fits_file(self, fitsFile):
        self.wcsAxes.setFitsFile(fitsFile)
        flux = fitsFile.flux()
        wave = fitsFile.wave()
        self.setImage(flux, xvals=wave)
        self.ui.roiPlot.setFitsFile(fitsFile)
        # TODO: Autorange the image after it is drawn.
        # This is a work around for what seems to be a bug in the
        # *pg.ArrowItem*: When arrows are shown in the canvas, the default
        # range of the axis becomes larger. Arrows are included from *WCSAxis*.
        timer = threading.Timer(0.1, lambda: self.view.vb.menu.autoRange())
        timer.start()

    def setImage(self,
                 img,
                 autoRange=True,
                 autoLevels=True,
                 levels=None,
                 axes=None,
                 xvals=None,
                 pos=None,
                 scale=None,
                 transform=None,
                 autoHistogramRange=True):
        """
        Reimplement setImage without using roiBtn
        """
        if hasattr(img, 'implements') and img.implements('MetaArray'):
            img = img.asarray()

        if not isinstance(img, np.ndarray):
            required = ['dtype', 'max', 'min', 'ndim', 'shape', 'size']
            if not all([hasattr(img, attr) for attr in required]):
                raise TypeError("Image must be NumPy array or any object "
                                "that provides compatible attributes/methods:"
                                "\n  %s" % str(required))

        self.image = img
        self.imageDisp = None

        if axes is None:
            if self.imageItem.axisOrder == 'col-major':
                x, y = (0, 1)
            else:
                x, y = (1, 0)

            if img.ndim == 2:
                self.axes = {'t': None, 'x': x, 'y': y, 'c': None}
            elif img.ndim == 3:
                # Ambiguous case; make a guess
                if img.shape[2] <= 4:
                    self.axes = {'t': None, 'x': x, 'y': y, 'c': 2}
                else:
                    self.axes = {'t': 0, 'x': x + 1, 'y': y + 1, 'c': None}
            elif img.ndim == 4:
                # Even more ambiguous; just assume the default
                self.axes = {'t': 0, 'x': x + 1, 'y': y + 1, 'c': 3}
            else:
                raise Exception("Can not interpret image with dimensions %s" %
                                str(img.shape))
        elif isinstance(axes, dict):
            self.axes = axes.copy()
        elif isinstance(axes, list) or isinstance(axes, tuple):
            self.axes = {}
            for i in range(len(axes)):
                self.axes[axes[i]] = i
        else:
            raise Exception("Can not interpret axis specification %s. "
                            "Must be like {'t': 2, 'x': 0, 'y': 1} or "
                            "('t', 'x', 'y', 'c')" % str(axes))

        for x in ['t', 'x', 'y', 'c']:
            self.axes[x] = self.axes.get(x, None)
        axes = self.axes

        if xvals is not None:
            self.tVals = xvals
        elif axes['t'] is not None:
            if hasattr(img, 'xvals'):
                try:
                    self.tVals = img.xvals(axes['t'])
                except Exception:
                    self.tVals = np.arange(img.shape[axes['t']])
            else:
                self.tVals = np.arange(img.shape[axes['t']])

        self.currentIndex = 0
        self.updateImage(autoHistogramRange=autoHistogramRange)
        if levels is None and autoLevels:
            self.autoLevels()
        # this does nothing since getProcessedImage sets these values again.
        if levels is not None:
            self.setLevels(*levels)

        if self.roiEnabled:
            self.roiChanged()

        if self.axes['t'] is not None:
            self.ui.roiPlot.setXRange(self.tVals.min(), self.tVals.max())
            self.timeLine.setValue(0)
            if len(self.tVals) > 1:
                start = self.tVals.min()
                stop = (self.tVals.max() +
                        abs(self.tVals[-1] - self.tVals[0]) * 0.02)
            elif len(self.tVals) == 1:
                start = self.tVals[0] - 0.5
                stop = self.tVals[0] + 0.5
            else:
                start = 0
                stop = 1
            for s in [self.timeLine, self.normRgn]:
                s.setBounds([start, stop])

        self.imageItem.resetTransform()
        if scale is not None:
            self.imageItem.scale(*scale)
        if pos is not None:
            self.imageItem.setPos(*pos)
        if transform is not None:
            self.imageItem.setTransform(transform)

        if autoRange:
            self.autoRange()
        self._updateRoiPlot()

    # Override normalization functions to just return the image as is
    # We do not use ImageView's normalization features (yet)
    def normalize(self, image):
        return image.view(np.ndarray).copy()

    # Override as well
    def updateNorm(self):
        pass

    def setROIType(self, roiType):
        if roiType is None:
            self.roiEnabled = False
        else:
            self.roiEnabled = True
            if roiType == ROIType.SEMIAUTOMATIC:
                self._showSlider()
            else:
                self._hideSlider()
            self.roi.setROIType(roiType)
        self._updateRoiPlot()

    def _updateRoiPlot(self):
        showRoiPlot = False
        if self.roiEnabled:
            showRoiPlot = True
            self.roi.show()
            self.ui.roiPlot.setMouseEnabled(True, True)
            self.ui.splitter.setSizes(
                [self.height() * 0.6, self.height() * 0.4])
            self.roiCurve.show()
            self.roiChanged()
            self.ui.roiPlot.showAxis('left')
        else:
            self.roi.hide()
            self.ui.roiPlot.setMouseEnabled(False, False)
            self.roiCurve.hide()
            self.ui.roiPlot.hideAxis('left')

        if self.hasTimeAxis():
            showRoiPlot = True
            mn = self.tVals.min()
            mx = self.tVals.max()
            self.ui.roiPlot.setXRange(mn, mx, padding=0.01)
            self.timeLine.show()
            self.timeLine.setBounds([mn, mx])
            self.ui.roiPlot.show()
            if not self.roiEnabled:
                self.ui.splitter.setSizes([self.height() - 35, 35])
        else:
            self.timeLine.hide()

        self.ui.roiPlot.setVisible(showRoiPlot)

    def _hideSlider(self):
        self.ui.horizontalSliderLabel.hide()
        self.ui.horizontalSlider.hide()
        self.ui.sliderValueSpinBox.hide()

    def _showSlider(self):
        self.ui.horizontalSliderLabel.show()
        self.ui.horizontalSlider.show()
        self.ui.sliderValueSpinBox.show()

    def _sliderValueChanged(self, value):
        spinBoxVal = value / 100.0
        self.ui.sliderValueSpinBox.setValue(spinBoxVal)
        self.roi.setSliderValue(spinBoxVal)

    def _spinBoxChanged(self, value):
        self.ui.horizontalSlider.setValue(int(value * 100))
        self.roi.setSliderValue(value)