Example #1
0
    def _computeAutoscaleRange(self, data):
        """Compute the data range which will be used in autoscale mode.

        :param numpy.ndarray data: The data for which to compute the range
        :return: (vmin, vmax) range (vmin and /or vmax might be `None`)
        """
        if data is None:
            return None, None
        if data.size == 0:
            return None, None

        if self.getNormalization() == Colormap.LOGARITHM:
            if self._autoscaleMode == Colormap.MINMAX:
                result = min_max(data, min_positive=True, finite=True)
                vMin = result.min_positive  # >0 or None
                vMax = result.maximum  # can be <= 0
            elif self._autoscaleMode == Colormap.STDDEV3:
                with numpy.errstate(divide='ignore', invalid='ignore'):
                    normdata = numpy.log10(data)
                mean = numpy.nanmean(normdata)
                std = numpy.nanstd(normdata)
                vMin = float(10**(mean - 3 * std))
                vMax = float(10**(mean + 3 * std))
            else:
                assert False
        else:
            if self._autoscaleMode == Colormap.MINMAX:
                vMin, vMax = min_max(data, min_positive=False, finite=True)
            elif self._autoscaleMode == Colormap.STDDEV3:
                mean = numpy.nanmean(data)
                std = numpy.nanstd(data)
                vMin, vMax = float(mean - 3 * std), float(mean + 3 * std)
            else:
                assert False
        return vMin, vMax
Example #2
0
 def test_nodata(self):
     """Test min_max with None and empty array"""
     for dtype in self.DTYPES:
         with self.subTest(dtype=dtype):
             with self.assertRaises(TypeError):
                 min_max(None)
             
             data = numpy.array((), dtype=dtype)
             with self.assertRaises(ValueError):
                 min_max(data)
    def test_nodata(self):
        """Test min_max with None and empty array"""
        for dtype in self.DTYPES:
            with self.subTest(dtype=dtype):
                with self.assertRaises(TypeError):
                    min_max(None)

                data = numpy.array((), dtype=dtype)
                with self.assertRaises(ValueError):
                    min_max(data)
Example #4
0
File: colors.py Project: fejat/silx
    def getColormapRange(self, data=None):
        """Return (vmin, vmax)

        :return: the tuple vmin, vmax fitting vmin, vmax, normalization and
            data if any given
        :rtype: tuple
        """
        vmin = self._vmin
        vmax = self._vmax
        assert vmin is None or vmax is None or vmin <= vmax  # TODO handle this in setters

        if self.getNormalization() == self.LOGARITHM:
            # Handle negative bounds as autoscale
            if vmin is not None and (vmin is not None and vmin <= 0.):
                mess = 'negative vmin, moving to autoscale for lower bound'
                _logger.warning(mess)
                vmin = None
            if vmax is not None and (vmax is not None and vmax <= 0.):
                mess = 'negative vmax, moving to autoscale for upper bound'
                _logger.warning(mess)
                vmax = None

        if vmin is None or vmax is None:  # Handle autoscale
            # Get min/max from data
            if data is not None:
                data = numpy.array(data, copy=False)
                if data.size == 0:  # Fallback an array but no data
                    min_, max_ = self._getDefaultMin(), self._getDefaultMax()
                else:
                    if self.getNormalization() == self.LOGARITHM:
                        result = min_max(data, min_positive=True, finite=True)
                        min_ = result.min_positive  # >0 or None
                        max_ = result.maximum  # can be <= 0
                    else:
                        min_, max_ = min_max(data,
                                             min_positive=False,
                                             finite=True)

                    # Handle fallback
                    if min_ is None or not numpy.isfinite(min_):
                        min_ = self._getDefaultMin()
                    if max_ is None or not numpy.isfinite(max_):
                        max_ = self._getDefaultMax()
            else:  # Fallback if no data is provided
                min_, max_ = self._getDefaultMin(), self._getDefaultMax()

            if vmin is None:  # Set vmin respecting provided vmax
                vmin = min_ if vmax is None else min(min_, vmax)

            if vmax is None:
                vmax = max(max_, vmin)  # Handle max_ <= 0 for log scale

        return vmin, vmax
Example #5
0
    def getColormapRange(self, data=None):
        """Return (vmin, vmax)

        :return: the tuple vmin, vmax fitting vmin, vmax, normalization and
            data if any given
        :rtype: tuple
        """
        vmin = self._vmin
        vmax = self._vmax
        assert vmin is None or vmax is None or vmin <= vmax  # TODO handle this in setters

        if self.getNormalization() == self.LOGARITHM:
            # Handle negative bounds as autoscale
            if vmin is not None and (vmin is not None and vmin <= 0.):
                mess = 'negative vmin, moving to autoscale for lower bound'
                _logger.warning(mess)
                vmin = None
            if vmax is not None and (vmax is not None and vmax <= 0.):
                mess = 'negative vmax, moving to autoscale for upper bound'
                _logger.warning(mess)
                vmax = None

        if vmin is None or vmax is None:  # Handle autoscale
            # Get min/max from data
            if data is not None:
                data = numpy.array(data, copy=False)
                if data.size == 0:  # Fallback an array but no data
                    min_, max_ = self._getDefaultMin(), self._getDefaultMax()
                else:
                    if self.getNormalization() == self.LOGARITHM:
                        result = min_max(data, min_positive=True, finite=True)
                        min_ = result.min_positive  # >0 or None
                        max_ = result.maximum  # can be <= 0
                    else:
                        min_, max_ = min_max(data, min_positive=False, finite=True)

                    # Handle fallback
                    if min_ is None or not numpy.isfinite(min_):
                        min_ = self._getDefaultMin()
                    if max_ is None or not numpy.isfinite(max_):
                        max_ = self._getDefaultMax()
            else:  # Fallback if no data is provided
                min_, max_ = self._getDefaultMin(), self._getDefaultMax()

            if vmin is None:  # Set vmin respecting provided vmax
                vmin = min_ if vmax is None else min(min_, vmax)

            if vmax is None:
                vmax = max(max_, vmin)  # Handle max_ <= 0 for log scale

        return vmin, vmax
Example #6
0
    def computeHistogram(data):
        """Compute the data histogram as used by :meth:`setHistogram`.

        :param data: The data to process
        :rtype: Tuple(List(float),List(float)
        """
        _data = data
        if _data.ndim == 3:  # RGB(A) images
            _logger.info('Converting current image from RGB(A) to grayscale\
                in order to compute the intensity distribution')
            _data = (_data[:, :, 0] * 0.299 +
                     _data[:, :, 1] * 0.587 +
                     _data[:, :, 2] * 0.114)

        if len(_data) == 0:
            return None, None

        xmin, xmax = min_max(_data, min_positive=False, finite=True)
        nbins = min(256, int(numpy.sqrt(_data.size)))
        data_range = xmin, xmax

        # bad hack: get 256 bins in the case we have a B&W
        if numpy.issubdtype(_data.dtype, numpy.integer):
            if nbins > xmax - xmin:
                nbins = xmax - xmin

        nbins = max(2, nbins)
        _data = _data.ravel().astype(numpy.float32)

        histogram = Histogramnd(_data, n_bins=nbins, histo_range=data_range)
        return histogram.histo, histogram.edges[0]
Example #7
0
    def computeDataRange(data):
        """Compute the data range as used by :meth:`setDataRange`.

        :param data: The data to process
        :rtype: Tuple(float, float, float)
        """
        if data is None or len(data) == 0:
            return None, None, None

        dataRange = min_max(data, min_positive=True, finite=True)
        if dataRange.minimum is None:
            # Only non-finite data
            dataRange = None

        if dataRange is not None:
            min_positive = dataRange.min_positive
            if min_positive is None:
                min_positive = float('nan')
            dataRange = dataRange.minimum, min_positive, dataRange.maximum

        if dataRange is None or len(dataRange) != 3:
            qt.QMessageBox.warning(
                None, "No Data",
                "Image data does not contain any real value")
            dataRange = 1., 1., 10.

        return dataRange
Example #8
0
    def createContext(self, item, plot, onlimits):
        self.origin = item.getOrigin()
        self.scale = item.getScale()
        self.data = item.getData()

        if onlimits:
            minX, maxX = plot.getXAxis().getLimits()
            minY, maxY = plot.getYAxis().getLimits()

            XMinBound = int((minX - self.origin[0]) / self.scale[0])
            YMinBound = int((minY - self.origin[1]) / self.scale[1])
            XMaxBound = int((maxX - self.origin[0]) / self.scale[0])
            YMaxBound = int((maxY - self.origin[1]) / self.scale[1])

            XMinBound = max(XMinBound, 0)
            YMinBound = max(YMinBound, 0)

            if XMaxBound <= XMinBound or YMaxBound <= YMinBound:
                return self.noDataSelected()
            data = item.getData()
            self.data = data[YMinBound:YMaxBound + 1, XMinBound:XMaxBound + 1]
        else:
            self.data = item.getData()

        if self.data.size > 0:
            self.min, self.max = min_max(self.data)
        else:
            self.min, self.max = None, None
        self.values = self.data
Example #9
0
    def computeDataRange(data):
        """Compute the data range as used by :meth:`setDataRange`.

        :param data: The data to process
        :rtype: Tuple(float, float, float)
        """
        if data is None or len(data) == 0:
            return None, None, None

        dataRange = min_max(data, min_positive=True, finite=True)
        if dataRange.minimum is None:
            # Only non-finite data
            dataRange = None

        if dataRange is not None:
            min_positive = dataRange.min_positive
            if min_positive is None:
                min_positive = float('nan')
            dataRange = dataRange.minimum, min_positive, dataRange.maximum

        if dataRange is None or len(dataRange) != 3:
            qt.QMessageBox.warning(
                None, "No Data", "Image data does not contain any real value")
            dataRange = 1., 1., 10.

        return dataRange
Example #10
0
    def computeHistogram(data):
        """Compute the data histogram as used by :meth:`setHistogram`.

        :param data: The data to process
        :rtype: Tuple(List(float),List(float)
        """
        _data = data
        if _data.ndim == 3:  # RGB(A) images
            _logger.info('Converting current image from RGB(A) to grayscale\
                in order to compute the intensity distribution')
            _data = (_data[:, :, 0] * 0.299 + _data[:, :, 1] * 0.587 +
                     _data[:, :, 2] * 0.114)

        if len(_data) == 0:
            return None, None

        xmin, xmax = min_max(_data, min_positive=False, finite=True)
        nbins = min(256, int(numpy.sqrt(_data.size)))
        data_range = xmin, xmax

        # bad hack: get 256 bins in the case we have a B&W
        if numpy.issubdtype(_data.dtype, numpy.integer):
            if nbins > xmax - xmin:
                nbins = xmax - xmin

        nbins = max(2, nbins)
        _data = _data.ravel().astype(numpy.float32)

        histogram = Histogramnd(_data, n_bins=nbins, histo_range=data_range)
        return histogram.histo, histogram.edges[0]
Example #11
0
File: stats.py Project: vasole/silx
    def createContext(self, item, plot, onlimits):
        self.origin = item.getOrigin()
        self.scale = item.getScale()
        self.data = item.getData()

        if onlimits:
            minX, maxX = plot.getXAxis().getLimits()
            minY, maxY = plot.getYAxis().getLimits()

            XMinBound = int((minX - self.origin[0]) / self.scale[0])
            YMinBound = int((minY - self.origin[1]) / self.scale[1])
            XMaxBound = int((maxX - self.origin[0]) / self.scale[0])
            YMaxBound = int((maxY - self.origin[1]) / self.scale[1])

            XMinBound = max(XMinBound, 0)
            YMinBound = max(YMinBound, 0)

            if XMaxBound <= XMinBound or YMaxBound <= YMinBound:
                return self.noDataSelected()
            data = item.getData()
            self.data = data[YMinBound:YMaxBound + 1, XMinBound:XMaxBound + 1]
        else:
            self.data = item.getData()

        if self.data.size > 0:
            self.min, self.max = min_max(self.data)
        else:
            self.min, self.max = None, None
        self.values = self.data
    def test_benchmark_min_max(self):
        """Benchmark min_max without min positive.
        
        Compares with:
        
        - numpy.nanmin, numpy.nanmax and
        - numpy.argmin, numpy.argmax

        It runs bench for different types, different data size and 3
        data sets: increasing , decreasing and random data.
        """
        durations = {'min/max': [], 'argmin/max': [], 'combo': []}

        _logger.info('Benchmark against argmin/argmax and nanmin/nanmax')

        for dtype in self.DTYPES:
            for arange in self.ARANGE:
                for exponent in self.EXPONENT:
                    size = 10**exponent
                    with self.subTest(dtype=dtype, size=size, arange=arange):
                        if arange == 'ascent':
                            data = numpy.arange(0, size, 1, dtype=dtype)
                        elif arange == 'descent':
                            data = numpy.arange(size, 0, -1, dtype=dtype)
                        else:
                            if dtype in ('float32', 'float64'):
                                data = numpy.random.random(size)
                            else:
                                data = numpy.random.randint(10**6, size=size)
                            data = numpy.array(data, dtype=dtype)

                        start = time.time()
                        ref_min = numpy.nanmin(data)
                        ref_max = numpy.nanmax(data)
                        durations['min/max'].append(time.time() - start)

                        start = time.time()
                        ref_argmin = numpy.argmin(data)
                        ref_argmax = numpy.argmax(data)
                        durations['argmin/max'].append(time.time() - start)

                        start = time.time()
                        result = combo.min_max(data, min_positive=False)
                        durations['combo'].append(time.time() - start)

                        _logger.info(
                            '%s-%s-10**%d\tx%.2f argmin/max x%.2f min/max',
                            dtype, arange, exponent,
                            durations['argmin/max'][-1] /
                            durations['combo'][-1],
                            durations['min/max'][-1] / durations['combo'][-1])

                        self.assertEqual(result.minimum, ref_min)
                        self.assertEqual(result.maximum, ref_max)
                        self.assertEqual(result.argmin, ref_argmin)
                        self.assertEqual(result.argmax, ref_argmax)

        self.show_results('min/max', durations, 'combo')
Example #13
0
    def test_benchmark_min_max(self):
        """Benchmark min_max without min positive.
        
        Compares with:
        
        - numpy.nanmin, numpy.nanmax and
        - numpy.argmin, numpy.argmax

        It runs bench for different types, different data size and 3
        data sets: increasing , decreasing and random data.
        """
        durations = {'min/max': [], 'argmin/max': [], 'combo': []}

        _logger.info('Benchmark against argmin/argmax and nanmin/nanmax')

        for dtype in self.DTYPES:
            for arange in self.ARANGE:
                for exponent in self.EXPONENT:
                    size = 10**exponent
                    with self.subTest(dtype=dtype, size=size, arange=arange):
                        if arange == 'ascent':
                            data = numpy.arange(0, size, 1, dtype=dtype)
                        elif arange == 'descent':
                            data = numpy.arange(size, 0, -1, dtype=dtype)
                        else:
                            if dtype in ('float32', 'float64'):
                                data = numpy.random.random(size)
                            else:
                                data = numpy.random.randint(10**6, size=size)
                            data = numpy.array(data, dtype=dtype)

                        start = time.time()
                        ref_min = numpy.nanmin(data)
                        ref_max = numpy.nanmax(data)
                        durations['min/max'].append(time.time() - start)

                        start = time.time()
                        ref_argmin = numpy.argmin(data)
                        ref_argmax = numpy.argmax(data)
                        durations['argmin/max'].append(time.time() - start)

                        start = time.time()
                        result = combo.min_max(data, min_positive=False)
                        durations['combo'].append(time.time() - start)

                        _logger.info(
                            '%s-%s-10**%d\tx%.2f argmin/max x%.2f min/max',
                            dtype, arange, exponent,
                            durations['argmin/max'][-1] / durations['combo'][-1],
                            durations['min/max'][-1] / durations['combo'][-1])

                        self.assertEqual(result.minimum, ref_min)
                        self.assertEqual(result.maximum, ref_max)
                        self.assertEqual(result.argmin, ref_argmin)
                        self.assertEqual(result.argmax, ref_argmax)

        self.show_results('min/max', durations, 'combo')
    def from_points(points):
        """

        :param numpy.array tuple points: list of points. Should be 2D:
                                         [(y1, x1), (y2, x2), (y3, x3), ...]
        :return: bounding box from two points
        :rtype: _BoundingBox
        """
        if not isinstance(points, numpy.ndarray):
            points_ = numpy.ndarray(points)
        else:
            points_ = points
        x = points_[:, 1]
        y = points_[:, 0]
        x_min, x_max = min_max(x)
        y_min, y_max = min_max(y)
        return _BoundingBox(bottom_left=(y_min, x_min),
                            top_right=(y_max, x_max))
Example #15
0
    def setData(self, data, copy=True):
        """Set the 3D scalar data set to use for building the iso-surface.

        Dataset order is zyx (i.e., first dimension is z).

        :param data: scalar field from which to extract the iso-surface
        :type data: 3D numpy.ndarray of float32 with shape at least (2, 2, 2)
        :param bool copy:
            True (default) to make a copy,
            False to avoid copy (DO NOT MODIFY data afterwards)
        """
        if data is None:
            self._data = None
            self._dataRange = None
            self.setSelectedRegion(zrange=None, yrange=None, xrange_=None)
            self._group.shape = None
            self.centerScene()

        else:
            data = numpy.array(data, copy=copy, dtype=numpy.float32, order='C')
            assert data.ndim == 3
            assert min(data.shape) >= 2

            wasData = self._data is not None
            previousSelectedRegion = self.getSelectedRegion()

            self._data = data

            # Store data range info
            dataRange = min_max(self._data, min_positive=True, finite=True)
            if dataRange.minimum is None:  # Only non-finite data
                dataRange = None

            if dataRange is not None:
                min_positive = dataRange.min_positive
                if min_positive is None:
                    min_positive = float('nan')
                dataRange = dataRange.minimum, min_positive, dataRange.maximum
            self._dataRange = dataRange

            if previousSelectedRegion is not None:
                # Update selected region to ensure it is clipped to array range
                self.setSelectedRegion(*previousSelectedRegion.getArrayRange())

            self._group.shape = self._data.shape

            if not wasData:
                self.centerScene()  # Reset viewpoint the first time only

        # Update iso-surfaces
        for isosurface in self.getIsosurfaces():
            isosurface._setData(self._data, copy=False)

        self.sigDataChanged.emit()
Example #16
0
    def autoscaleMinMax(self, data):
        """Autoscale using min/max

        :param numpy.ndarray data:
        :returns: (vmin, vmax)
        :rtype: Tuple[float,float]
        """
        data = data[self.isValid(data)]
        if data.size == 0:
            return None, None
        result = min_max(data, min_positive=False, finite=True)
        return result.minimum, result.maximum
    def computeIntensityDistribution(self):
        """Get the active image and compute the image intensity distribution
        """
        item = self._getSelectedItem()

        if item is None:
            self._cleanUp()
            return

        if isinstance(item, items.ImageBase):
            array = item.getData(copy=False)
            if array.ndim == 3:  # RGB(A) images
                _logger.info('Converting current image from RGB(A) to grayscale\
                    in order to compute the intensity distribution')
                array = (array[:, :, 0] * 0.299 +
                         array[:, :, 1] * 0.587 +
                         array[:, :, 2] * 0.114)
        elif isinstance(item, items.Scatter):
            array = item.getValueData(copy=False)
        else:
            assert(False)

        if array.size == 0:
            self._cleanUp()
            return

        xmin, xmax = min_max(array, min_positive=False, finite=True)
        nbins = min(1024, int(numpy.sqrt(array.size)))
        data_range = xmin, xmax

        # bad hack: get 256 bins in the case we have a B&W
        if numpy.issubdtype(array.dtype, numpy.integer):
            if nbins > xmax - xmin:
                nbins = xmax - xmin

        nbins = max(2, nbins)

        data = array.ravel().astype(numpy.float32)
        histogram = Histogramnd(data, n_bins=nbins, histo_range=data_range)
        assert len(histogram.edges) == 1
        self._histo = histogram.histo
        edges = histogram.edges[0]
        plot = self.getHistogramPlotWidget()
        plot.addHistogram(histogram=self._histo,
                          edges=edges,
                          legend='pixel intensity',
                          fill=True,
                          color='#66aad7')
        plot.resetZoom()
Example #18
0
    def _computeView(self, dataMin, dataMax):
        """Compute the location of the view according to the bound of the data

        :rtype: Tuple(float, float)
        """
        marginRatio = 1.0 / 6.0
        scale = self._plot.getXAxis().getScale()

        if self._dataRange is not None:
            if scale == Axis.LOGARITHMIC:
                minRange = self._dataRange[1]
            else:
                minRange = self._dataRange[0]
            maxRange = self._dataRange[2]
            if minRange is not None:
                dataMin = min(dataMin, minRange)
                dataMax = max(dataMax, maxRange)

        if self._histogramData is not None:
            info = min_max(self._histogramData[1])
            if scale == Axis.LOGARITHMIC:
                minHisto = info.min_positive
            else:
                minHisto = info.minimum
            maxHisto = info.maximum
            if minHisto is not None:
                dataMin = min(dataMin, minHisto)
                dataMax = max(dataMax, maxHisto)

        if scale == Axis.LOGARITHMIC:
            epsilon = numpy.finfo(numpy.float32).eps
            if dataMin == 0:
                dataMin = epsilon
            if dataMax < dataMin:
                dataMax = dataMin + epsilon
            marge = marginRatio * abs(
                numpy.log10(dataMax) - numpy.log10(dataMin))
            viewMin = 10**(numpy.log10(dataMin) - marge)
            viewMax = 10**(numpy.log10(dataMax) + marge)
        else:  # scale == Axis.LINEAR:
            marge = marginRatio * abs(dataMax - dataMin)
            if marge < 0.0001:
                # Smaller that the QLineEdit precision
                marge = 0.0001
            viewMin = dataMin - marge
            viewMax = dataMax + marge

        return viewMin, viewMax
Example #19
0
File: stats.py Project: vasole/silx
    def createContext(self, item, plot, onlimits):
        xData, edges = item.getData(copy=True)[0:2]
        yData = item._revertComputeEdges(x=edges, histogramType=item.getAlignment())
        if onlimits:
            minX, maxX = plot.getXAxis().getLimits()
            yData = yData[(minX <= xData) & (xData <= maxX)]
            xData = xData[(minX <= xData) & (xData <= maxX)]

        self.xData = xData
        self.yData = yData
        if len(yData) > 0:
            self.min, self.max = min_max(yData)
        else:
            self.min, self.max = None, None
        self.data = (xData, yData)
        self.values = yData
Example #20
0
    def createContext(self, item, plot, onlimits):
        xData, yData = item.getData(copy=True)[0:2]

        if onlimits:
            minX, maxX = plot.getXAxis().getLimits()
            yData = yData[(minX <= xData) & (xData <= maxX)]
            xData = xData[(minX <= xData) & (xData <= maxX)]

        self.xData = xData
        self.yData = yData
        if len(yData) > 0:
            self.min, self.max = min_max(yData)
        else:
            self.min, self.max = None, None
        self.data = (xData, yData)
        self.values = yData
Example #21
0
File: stats.py Project: vasole/silx
    def createContext(self, item, plot, onlimits):
        xData, yData = item.getData(copy=True)[0:2]

        if onlimits:
            minX, maxX = plot.getXAxis().getLimits()
            yData = yData[(minX <= xData) & (xData <= maxX)]
            xData = xData[(minX <= xData) & (xData <= maxX)]

        self.xData = xData
        self.yData = yData
        if len(yData) > 0:
            self.min, self.max = min_max(yData)
        else:
            self.min, self.max = None, None
        self.data = (xData, yData)
        self.values = yData
Example #22
0
    def _computeView(self, dataMin, dataMax):
        """Compute the location of the view according to the bound of the data

        :rtype: Tuple(float, float)
        """
        marginRatio = 1.0 / 6.0
        scale = self._plot.getXAxis().getScale()

        if self._dataRange is not None:
            if scale == Axis.LOGARITHMIC:
                minRange = self._dataRange[1]
            else:
                minRange = self._dataRange[0]
            maxRange = self._dataRange[2]
            if minRange is not None:
                dataMin = min(dataMin, minRange)
                dataMax = max(dataMax, maxRange)

        if self._histogramData is not None:
            info = min_max(self._histogramData[1])
            if scale == Axis.LOGARITHMIC:
                minHisto = info.min_positive
            else:
                minHisto = info.minimum
            maxHisto = info.maximum
            if minHisto is not None:
                dataMin = min(dataMin, minHisto)
                dataMax = max(dataMax, maxHisto)

        if scale == Axis.LOGARITHMIC:
            epsilon = numpy.finfo(numpy.float32).eps
            if dataMin == 0:
                dataMin = epsilon
            if dataMax < dataMin:
                dataMax = dataMin + epsilon
            marge = marginRatio * abs(numpy.log10(dataMax) - numpy.log10(dataMin))
            viewMin = 10**(numpy.log10(dataMin) - marge)
            viewMax = 10**(numpy.log10(dataMax) + marge)
        else:  # scale == Axis.LINEAR:
            marge = marginRatio * abs(dataMax - dataMin)
            if marge < 0.0001:
                # Smaller that the QLineEdit precision
                marge = 0.0001
            viewMin = dataMin - marge
            viewMax = dataMax + marge

        return viewMin, viewMax
Example #23
0
    def _updateFromItem(self):
        """Update histogram and stats from the item"""
        item = self.getItem()

        if item is None:
            self.reset()
            return

        if not isinstance(item, self._SUPPORTED_ITEM_CLASS):
            _logger.error("Unsupported item", item)
            self.reset()
            return

        # Compute histogram and stats
        array = item.getValueData(copy=False)

        if array.size == 0:
            self.reset()
            return

        xmin, xmax = min_max(array, min_positive=False, finite=True)
        nbins = min(1024, int(numpy.sqrt(array.size)))
        data_range = xmin, xmax

        # bad hack: get 256 bins in the case we have a B&W
        if numpy.issubdtype(array.dtype, numpy.integer):
            if nbins > xmax - xmin:
                nbins = xmax - xmin

        nbins = max(2, nbins)

        data = array.ravel().astype(numpy.float32)
        histogram = Histogramnd(data, n_bins=nbins, histo_range=data_range)
        if len(histogram.edges) != 1:
            _logger.error("Error while computing the histogram")
            self.reset()
            return

        self.setHistogram(histogram.histo, histogram.edges[0])
        self.resetZoom()
        self.setStatistics(
            min_=xmin,
            max_=xmax,
            mean=numpy.nanmean(array),
            std=numpy.nanstd(array),
            sum_=numpy.nansum(array))
Example #24
0
    def createContext(self, item, plot, onlimits):
        xData, edges = item.getData(copy=True)[0:2]
        yData = item._revertComputeEdges(x=edges,
                                         histogramType=item.getAlignment())
        if onlimits:
            minX, maxX = plot.getXAxis().getLimits()
            yData = yData[(minX <= xData) & (xData <= maxX)]
            xData = xData[(minX <= xData) & (xData <= maxX)]

        self.xData = xData
        self.yData = yData
        if len(yData) > 0:
            self.min, self.max = min_max(yData)
        else:
            self.min, self.max = None, None
        self.data = (xData, yData)
        self.values = yData
Example #25
0
    def _computeRangeFromData(data):
        """Compute range info (min, min positive, max) from data

        :param Union[numpy.ndarray,None] data:
        :return: Union[List[float],None]
        """
        if data is None:
            return None

        dataRange = min_max(data, min_positive=True, finite=True)
        if dataRange.minimum is None:  # Only non-finite data
            return None

        if dataRange is not None:
            min_positive = dataRange.min_positive
            if min_positive is None:
                min_positive = float('nan')
            return dataRange.minimum, min_positive, dataRange.maximum
Example #26
0
    def _test_min_max(self, data, min_positive, finite=False):
        """Compare min_max with numpy for the given dataset

        :param numpy.ndarray data: Data set to use for test
        :param bool min_positive: True to test with positive min
        :param bool finite: True to only test finite values
        """
        minimum, min_pos, maximum, argmin, argmin_pos, argmax = \
            self._numpy_min_max(data, min_positive, finite)

        result = min_max(data, min_positive, finite)

        self.assertSimilar(minimum, result.minimum)
        self.assertSimilar(min_pos, result.min_positive)
        self.assertSimilar(maximum, result.maximum)
        self.assertSimilar(argmin, result.argmin)
        self.assertSimilar(argmin_pos, result.argmin_positive)
        self.assertSimilar(argmax, result.argmax)
    def _test_min_max(self, data, min_positive, finite=False):
        """Compare min_max with numpy for the given dataset

        :param numpy.ndarray data: Data set to use for test
        :param bool min_positive: True to test with positive min
        :param bool finite: True to only test finite values
        """
        minimum, min_pos, maximum, argmin, argmin_pos, argmax = \
            self._numpy_min_max(data, min_positive, finite)

        result = min_max(data, min_positive, finite)

        self.assertSimilar(minimum, result.minimum)
        self.assertSimilar(min_pos, result.min_positive)
        self.assertSimilar(maximum, result.maximum)
        self.assertSimilar(argmin, result.argmin)
        self.assertSimilar(argmin_pos, result.argmin_positive)
        self.assertSimilar(argmax, result.argmax)
Example #28
0
    def _computeRangeFromData(data):
        """Compute range info (min, min positive, max) from data

        :param Union[numpy.ndarray,None] data:
        :return: Union[List[float],None]
        """
        if data is None:
            return None

        dataRange = min_max(data, min_positive=True, finite=True)
        if dataRange.minimum is None:  # Only non-finite data
            return None

        if dataRange is not None:
            min_positive = dataRange.min_positive
            if min_positive is None:
                min_positive = float('nan')
            return dataRange.minimum, min_positive, dataRange.maximum
Example #29
0
    def setData(self, data, copy=True):
        """Set the 3D scalar data represented by this item.

        Dataset order is zyx (i.e., first dimension is z).

        :param data: 3D array
        :type data: 3D numpy.ndarray of float32 with shape at least (2, 2, 2)
        :param bool copy:
            True (default) to make a copy,
            False to avoid copy (DO NOT MODIFY data afterwards)
        """
        if data is None:
            self._data = None
            self._dataRange = None
            self._boundedGroup.shape = None

        else:
            data = numpy.array(data, copy=copy, dtype=numpy.float32, order='C')
            assert data.ndim == 3
            assert min(data.shape) >= 2

            self._data = data

            # Store data range info
            dataRange = min_max(self._data, min_positive=True, finite=True)
            if dataRange.minimum is None:  # Only non-finite data
                dataRange = None

            if dataRange is not None:
                min_positive = dataRange.min_positive
                if min_positive is None:
                    min_positive = float('nan')
                dataRange = dataRange.minimum, min_positive, dataRange.maximum
            self._dataRange = dataRange

            self._boundedGroup.shape = self._data.shape

        # Update iso-surfaces
        for isosurface in self.getIsosurfaces():
            isosurface._setData(self._data, copy=False)

        self._updated(ItemChangedType.DATA)
Example #30
0
File: volume.py Project: fejat/silx
    def setData(self, data, copy=True):
        """Set the 3D scalar data represented by this item.

        Dataset order is zyx (i.e., first dimension is z).

        :param data: 3D array
        :type data: 3D numpy.ndarray of float32 with shape at least (2, 2, 2)
        :param bool copy:
            True (default) to make a copy,
            False to avoid copy (DO NOT MODIFY data afterwards)
        """
        if data is None:
            self._data = None
            self._dataRange = None
            self._boundedGroup.shape = None

        else:
            data = numpy.array(data, copy=copy, dtype=numpy.float32, order='C')
            assert data.ndim == 3
            assert min(data.shape) >= 2

            self._data = data

            # Store data range info
            dataRange = min_max(self._data, min_positive=True, finite=True)
            if dataRange.minimum is None:  # Only non-finite data
                dataRange = None

            if dataRange is not None:
                min_positive = dataRange.min_positive
                if min_positive is None:
                    min_positive = float('nan')
                dataRange = dataRange.minimum, min_positive, dataRange.maximum
            self._dataRange = dataRange

            self._boundedGroup.shape = self._data.shape

        # Update iso-surfaces
        for isosurface in self.getIsosurfaces():
            isosurface._setData(self._data, copy=False)

        self._updated(ItemChangedType.DATA)
Example #31
0
 def createContext(self, item, plot, onlimits):
     xData, yData, valueData, xerror, yerror = item.getData(copy=True)
     assert plot
     if onlimits:
         minX, maxX = plot.getXAxis().getLimits()
         minY, maxY = plot.getYAxis().getLimits()
         # filter on X axis
         valueData = valueData[(minX <= xData) & (xData <= maxX)]
         yData = yData[(minX <= xData) & (xData <= maxX)]
         xData = xData[(minX <= xData) & (xData <= maxX)]
         # filter on Y axis
         valueData = valueData[(minY <= yData) & (yData <= maxY)]
         xData = xData[(minY <= yData) & (yData <= maxY)]
         yData = yData[(minY <= yData) & (yData <= maxY)]
     if len(valueData) > 0:
         self.min, self.max = min_max(valueData)
     else:
         self.min, self.max = None, None
     self.data = (xData, yData, valueData)
     self.values = valueData
Example #32
0
File: stats.py Project: vasole/silx
 def createContext(self, item, plot, onlimits):
     xData, yData, valueData, xerror, yerror = item.getData(copy=True)
     assert plot
     if onlimits:
         minX, maxX = plot.getXAxis().getLimits()
         minY, maxY = plot.getYAxis().getLimits()
         # filter on X axis
         valueData = valueData[(minX <= xData) & (xData <= maxX)]
         yData = yData[(minX <= xData) & (xData <= maxX)]
         xData = xData[(minX <= xData) & (xData <= maxX)]
         # filter on Y axis
         valueData = valueData[(minY <= yData) & (yData <= maxY)]
         xData = xData[(minY <= yData) & (yData <= maxY)]
         yData = yData[(minY <= yData) & (yData <= maxY)]
     if len(valueData) > 0:
         self.min, self.max = min_max(valueData)
     else:
         self.min, self.max = None, None
     self.data = (xData, yData, valueData)
     self.values = valueData
Example #33
0
    def _test_min_max(self, data, min_positive):
        """Compare min_max with numpy for the given dataset

        :param numpy.ndarray data: Data set to use for test
        :param bool min_positive: True to test with positive min
        """
        result = min_max(data, min_positive)

        minimum = numpy.nanmin(data)
        if numpy.isnan(minimum):  # All NaNs
            self.assertTrue(numpy.isnan(result.minimum))
            self.assertEqual(result.argmin, 0)

        else:
            self.assertEqual(result.minimum, minimum)

            argmin = numpy.where(data == minimum)[0][0]
            self.assertEqual(result.argmin, argmin)

        maximum = numpy.nanmax(data)
        if numpy.isnan(maximum):  # All NaNs
            self.assertTrue(numpy.isnan(result.maximum))
            self.assertEqual(result.argmax, 0)

        else:
            self.assertEqual(result.maximum, maximum)

            argmax = numpy.where(data == maximum)[0][0]
            self.assertEqual(result.argmax, argmax)

        if min_positive:
            pos_data = data[data > 0]
            if len(pos_data) > 0:
                min_pos = numpy.min(pos_data)
                argmin_pos = numpy.where(data == min_pos)[0][0]
            else:
                min_pos = None
                argmin_pos = None
            self.assertEqual(result.min_positive, min_pos)
            self.assertEqual(result.argmin_positive, argmin_pos)
Example #34
0
    def _setRangeFromData(self, data=None):
        """Compute the data range the colormap should use from provided data.

        :param data: Data set from which to compute the range or None
        """
        if data is None or len(data) == 0:
            dataRange = None
        else:
            dataRange = min_max(data, min_positive=True, finite=True)
            if dataRange.minimum is None:  # Only non-finite data
                dataRange = None

            if dataRange is not None:
                min_positive = dataRange.min_positive
                if min_positive is None:
                    min_positive = float('nan')
                dataRange = dataRange.minimum, min_positive, dataRange.maximum

        self._dataRange = dataRange

        if self.getColormap().isAutoscale():
            self._syncSceneColormap()
    def _setRangeFromData(self, data=None):
        """Compute the data range the colormap should use from provided data.

        :param data: Data set from which to compute the range or None
        """
        if data is None or len(data) == 0:
            dataRange = None
        else:
            dataRange = min_max(data, min_positive=True, finite=True)
            if dataRange.minimum is None:  # Only non-finite data
                dataRange = None

            if dataRange is not None:
                min_positive = dataRange.min_positive
                if min_positive is None:
                    min_positive = float('nan')
                dataRange = dataRange.minimum, min_positive, dataRange.maximum

        self._dataRange = dataRange

        if self.getColormap().isAutoscale():
            self._syncSceneColormap()
Example #36
0
    def _setRangeFromData(self, data=None):
        """Compute the data range the colormap should use from provided data.

        :param data: Data set from which to compute the range or None
        """
        if data is None or data.size == 0:
            dataRange = None
        else:
            dataRange = min_max(data, min_positive=True, finite=True)
            if dataRange.minimum is None:  # Only non-finite data
                dataRange = None

            if dataRange is not None:
                min_positive = dataRange.min_positive
                if min_positive is None:
                    min_positive = float('nan')
                dataRange = dataRange.minimum, min_positive, dataRange.maximum

        self._dataRange = dataRange

        colormap = self.getColormap()
        if None in (colormap.getVMin(), colormap.getVMax()):
            self._colormapChanged()
Example #37
0
    def _setRangeFromData(self, data=None):
        """Compute the data range the colormap should use from provided data.

        :param data: Data set from which to compute the range or None
        """
        if data is None or data.size == 0:
            dataRange = None
        else:
            dataRange = min_max(data, min_positive=True, finite=True)
            if dataRange.minimum is None:  # Only non-finite data
                dataRange = None

            if dataRange is not None:
                min_positive = dataRange.min_positive
                if min_positive is None:
                    min_positive = float('nan')
                dataRange = dataRange.minimum, min_positive, dataRange.maximum

        self._dataRange = dataRange

        colormap = self.getColormap()
        if None in (colormap.getVMin(), colormap.getVMax()):
            self._colormapChanged()
    def computeIntensityDistribution(self):
        """Get the active image and compute the image intensity distribution
        """
        activeImage = self.plot.getActiveImage()

        if activeImage is not None:
            image = activeImage.getData(copy=False)
            if image.ndim == 3:  # RGB(A) images
                _logger.info(
                    'Converting current image from RGB(A) to grayscale\
                    in order to compute the intensity distribution')
                image = (image[:, :, 0] * 0.299 + image[:, :, 1] * 0.587 +
                         image[:, :, 2] * 0.114)

            xmin, xmax = min_max(image, min_positive=False, finite=True)
            nbins = min(1024, int(numpy.sqrt(image.size)))
            data_range = xmin, xmax

            # bad hack: get 256 bins in the case we have a B&W
            if numpy.issubdtype(image.dtype, numpy.integer):
                if nbins > xmax - xmin:
                    nbins = xmax - xmin

            nbins = max(2, nbins)

            data = image.ravel().astype(numpy.float32)
            histogram = Histogramnd(data, n_bins=nbins, histo_range=data_range)
            assert len(histogram.edges) == 1
            self._histo = histogram.histo
            edges = histogram.edges[0]
            plot = self.getHistogramPlotWidget()
            plot.addHistogram(histogram=self._histo,
                              edges=edges,
                              legend='pixel intensity',
                              fill=True,
                              color='#66aad7')
            plot.resetZoom()
Example #39
0
    def computeIntensityDistribution(self):
        """Get the active image and compute the image intensity distribution
        """
        activeImage = self.plot.getActiveImage()

        if activeImage is not None:
            image = activeImage.getData(copy=False)
            if image.ndim == 3:  # RGB(A) images
                _logger.info('Converting current image from RGB(A) to grayscale\
                    in order to compute the intensity distribution')
                image = (image[:, :, 0] * 0.299 +
                         image[:, :, 1] * 0.587 +
                         image[:, :, 2] * 0.114)

            xmin, xmax = min_max(image, min_positive=False, finite=True)
            nbins = min(1024, int(numpy.sqrt(image.size)))
            data_range = xmin, xmax

            # bad hack: get 256 bins in the case we have a B&W
            if numpy.issubdtype(image.dtype, numpy.integer):
                if nbins > xmax - xmin:
                    nbins = xmax - xmin

            nbins = max(2, nbins)

            data = image.ravel().astype(numpy.float32)
            histogram = Histogramnd(data, n_bins=nbins, histo_range=data_range)
            assert len(histogram.edges) == 1
            self._histo = histogram.histo
            edges = histogram.edges[0]
            plot = self.getHistogramPlotWidget()
            plot.addHistogram(histogram=self._histo,
                              edges=edges,
                              legend='pixel intensity',
                              fill=True,
                              color='#66aad7')
            plot.resetZoom()
Example #40
0
    def __init__(self, xData, yData, colorData=None,
                 xError=None, yError=None,
                 lineStyle=SOLID,
                 lineColor=(0., 0., 0., 1.),
                 lineWidth=1,
                 lineDashPeriod=20,
                 marker=SQUARE,
                 markerColor=(0., 0., 0., 1.),
                 markerSize=7,
                 fillColor=None,
                 isYLog=False):

        self.colorData = colorData

        # Compute x bounds
        if xError is None:
            self.xMin, self.xMax = min_max(xData, min_positive=False)
        else:
            # Takes the error into account
            if hasattr(xError, 'shape') and len(xError.shape) == 2:
                xErrorMinus, xErrorPlus = xError[0], xError[1]
            else:
                xErrorMinus, xErrorPlus = xError, xError
            self.xMin = numpy.nanmin(xData - xErrorMinus)
            self.xMax = numpy.nanmax(xData + xErrorPlus)

        # Compute y bounds
        if yError is None:
            self.yMin, self.yMax = min_max(yData, min_positive=False)
        else:
            # Takes the error into account
            if hasattr(yError, 'shape') and len(yError.shape) == 2:
                yErrorMinus, yErrorPlus = yError[0], yError[1]
            else:
                yErrorMinus, yErrorPlus = yError, yError
            self.yMin = numpy.nanmin(yData - yErrorMinus)
            self.yMax = numpy.nanmax(yData + yErrorPlus)

        # Handle data offset
        if xData.itemsize > 4 or yData.itemsize > 4:  # Use normalization
            # offset data, do not offset error as it is relative
            self.offset = self.xMin, self.yMin
            self.xData = (xData - self.offset[0]).astype(numpy.float32)
            self.yData = (yData - self.offset[1]).astype(numpy.float32)

        else:  # float32
            self.offset = 0., 0.
            self.xData = xData
            self.yData = yData

        if fillColor is not None:
            # Use different baseline depending of Y log scale
            self.fill = _Fill2D(self.xData, self.yData,
                                baseline=-38 if isYLog else 0,
                                color=fillColor,
                                offset=self.offset)
        else:
            self.fill = None

        self._errorBars = _ErrorBars(self.xData, self.yData,
                                     xError, yError,
                                     self.xMin, self.yMin,
                                     offset=self.offset)

        self.lines = GLLines2D()
        self.lines.style = lineStyle
        self.lines.color = lineColor
        self.lines.width = lineWidth
        self.lines.dashPeriod = lineDashPeriod
        self.lines.offset = self.offset

        self.points = _Points2D()
        self.points.marker = marker
        self.points.color = markerColor
        self.points.size = markerSize
        self.points.offset = self.offset
Example #41
0
    def __init__(self,
                 xData,
                 yData,
                 colorData=None,
                 xError=None,
                 yError=None,
                 lineStyle=SOLID,
                 lineColor=(0., 0., 0., 1.),
                 lineWidth=1,
                 lineDashPeriod=20,
                 marker=SQUARE,
                 markerColor=(0., 0., 0., 1.),
                 markerSize=7,
                 fillColor=None,
                 baseline=None,
                 isYLog=False):

        self.colorData = colorData

        # Compute x bounds
        if xError is None:
            self.xMin, self.xMax = min_max(xData, min_positive=False)
        else:
            # Takes the error into account
            if hasattr(xError, 'shape') and len(xError.shape) == 2:
                xErrorMinus, xErrorPlus = xError[0], xError[1]
            else:
                xErrorMinus, xErrorPlus = xError, xError
            self.xMin = numpy.nanmin(xData - xErrorMinus)
            self.xMax = numpy.nanmax(xData + xErrorPlus)

        # Compute y bounds
        if yError is None:
            self.yMin, self.yMax = min_max(yData, min_positive=False)
        else:
            # Takes the error into account
            if hasattr(yError, 'shape') and len(yError.shape) == 2:
                yErrorMinus, yErrorPlus = yError[0], yError[1]
            else:
                yErrorMinus, yErrorPlus = yError, yError
            self.yMin = numpy.nanmin(yData - yErrorMinus)
            self.yMax = numpy.nanmax(yData + yErrorPlus)

        # Handle data offset
        if xData.itemsize > 4 or yData.itemsize > 4:  # Use normalization
            # offset data, do not offset error as it is relative
            self.offset = self.xMin, self.yMin
            self.xData = (xData - self.offset[0]).astype(numpy.float32)
            self.yData = (yData - self.offset[1]).astype(numpy.float32)

        else:  # float32
            self.offset = 0., 0.
            self.xData = xData
            self.yData = yData
        if fillColor is not None:

            def deduce_baseline(baseline):
                if baseline is None:
                    _baseline = 0
                else:
                    _baseline = baseline
                if not isinstance(_baseline, numpy.ndarray):
                    _baseline = numpy.repeat(_baseline, len(self.xData))
                if isYLog is True:
                    with numpy.errstate(divide='ignore', invalid='ignore'):
                        log_val = numpy.log10(_baseline)
                        _baseline = numpy.where(_baseline > 0.0, log_val, -38)
                return _baseline

            _baseline = deduce_baseline(baseline)

            # Use different baseline depending of Y log scale
            self.fill = _Fill2D(self.xData,
                                self.yData,
                                baseline=_baseline,
                                color=fillColor,
                                offset=self.offset)
        else:
            self.fill = None

        self._errorBars = _ErrorBars(self.xData,
                                     self.yData,
                                     xError,
                                     yError,
                                     self.xMin,
                                     self.yMin,
                                     offset=self.offset)

        self.lines = GLLines2D()
        self.lines.style = lineStyle
        self.lines.color = lineColor
        self.lines.width = lineWidth
        self.lines.dashPeriod = lineDashPeriod
        self.lines.offset = self.offset

        self.points = _Points2D()
        self.points.marker = marker
        self.points.color = markerColor
        self.points.size = markerSize
        self.points.offset = self.offset
Example #42
0
    def __init__(self, xData, yData, colorData=None,
                 xError=None, yError=None,
                 lineStyle=SOLID,
                 lineColor=(0., 0., 0., 1.),
                 lineWidth=1,
                 lineDashPeriod=20,
                 marker=SQUARE,
                 markerColor=(0., 0., 0., 1.),
                 markerSize=7,
                 fillColor=None,
                 isYLog=False):

        self.colorData = colorData

        # Compute x bounds
        if xError is None:
            self.xMin, self.xMax = min_max(xData, min_positive=False)
        else:
            # Takes the error into account
            if hasattr(xError, 'shape') and len(xError.shape) == 2:
                xErrorMinus, xErrorPlus = xError[0], xError[1]
            else:
                xErrorMinus, xErrorPlus = xError, xError
            self.xMin = numpy.nanmin(xData - xErrorMinus)
            self.xMax = numpy.nanmax(xData + xErrorPlus)

        # Compute y bounds
        if yError is None:
            self.yMin, self.yMax = min_max(yData, min_positive=False)
        else:
            # Takes the error into account
            if hasattr(yError, 'shape') and len(yError.shape) == 2:
                yErrorMinus, yErrorPlus = yError[0], yError[1]
            else:
                yErrorMinus, yErrorPlus = yError, yError
            self.yMin = numpy.nanmin(yData - yErrorMinus)
            self.yMax = numpy.nanmax(yData + yErrorPlus)

        # Handle data offset
        if xData.itemsize > 4 or yData.itemsize > 4:  # Use normalization
            # offset data, do not offset error as it is relative
            self.offset = self.xMin, self.yMin
            self.xData = (xData - self.offset[0]).astype(numpy.float32)
            self.yData = (yData - self.offset[1]).astype(numpy.float32)

        else:  # float32
            self.offset = 0., 0.
            self.xData = xData
            self.yData = yData

        if fillColor is not None:
            # Use different baseline depending of Y log scale
            self.fill = _Fill2D(self.xData, self.yData,
                                baseline=-38 if isYLog else 0,
                                color=fillColor,
                                offset=self.offset)
        else:
            self.fill = None

        self._errorBars = _ErrorBars(self.xData, self.yData,
                                     xError, yError,
                                     self.xMin, self.yMin,
                                     offset=self.offset)

        self.lines = GLLines2D()
        self.lines.style = lineStyle
        self.lines.color = lineColor
        self.lines.width = lineWidth
        self.lines.dashPeriod = lineDashPeriod
        self.lines.offset = self.offset

        self.points = _Points2D()
        self.points.marker = marker
        self.points.color = markerColor
        self.points.size = markerSize
        self.points.offset = self.offset
Example #43
0
    def _updateFromItem(self):
        """Update histogram and stats from the item"""
        item = self.getItem()

        if item is None:
            self.reset()
            return

        if not isinstance(item, self._SUPPORTED_ITEM_CLASS):
            _logger.error("Unsupported item", item)
            self.reset()
            return

        # Compute histogram and stats
        array = item.getValueData(copy=False)

        if array.size == 0:
            self.reset()
            return

        xmin, xmax = min_max(array, min_positive=False, finite=True)
        if xmin is None or xmax is None:  # All not finite data
            self.reset()
            return
        guessed_nbins = min(1024, int(numpy.sqrt(array.size)))

        # bad hack: get 256 bins in the case we have a B&W
        if numpy.issubdtype(array.dtype, numpy.integer):
            if guessed_nbins > xmax - xmin:
                guessed_nbins = xmax - xmin
        guessed_nbins = max(2, guessed_nbins)

        # Set default nbins
        self.__nbinsLineEdit.setDefaultValue(guessed_nbins, extend_range=True)
        # Set slider range: do not keep the range value, but the relative pos.
        previousPositions = self.__rangeSlider.getPositions()
        if xmin == xmax:  # Enlarge range is none
            if xmin == 0:
                range_ = -0.01, 0.01
            else:
                range_ = sorted((xmin * .99, xmin * 1.01))
        else:
            range_ = xmin, xmax

        self.__rangeSlider.setRange(*range_)
        self.__rangeSlider.setPositions(*previousPositions)

        histogram = Histogramnd(
            array.ravel().astype(numpy.float32),
            n_bins=max(2, self.__nbinsLineEdit.getValue()),
            histo_range=self.__rangeSlider.getValues(),
        )
        if len(histogram.edges) != 1:
            _logger.error("Error while computing the histogram")
            self.reset()
            return

        self.setHistogram(histogram.histo, histogram.edges[0])
        self.resetZoom()
        self.setStatistics(min_=xmin,
                           max_=xmax,
                           mean=numpy.nanmean(array),
                           std=numpy.nanstd(array),
                           sum_=numpy.nansum(array))
Example #44
0
 def autoscaleMinMax(self, data):
     result = min_max(data, min_positive=True, finite=True)
     return result.min_positive, result.maximum
Example #45
0
    def __init__(self,
                 xData,
                 yData,
                 colorData=None,
                 xError=None,
                 yError=None,
                 lineStyle=None,
                 lineColor=None,
                 lineWidth=None,
                 lineDashPeriod=None,
                 marker=None,
                 markerColor=None,
                 markerSize=None,
                 fillColor=None):
        self._isXLog = False
        self._isYLog = False
        self.xData, self.yData, self.colorData = xData, yData, colorData

        if fillColor is not None:
            self.fill = _Fill2D(color=fillColor)
        else:
            self.fill = None

        # Compute x bounds
        if xError is None:
            result = min_max(xData, min_positive=True)
            self.xMin = result.minimum
            self.xMinPos = result.min_positive
            self.xMax = result.maximum
        else:
            # Takes the error into account
            if hasattr(xError, 'shape') and len(xError.shape) == 2:
                xErrorPlus, xErrorMinus = xError[0], xError[1]
            else:
                xErrorPlus, xErrorMinus = xError, xError
            result = min_max(xData - xErrorMinus, min_positive=True)
            self.xMin = result.minimum
            self.xMinPos = result.min_positive
            self.xMax = (xData + xErrorPlus).max()

        # Compute y bounds
        if yError is None:
            result = min_max(yData, min_positive=True)
            self.yMin = result.minimum
            self.yMinPos = result.min_positive
            self.yMax = result.maximum
        else:
            # Takes the error into account
            if hasattr(yError, 'shape') and len(yError.shape) == 2:
                yErrorPlus, yErrorMinus = yError[0], yError[1]
            else:
                yErrorPlus, yErrorMinus = yError, yError
            result = min_max(yData - yErrorMinus, min_positive=True)
            self.yMin = result.minimum
            self.yMinPos = result.min_positive
            self.yMax = (yData + yErrorPlus).max()

        self._errorBars = _ErrorBars(xData, yData, xError, yError, self.xMin,
                                     self.yMin)

        kwargs = {'style': lineStyle}
        if lineColor is not None:
            kwargs['color'] = lineColor
        if lineWidth is not None:
            kwargs['width'] = lineWidth
        if lineDashPeriod is not None:
            kwargs['dashPeriod'] = lineDashPeriod
        self.lines = _Lines2D(**kwargs)

        kwargs = {'marker': marker}
        if markerColor is not None:
            kwargs['color'] = markerColor
        if markerSize is not None:
            kwargs['size'] = markerSize
        self.points = _Points2D(**kwargs)