def testRelativePositionLinear(self): self.colorMapLin1 = Colormap(name='gray', normalization=Colormap.LINEAR, vmin=0.0, vmax=1.0) self.colorScaleWidget.setColormap(self.colorMapLin1) self.assertTrue( self.colorScaleWidget.getValueFromRelativePosition(0.25) == 0.25) self.assertTrue( self.colorScaleWidget.getValueFromRelativePosition(0.5) == 0.5) self.assertTrue( self.colorScaleWidget.getValueFromRelativePosition(1.0) == 1.0) self.colorMapLin2 = Colormap(name='viridis', normalization=Colormap.LINEAR, vmin=-10, vmax=0) self.colorScaleWidget.setColormap(self.colorMapLin2) self.assertTrue( self.colorScaleWidget.getValueFromRelativePosition(0.25) == -7.5) self.assertTrue( self.colorScaleWidget.getValueFromRelativePosition(0.5) == -5.0) self.assertTrue( self.colorScaleWidget.getValueFromRelativePosition(1.0) == 0.0)
def testSet(self): colormap = Colormap() other = Colormap(name="viridis", vmin=1, vmax=2, normalization=Colormap.LOGARITHM) self.assertNotEqual(colormap, other) colormap.setFromColormap(other) self.assertIsNot(colormap, other) self.assertEqual(colormap, other)
def testPlotAssocation(self): """Make sure the ColorBarWidget is properly connected with the plot""" colormap = Colormap(name='gray', normalization=Colormap.LINEAR, vmin=None, vmax=None) # make sure that default settings are the same (but a copy of the self.colorBar.setPlot(self.plot) self.assertTrue( self.colorBar.getColormap() is self.plot.getDefaultColormap()) data = numpy.linspace(0, 10, 100).reshape(10, 10) self.plot.addImage(data=data, colormap=colormap, legend='toto') self.plot.setActiveImage('toto') # make sure the modification of the colormap has been done self.assertFalse( self.colorBar.getColormap() is self.plot.getDefaultColormap()) self.assertTrue(self.colorBar.getColormap() is colormap) # test that colorbar is updated when default plot colormap changes self.plot.clear() plotColormap = Colormap(name='gray', normalization=Colormap.LOGARITHM, vmin=None, vmax=None) self.plot.setDefaultColormap(plotColormap) self.assertTrue(self.colorBar.getColormap() is plotColormap)
def testStorageV1(self): state = b'\x00\x00\x00\x10\x00C\x00o\x00l\x00o\x00r\x00m\x00a\x00p\x00\x00'\ b'\x00\x01\x00\x00\x00\x0E\x00v\x00i\x00r\x00i\x00d\x00i\x00s\x00'\ b'\x00\x00\x00\x06\x00?\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ b'\x00\x06\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00'\ b'l\x00o\x00g' state = qt.QByteArray(state) colormap = Colormap() colormap.restoreState(state) expected = Colormap(name="viridis", vmin=1, vmax=2, normalization=Colormap.LOGARITHM) self.assertEqual(colormap, expected)
def _buildPlot(self): image1 = numpy.exp(numpy.random.rand(IMG_WIDTH, IMG_WIDTH) * 10) image2 = numpy.linspace(-100, 1000, IMG_WIDTH * IMG_WIDTH).reshape(IMG_WIDTH, IMG_WIDTH) image3 = numpy.linspace(-1, 1, IMG_WIDTH * IMG_WIDTH).reshape(IMG_WIDTH, IMG_WIDTH) image4 = numpy.linspace(-20, 50, IMG_WIDTH * IMG_WIDTH).reshape(IMG_WIDTH, IMG_WIDTH) image5 = image3 image6 = image4 # viridis colormap self.colormap1 = Colormap.Colormap(name='green', normalization='log', vmin=None, vmax=None) self.plot = PlotWidget(parent=self) self.plot.addImage(data=image1, origin=(0, 0), legend='image1', colormap=self.colormap1) self.plot.addImage(data=image2, origin=(100, 0), legend='image2', colormap=self.colormap1) # red colormap self.colormap2 = Colormap.Colormap(name='red', normalization='linear', vmin=None, vmax=None) self.plot.addImage(data=image3, origin=(0, 100), legend='image3', colormap=self.colormap2) self.plot.addImage(data=image4, origin=(100, 100), legend='image4', colormap=self.colormap2) # gray colormap self.colormap3 = Colormap.Colormap(name='gray', normalization='linear', vmin=1.0, vmax=20.0) self.plot.addImage(data=image5, origin=(0, 200), legend='image5', colormap=self.colormap3) self.plot.addImage(data=image6, origin=(100, 200), legend='image6', colormap=self.colormap3)
def testStorageV2(self): state = b'\x00\x00\x00\x10\x00C\x00o\x00l\x00o\x00r\x00m\x00a\x00p\x00'\ b'\x00\x00\x02\x00\x00\x00\x0e\x00v\x00i\x00r\x00i\x00d\x00i\x00'\ b's\x00\x00\x00\x00\x06\x00?\xf0\x00\x00\x00\x00\x00\x00\x00\x00'\ b'\x00\x00\x06\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06'\ b'\x00l\x00o\x00g\x00\x00\x00\x0c\x00m\x00i\x00n\x00m\x00a\x00x' state = qt.QByteArray(state) colormap = Colormap() colormap.restoreState(state) expected = Colormap(name="viridis", vmin=1, vmax=2, normalization=Colormap.LOGARITHM) expected.setGammaNormalizationParameter(1.5) self.assertEqual(colormap, expected)
def setUp(self): TestCaseQt.setUp(self) self.plot = PlotWindow() self.plot.setAttribute(qt.Qt.WA_DeleteOnClose) self.colormap1 = Colormap(name='blue', vmin=0.0, vmax=1.0, normalization='linear') self.colormap2 = Colormap(name='red', vmin=10.0, vmax=100.0, normalization='log') self.defaultColormap = self.plot.getDefaultColormap() self.plot.getColormapAction()._actionTriggered(checked=True) self.colormapDialog = self.plot.getColormapAction()._dialog self.colormapDialog.setAttribute(qt.Qt.WA_DeleteOnClose)
def testStoreRestore(self): colormaps = [ Colormap(name="viridis"), Colormap(normalization=Colormap.SQRT) ] cmap = Colormap(normalization=Colormap.GAMMA) cmap.setGammaNormalizationParameter(1.2) cmap.setNaNColor('red') colormaps.append(cmap) for expected in colormaps: with self.subTest(colormap=expected): state = expected.saveState() result = Colormap() result.restoreState(state) self.assertEqual(expected, result)
def _onLoadPixmap(self, checked): legend, data = getPixmap() if legend is not None and data.ndim in [2, 3]: item3d = self._sceneGlWindow.getSceneWidget().addImage(data) item3d.setLabel(legend) if not isinstance(item3d, items.ImageRgba): item3d.setColormap(Colormap(name="temperature"))
def testUpdateColorMap(self): colormap = Colormap(name='gray', normalization='linear', vmin=0, vmax=1) # check inital state self.plot.addImage(data=self.data, colormap=colormap, legend='toto') self.plot.setActiveImage('toto') self.assertTrue(self.colorBar.getColorScaleBar().minVal == 0) self.assertTrue(self.colorBar.getColorScaleBar().maxVal == 1) self.assertTrue( self.colorBar.getColorScaleBar().getTickBar()._vmin == 0) self.assertTrue( self.colorBar.getColorScaleBar().getTickBar()._vmax == 1) self.assertIsInstance( self.colorBar.getColorScaleBar().getTickBar()._normalizer, colors._LinearNormalization) # update colormap colormap.setVMin(0.5) self.assertTrue(self.colorBar.getColorScaleBar().minVal == 0.5) self.assertTrue( self.colorBar.getColorScaleBar().getTickBar()._vmin == 0.5) colormap.setVMax(0.8) self.assertTrue(self.colorBar.getColorScaleBar().maxVal == 0.8) self.assertTrue( self.colorBar.getColorScaleBar().getTickBar()._vmax == 0.8) colormap.setNormalization('log') self.assertIsInstance( self.colorBar.getColorScaleBar().getTickBar()._normalizer, colors._LogarithmicNormalization)
def getFreeColorRange(colormap): """ Returns a list of 10 colors in range not covered by colormap. :rtype: List[qt.QColor] """ name = colormap['name'] colormap = Colormap(name) # extract all hues from colormap colors = colormap.getNColors() hues = [] for c in colors: c = qt.QColor.fromRgb(c[0], c[1], c[2]) hues.append(c.hueF()) # search the bigger empty hue range current = (0, 0.0, 0.2) hues = filter(lambda x: x >= 0, set(hues)) hues = list(sorted(hues)) if len(hues) > 1: for i in range(len(hues)): h1 = hues[i] h2 = hues[(i + 1) % len(hues)] if h2 < h1: h2 = h2 + 1.0 diff = h2 - h1 if diff > 0.5: diff = 1.0 - diff if diff > current[0]: current = diff, h1, h2 elif len(hues) == 1: h = (hues[0] + 0.5) % 1.0 current = (0, h - 0.1, h + 0.1) else: pass h1, h2 = current[1:] delta = (h2 - h1) / 6.0 # move the range from the colormap h1, h2 = h1 + delta, h2 - delta hmin = (h1 + h2) / 2.0 # generate colors with 3 hsv control points # (h1, 1, 1), (hmid, 1, 0.5), (h2, 1, 1) colors = [] for i in range(5): h = h1 + (hmin - h1) * (i / 5.0) v = 0.5 + 0.1 * (5 - i) c = qt.QColor.fromHsvF(h % 1.0, 1.0, v) colors.append(c) for i in range(5): h = hmin + (h2 - hmin) * (i / 5.0) v = 0.5 + 0.1 * (i) c = qt.QColor.fromHsvF(h % 1.0, 1.0, v) colors.append(c) return colors
def testAutoscaleFromDataReference(self): colormap = Colormap(name='gray', normalization='linear') data = numpy.array([50]) reference = numpy.array([0, 100]) value = colormap.applyToData(data, reference) self.assertEqual(len(value), 1) self.assertEqual(value[0, 0], 128)
def testColomap(self): dialog = self.createDialog() colormap = dialog.colormap() self.assertEqual(colormap.getNormalization(), "linear") colormap = Colormap(normalization=Colormap.LOGARITHM) dialog.setColormap(colormap) self.assertEqual(colormap.getNormalization(), "log")
def printState(self): """ Print state of the ImageFileDialog. Can be used to add or regenerate `STATE_VERSION1_QT4` or `STATE_VERSION1_QT5`. >>> ./run_tests.py -v silx.gui.dialog.test.test_imagefiledialog.TestImageFileDialogApi.printState """ dialog = self.createDialog() colormap = Colormap(normalization=Colormap.LOGARITHM) dialog.setDirectory("") dialog.setHistory([]) dialog.setColormap(colormap) dialog.setSidebarUrls([]) state = dialog.saveState() string = "" strings = [] for i in range(state.size()): d = state.data()[i] if not isinstance(d, int): d = ord(d) if d > 0x20 and d < 0x7F: string += chr(d) else: string += "\\x%02X" % d if len(string) > 60: strings.append(string) string = "" strings.append(string) strings = ["b'%s'" % s for s in strings] print() print("\\\n".join(strings))
def testSetColormapScenario(self): """Test of a simple scenario of a colormap dialog editing several colormap""" colormap1 = Colormap(name='gray', vmin=10.0, vmax=20.0, normalization='linear') colormap2 = Colormap(name='red', vmin=10.0, vmax=20.0, normalization='log') colormap3 = Colormap(name='blue', vmin=None, vmax=None, normalization='linear') self.colormapDiag.setColormap(self.colormap) self.colormapDiag.setColormap(colormap1) del colormap1 self.colormapDiag.setColormap(colormap2) del colormap2 self.colormapDiag.setColormap(colormap3) del colormap3
def testColormapAutoscaleCache(self): # Test that the min/max cache is not computed twice old = Colormap._computeAutoscaleRange self._count = 0 def _computeAutoscaleRange(colormap, data): self._count = self._count + 1 return 10, 20 Colormap._computeAutoscaleRange = _computeAutoscaleRange try: colormap = Colormap(name='red') self.plot.setVisible(True) # Add an image data = numpy.arange(8**2).reshape(8, 8) self.plot.addImage(data, legend="foo", colormap=colormap) self.plot.setActiveImage("foo") # Use the colorbar self.plot.getColorBarWidget().setVisible(True) self.qWait(50) # Remove and add again the same item image = self.plot.getImage("foo") self.plot.removeImage("foo") self.plot._add(image) self.qWait(50) finally: Colormap._computeAutoscaleRange = old self.assertEqual(self._count, 1) del self._count
def setUp(self): TestCaseQt.setUp(self) ParametricTestCase.setUp(self) self.colormap = Colormap(name='gray', vmin=10.0, vmax=20.0, normalization='linear') self.colormapDiag = ColormapDialog.ColormapDialog()
def _onLoad4DStack(self, checked): # todo: use fileIndex to decide the slicing direction of the cube legend, stackData, xScale, yScale, fileIndex = get4DStack() if legend is None: return origin = [0., 0., 0.] delta = [1., 1., 1.] if xScale is not None: origin[0] = xScale[0] delta[0] = xScale[1] if yScale is not None: origin[1] = yScale[0] delta[1] = yScale[1] # Uncomment this block for a stack of images (may be slow) # group = items.GroupItem() # group.setLabel(legend) # for i in range(stackData.shape[0]): # item3d = items.ImageData() # item3d.setData(stackData[i]) # item3d.setLabel("frame %d" % i) # origin[2] = i # shift each frame by 1 # item3d.setTranslation(*origin) # item3d.setScale(*delta) # group.addItem(item3d) # self._sceneGlWindow.getSceneWidget().addItem(group) item3d = self._sceneGlWindow.getSceneWidget().add3DScalarField( stackData) item3d.setLabel(legend) item3d.setTranslation(*origin) item3d.setScale(*delta) item3d.addIsosurface(mean_isolevel, "blue") for cp in item3d.getCutPlanes(): cp.setColormap(Colormap(name="temperature"))
def testAutoscaleRange(self): nan = numpy.nan data_std_inside = numpy.array([0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2]) data_std_inside_nan = numpy.array([0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, numpy.nan]) data = [ # Positive values (Colormap.LINEAR, Colormap.MINMAX, numpy.array([10, 20, 50]), (10, 50)), (Colormap.LOGARITHM, Colormap.MINMAX, numpy.array([10, 50, 100]), (10, 100)), (Colormap.LINEAR, Colormap.STDDEV3, data_std_inside, (0.026671473215424735, 1.9733285267845753)), (Colormap.LOGARITHM, Colormap.STDDEV3, data_std_inside, (1, 1.6733506885453602)), (Colormap.LINEAR, Colormap.STDDEV3, numpy.array([10, 100]), (10, 100)), (Colormap.LOGARITHM, Colormap.STDDEV3, numpy.array([10, 100]), (10, 100)), # With nan (Colormap.LINEAR, Colormap.MINMAX, numpy.array([10, 20, 50, nan]), (10, 50)), (Colormap.LOGARITHM, Colormap.MINMAX, numpy.array([10, 50, 100, nan]), (10, 100)), (Colormap.LINEAR, Colormap.STDDEV3, data_std_inside_nan, (0.026671473215424735, 1.9733285267845753)), (Colormap.LOGARITHM, Colormap.STDDEV3, data_std_inside_nan, (1, 1.6733506885453602)), # With negative (Colormap.LOGARITHM, Colormap.MINMAX, numpy.array([10, 50, 100, -50]), (10, 100)), (Colormap.LOGARITHM, Colormap.STDDEV3, numpy.array([10, 100, -10]), (10, 100)), ] for norm, mode, array, expectedRange in data: with self.subTest(norm=norm, mode=mode, array=array): colormap = Colormap() colormap.setNormalization(norm) colormap.setAutoscaleMode(mode) vRange = colormap._computeAutoscaleRange(array) if vRange is None: self.assertIsNone(expectedRange) else: self.assertAlmostEqual(vRange[0], expectedRange[0]) self.assertAlmostEqual(vRange[1], expectedRange[1])
def testNotPreferredColormap(self): """Test that the colormapEditor is able to edit a colormap which is not part of the 'prefered colormap' """ def getFirstNotPreferredColormap(): cms = Colormap.getSupportedColormaps() preferred = preferredColormaps() for cm in cms: if cm not in preferred: return cm return None colormapName = getFirstNotPreferredColormap() assert colormapName is not None colormap = Colormap(name=colormapName) self.colormapDiag.setColormap(colormap) self.colormapDiag.show() self.qapp.processEvents() cb = self.colormapDiag._comboBoxColormap self.assertTrue(cb.getCurrentName() == colormapName) cb.setCurrentIndex(0) index = cb.findLutName(colormapName) assert index is not 0 # if 0 then the rest of the test has no sense cb.setCurrentIndex(index) self.assertTrue(cb.getCurrentName() == colormapName)
def restoreSettings(self): """Restore the settings of all the application""" settings = self.__settings if settings is None: return parent = self.__parent() parent.restoreSettings(settings) settings.beginGroup("colormap") byteArray = settings.value("default", None) if byteArray is not None: try: colormap = Colormap() colormap.restoreState(byteArray) self.__defaultColormap = colormap except Exception: _logger.debug("Backtrace", exc_info=True) settings.endGroup() self.__recentFiles = [] settings.beginGroup("recent-files") for index in range(1, 10 + 1): if not settings.contains("path%d" % index): break filePath = settings.value("path%d" % index) self.__recentFiles.append(filePath) settings.endGroup()
def testColormapEditableMode(self): """Test that the colormapDialog is correctly updated when changing the colormap editable status""" colormap = Colormap(normalization='linear', vmin=1.0, vmax=10.0) self.colormapDiag.show() self.qapp.processEvents() self.colormapDiag.setColormap(colormap) for editable in (True, False): with self.subTest(editable=editable): colormap.setEditable(editable) self.assertTrue( self.colormapDiag._comboBoxColormap.isEnabled() is editable ) self.assertTrue( self.colormapDiag._minValue.isEnabled() is editable) self.assertTrue( self.colormapDiag._maxValue.isEnabled() is editable) self.assertTrue( self.colormapDiag._normButtonLinear.isEnabled() is editable ) self.assertTrue( self.colormapDiag._normButtonLog.isEnabled() is editable) # Make sure the reset button is also set to enable when edition mode is # False self.colormapDiag.setModal(False) colormap.setEditable(True) self.colormapDiag._normButtonLog.click() resetButton = self.colormapDiag._buttonsNonModal.button( qt.QDialogButtonBox.Reset) self.assertTrue(resetButton.isEnabled()) colormap.setEditable(False) self.assertFalse(resetButton.isEnabled())
def testNegativeColormaps(self): """test the behavior of the ColorBarWidget in the case of negative values Note : colorbar is modified by the Plot directly not ColorBarWidget """ colormapLog = Colormap(name='gray', normalization=Colormap.LOGARITHM, vmin=None, vmax=None) data = numpy.array([-5, -4, 0, 2, 3, 5, 10, 20, 30]) data = data.reshape(3, 3) self.plot.addImage(data=data, colormap=colormapLog, legend='toto') self.plot.setActiveImage('toto') # default behavior when with log and negative values: should set vmin # to 1 and vmax to 10 self.assertTrue(self.colorBar.getColorScaleBar().minVal == 2) self.assertTrue(self.colorBar.getColorScaleBar().maxVal == 30) # if data is positive data[data < 1] = data.max() self.plot.addImage(data=data, colormap=colormapLog, legend='toto', replace=True) self.plot.setActiveImage('toto') self.assertTrue(self.colorBar.getColorScaleBar().minVal == data.min()) self.assertTrue(self.colorBar.getColorScaleBar().maxVal == data.max())
def generateMagneticField(self): shape = 512 x1 = numpy.random.random() * 2 - 1 y1 = numpy.random.random() * 2 - 1 x2 = numpy.random.random() * 2 - 1 y2 = numpy.random.random() * 2 - 1 image = create_magnetic_field(shape, x1, y1, x2, y2) self.__colormap = Colormap("coolwarm") self.setData(image=image, mask=None) maximum = abs(image.max()) m = abs(image.min()) if m > maximum: maximum = m maximum = int(maximum) values = range(-maximum, maximum, maximum // 20) def styleCallback(value, ivalue, ipolygon): if (ivalue % 2) == 0: style = {"linestyle": "-", "linewidth": 0.5, "color": "black"} else: style = {"linestyle": "-", "linewidth": 0.5, "color": "white"} return style self.__drawContours(values, styleCallback) self.__defineDefaultValues(value=0)
def testColormapWithoutRange(self): """Test with a colormap with vmin==vmax""" colormap = Colormap(name='gray', normalization=Colormap.LINEAR, vmin=1.0, vmax=1.0) self.colorBar.setColormap(colormap)
def __getPixmap(self): if self.__pixmap is not None: return self.__pixmap calibrant = self.__getConfiguredCalibrant() if calibrant is None: return None tths = numpy.array(calibrant.get_2th()) tth_min, tth_max = 0, numpy.pi size = 360 agregation = numpy.zeros((1, size)) for tth in tths: pos = int((tth - tth_min) / (tth_max - tth_min) * size) if pos < 0: continue if pos >= size: continue agregation[0, pos] += 1 agregation = -agregation colormap = Colormap() rgbImage = colormap.applyToData(agregation)[:, :, :3] qimage = imageutils.convertArrayToQImage(rgbImage) qpixmap = qt.QPixmap.fromImage(qimage) self.__pixmap = qpixmap return self.__pixmap
def testVMinVMax(self): """Test getter and setter associated to vmin and vmax values""" vmin = 1.0 vmax = 2.0 colormapObject = Colormap(name='viridis', vmin=vmin, vmax=vmax, normalization=Colormap.LINEAR) with self.assertRaises(ValueError): colormapObject.setVMin(3) with self.assertRaises(ValueError): colormapObject.setVMax(-2) with self.assertRaises(ValueError): colormapObject.setVRange(3, -2) self.assertTrue(colormapObject.getColormapRange() == (1.0, 2.0)) self.assertTrue(colormapObject.isAutoscale() is False) colormapObject.setVRange(None, None) self.assertTrue(colormapObject.getVMin() is None) self.assertTrue(colormapObject.getVMax() is None) self.assertTrue(colormapObject.isAutoscale() is True)
def main(): app = qt.QApplication([]) plot = Plot1D() x = numpy.arange(21) y = numpy.arange(21) plot.addCurve(x=x, y=y, legend='myCurve') plot.addCurve(x=x, y=(y + 5), legend='myCurve2') plot.setActiveCurve('myCurve') plot.addScatter(x=[0, 2, 5, 5, 12, 20], y=[2, 3, 4, 20, 15, 6], value=[5, 6, 7, 10, 90, 20], colormap=Colormap('viridis'), legend='myScatter') stats = [ ('sum', numpy.sum), Integral(), (COM(), '{0:.2f}'), ] plot.getStatsWidget().setStats(stats) plot.getStatsWidget().parent().setVisible(True) plot.show() app.exec_()
def generateCompositeGradient(self): shape = 512 hole = 1 / 4.0 dx = numpy.random.random() * hole - hole / 2.0 dy = numpy.random.random() * hole - hole * 2 sx = numpy.random.random() * 10.0 + 1 sy = numpy.random.random() * 10.0 + 1 image = create_composite_gradient(shape, dx, dy, sx, sy) image *= 1000.0 def styleCallback(value, ivalue, ipolygon): colors = [ "#9400D3", "#4B0082", "#0000FF", "#00FF00", "#FFFF00", "#FF7F00", "#FF0000" ] color = colors[ivalue % len(colors)] style = {"linestyle": "-", "linewidth": 2.0, "color": color} return style delta = (image.max() - image.min()) / 9.0 values = numpy.arange(image.min(), image.max(), delta) values = values[1:8] self.__colormap = Colormap("Greys") self.setData(image=image, mask=None) self.__drawContours(values, styleCallback) self.__defineDefaultValues()
def testAutoscaleRange(self): nan = numpy.nan data = [ # Positive values (Colormap.LINEAR, Colormap.MINMAX, numpy.array([10, 20, 50]), (10, 50)), (Colormap.LOGARITHM, Colormap.MINMAX, numpy.array([10, 50, 100]), (10, 100)), (Colormap.LINEAR, Colormap.STDDEV3, numpy.array([10, 100]), (-80, 190)), (Colormap.LOGARITHM, Colormap.STDDEV3, numpy.array([10, 100]), (1, 1000)), # With nan (Colormap.LINEAR, Colormap.MINMAX, numpy.array([10, 20, 50, nan]), (10, 50)), (Colormap.LOGARITHM, Colormap.MINMAX, numpy.array([10, 50, 100, nan]), (10, 100)), (Colormap.LINEAR, Colormap.STDDEV3, numpy.array([10, 100, nan]), (-80, 190)), (Colormap.LOGARITHM, Colormap.STDDEV3, numpy.array([10, 100, nan]), (1, 1000)), # With negative (Colormap.LOGARITHM, Colormap.MINMAX, numpy.array([10, 50, 100, -50]), (10, 100)), (Colormap.LOGARITHM, Colormap.STDDEV3, numpy.array([10, 100, -10]), (1, 1000)), ] for norm, mode, array, expectedRange in data: with self.subTest(norm=norm, mode=mode, array=array): colormap = Colormap() colormap.setNormalization(norm) colormap.setAutoscaleMode(mode) vRange = colormap._computeAutoscaleRange(array) if vRange is None: self.assertIsNone(expectedRange) else: self.assertEqual(vRange[0], expectedRange[0]) self.assertEqual(vRange[1], expectedRange[1])