def test_badargs(): testcases = [ dict(cmap='badcmap'), dict(orientation='badorient'), dict(labelside='badside'), dict(ticks=[0, 0.5, 1], ticklabels=['l', 'l', 'l'], tickalign=['badalign', 'badalign', 'badalign']), ] # bad colour map for t in testcases: with pytest.raises(Exception): cbarbmp.colourBarBitmap(t.get('cmap', 'Reds'), 50, 50, **t)
def test_negCmap_invert(): # cmap, negCmap, invert, orientation testcases = [ ('Reds', None, False, 'vertical'), ('Reds', None, False, 'horizontal'), ('Reds', None, True, 'vertical'), ('Reds', None, True, 'horizontal'), ('Reds', 'Blues', False, 'vertical'), ('Reds', 'Blues', False, 'horizontal'), ('Reds', 'Blues', True, 'vertical'), ('Reds', 'Blues', True, 'horizontal') ] size = 100, 25 for cmap, negCmap, invert, orient in testcases: fname = '_'.join(map(str, [cmap, negCmap, invert, orient])) fname = 'negCmap_invert_{}.png'.format(fname) if orient == 'vertical': height, width = size else: width, height = size bmp = cbarbmp.colourBarBitmap(cmap, width, height, negCmap=negCmap, invert=invert, orientation=orient) assert _compare(bmp, fname)
def test_label_and_ticks(): orientations = ['horizontal', 'vertical'] labelsides = ['top', 'bottom'] fontsizes = [6, 10, 16] testcases = it.product(orientations, labelsides, fontsizes) ticks = [0.2, 0.5, 0.8] ticklabels = [str(t) for t in ticks] label = 'Label' for orient, side, size, in testcases: if orient[0] == 'v': width, height = 100, 300 else: width, height = 300, 100 bmp = cbarbmp.colourBarBitmap('Reds', width, height, ticks=ticks, ticklabels=ticklabels, label=label, orientation=orient, labelside=side, fontsize=size, textColour=(0, 0, 0.2, 1)) fname = '_'.join([orient, side, str(size)]) fname = 'label_and_ticks_{}.png'.format(fname) assert _compare(bmp, fname)
def test_negCmap_ticks(): testcases = [ ('Reds', 'Blues', [0, 1]), ('Reds', 'Blues', [0, 0.5, 1]), ('Reds', 'Blues', [0, 0.49, 0.51, 1]), ('Reds', 'Blues', [0, 0.25, 0.5, 0.75, 1]) ] for cmap, negCmap, ticks in testcases: fname = '_'.join(map(str, [cmap, negCmap] + ticks)) fname = 'negCmap_invert_ticks_{}.png'.format(fname) ticklabels = ['{:0.2f}'.format(t) for t in ticks] tickalign = ['left'] + ['center'] * (len(ticks) - 2) + ['right'] bmp = cbarbmp.colourBarBitmap(cmap, 800, 100, fontsize=30, negCmap=negCmap, orientation='horizontal', ticks=ticks, tickalign=tickalign, ticklabels=ticklabels) assert _compare(bmp, fname)
def test_label(): orientations = ['horizontal', 'vertical'] labelsides = ['top', 'bottom', 'left', 'right'] fontsizes = [6, 10, 16] textcolours = [(0, 0, 0, 1), (1, 0, 0, 1)] testcases = it.product(orientations, labelsides, fontsizes, textcolours) for orient, side, size, colour in testcases: if orient[0] == 'v': width, height = 100, 300 else: width, height = 300, 100 bmp = cbarbmp.colourBarBitmap('Reds', width, height, label='Label', orientation=orient, labelside=side, fontsize=size, textColour=colour) fname = '_'.join(map(str, [orient, side, size] + list(colour))) fname = 'label_{}.png'.format(fname) assert _compare(bmp, fname)
def test_scale(): scales = [0.5, 1.0, 2.0, 3.0] orientations = ['horizontal', 'vertical'] labelsides = ['top', 'bottom'] testcases = it.product(scales, orientations, labelsides) ticks = [0.1, 0.9] ticklabels = [str(t) for t in ticks] label = 'Label' for scale, orient, side in testcases: if orient[0] == 'v': width, height = 100, 300 else: width, height = 300, 100 bmp = cbarbmp.colourBarBitmap('Reds', width, height, ticks=ticks, ticklabels=ticklabels, label=label, orientation=orient, labelside=side, scale=scale, textColour=(0, 0, 0.2, 1)) fname = '_'.join([str(scale), orient, side]) fname = 'scale_{}.png'.format(fname) assert _compare(bmp, fname)
def test_gamma(): gammas = [0.5, 1.0, 2.0, 3.0] inverts = [False, True] negCmaps = [False, True] cmaps = [('Greys', 'Greys'), ('Reds', 'Blues')] width, height = 100, 25 testcases = it.product(gammas, inverts, negCmaps, cmaps) for gamma, invert, useNegCmap, cmap in testcases: cmap, negCmap = cmap if not useNegCmap: negCmap = None fname = '_'.join(map(str, [gamma, invert, cmap, negCmap])) fname = 'gamma_{}.png'.format(fname) bmp = cbarbmp.colourBarBitmap(cmap, width, height, invert=invert, orientation='horizontal', gamma=gamma, negCmap=negCmap) assert _compare(bmp, fname)
def test_standard_usage(): cmaps = ['Greys', 'Blues'] sizes = [(100, 25)] cmapResolutions = [6, 256] orientations = ['vertical', 'horizontal'] alphas = [0.25, 1.0] bgColours = [(0, 0, 0, 0), (0, 0, 0, 1), (1, 0, 0, 1)] testcases = it.product(cmaps, sizes, cmapResolutions, orientations, alphas, bgColours) for testcase in testcases: cmap, size, cmapRes, orient, alpha, bgColour = testcase if orient == 'vertical': height, width = size else: width, height = size bmp = cbarbmp.colourBarBitmap(cmap, width, height, cmapResolution=cmapRes, alpha=alpha, orientation=orient, bgColour=bgColour) fname = '_'.join(map(str, [ cmap, cmapRes, orient, alpha] + list(bgColour))) fname = 'standard_usage_{}.png'.format(fname) assert _compare(bmp, fname)
def test_ticks(): orientations = ['horizontal', 'vertical'] labelsides = ['top', 'bottom', 'left', 'right'] fontsizes = [6, 10, 16] textcolours = [(0, 0, 0, 1), (1, 0, 0, 1)] tickss = [[0.0, 0.25, 0.75, 1.0], [0.25, 0.75]] testcases = it.product(orientations, labelsides, fontsizes, textcolours, tickss) for orient, side, size, colour, ticks in testcases: labels = [str(t) for t in ticks] if orient[0] == 'v': width, height = 100, 300 else: width, height = 300, 100 bmp = cbarbmp.colourBarBitmap('Reds', width, height, ticks=ticks, ticklabels=labels, orientation=orient, labelside=side, fontsize=size, textColour=colour) fname = [orient, side, size] + list(colour) + labels fname = '_'.join(map(str, fname)) fname = 'ticks_{}.png'.format(fname) assert _compare(bmp, fname)
def test_tickalign(): orientations = ['horizontal', 'vertical'] labelsides = ['top', 'bottom'] ticks = [0.0, 0.25, 0.5, 0.75, 1.0] ticklabels = [str(t) for t in ticks] tickaligns = [ ['left' for t in ticks], ['right' for t in ticks], ['center' for t in ticks], ['left', 'center', 'center', 'center', 'right']] testcases = it.product(orientations, labelsides, tickaligns) for orient, side, align in testcases: if orient[0] == 'v': width, height = 100, 300 else: width, height = 300, 100 bmp = cbarbmp.colourBarBitmap('Blues', width, height, ticks=ticks, ticklabels=ticklabels, tickalign=align, orientation=orient, labelside=side, textColour=(0, 0, 0, 1)) falign = ''.join([a[0] for a in align]) fname = '_'.join([orient, side, falign]) fname = 'tickalign_{}.png'.format(fname) assert _compare(bmp, fname)
def colourBar(self, w, h, scale=1): """Returns a bitmap containing the rendered colour bar, rendering it if necessary. :arg w: Width in pixels :arg h: Height in pixels :arg scale: DPI scaling factor, if applicable. """ if self.__opts is None: return None if w < 20: w = 20 if h < 20: h = 20 if (w, h, scale) == self.__size and self.__colourBar is not None: return self.__colourBar display = self.__display opts = self.__opts cmap = opts.cmap negCmap = opts.negativeCmap useNegCmap = opts.useNegativeCmap cmapResolution = opts.cmapResolution gamma = opts.realGamma(opts.gamma) invert = opts.invert dmin, dmax = opts.displayRange.x label = display.name if self.orientation == 'horizontal': if self.labelSide == 'top-left': labelSide = 'top' else: labelSide = 'bottom' else: if self.labelSide == 'top-left': labelSide = 'left' else: labelSide = 'right' if useNegCmap and dmin == 0.0: ticks = [0.0, 0.5, 1.0] ticklabels = ['{:0.3G}'.format(-dmax), '{:0.3G}'.format( dmin), '{:0.3G}'.format( dmax)] tickalign = ['left', 'center', 'right'] elif useNegCmap: ticks = [0.0, 0.49, 0.51, 1.0] ticklabels = ['{:0.3G}'.format(-dmax), '{:0.3G}'.format(-dmin), '{:0.3G}'.format( dmin), '{:0.3G}'.format( dmax)] tickalign = ['left', 'right', 'left', 'right'] else: negCmap = None ticks = [0.0, 1.0] tickalign = ['left', 'right'] ticklabels = ['{:0.3G}'.format(dmin), '{:0.3G}'.format(dmax)] ticks = np.array(ticks) ticks[np.isclose(ticks , 0)] = 0 if not self.showLabel: label = None if not self.showTicks: ticks = None ticklabels = None bitmap = cbarbmp.colourBarBitmap( cmap=cmap, negCmap=negCmap, invert=invert, gamma=gamma, ticks=ticks, ticklabels=ticklabels, tickalign=tickalign, width=w, height=h, label=label, scale=scale, orientation=self.orientation, labelside=labelSide, textColour=self.textColour, fontsize=self.fontSize, bgColour=self.bgColour, cmapResolution=cmapResolution) self.__size = (w, h, scale) self.__colourBar = bitmap return bitmap
def buildColourBarBitmap(overlayList, displayCtx, width, height, cbarLocation, cbarLabelSide, bgColour, fgColour): """If the currently selected overlay has a display range, creates and returns a bitmap containing a colour bar. Returns ``None`` otherwise. :arg overlayList: The :class:`.OverlayList`. :arg displayCtx: The :class:`.DisplayContext`. :arg width: Colour bar width in pixels. :arg height: Colour bar height in pixels. :arg cbarLocation: One of ``'top'``, ``'bottom'``, ``'left'``, or ``'right'``. :arg cbarLabelSide: One of ``'top-left'`` or ``'bottom-right'``. :arg bgColour: RGBA background colour. :arg fgColour: RGBA foreground (text) colour. """ overlay = displayCtx.getSelectedOverlay() display = displayCtx.getDisplay(overlay) opts = display.opts if not isinstance(opts, displaycontext.ColourMapOpts): return None if cbarLocation in ('top', 'bottom'): orient = 'horizontal' elif cbarLocation in ('left', 'right'): orient = 'vertical' if cbarLabelSide == 'top-left': if orient == 'horizontal': labelSide = 'top' else: labelSide = 'left' elif cbarLabelSide == 'bottom-right': if orient == 'horizontal': labelSide = 'bottom' else: labelSide = 'right' if opts.useNegativeCmap: negCmap = opts.negativeCmap ticks = [0.0, 0.49, 0.51, 1.0] ticklabels = [ '{:0.2f}'.format(-opts.displayRange.xhi), '{:0.2f}'.format(-opts.displayRange.xlo), '{:0.2f}'.format(opts.displayRange.xlo), '{:0.2f}'.format(opts.displayRange.xhi) ] tickalign = ['left', 'right', 'left', 'right'] else: negCmap = None ticks = [0.0, 1.0] tickalign = ['left', 'right'] ticklabels = [ '{:0.2f}'.format(opts.displayRange.xlo), '{:0.2f}'.format(opts.displayRange.xhi) ] cbarBmp = cbarbitmap.colourBarBitmap(cmap=opts.cmap, width=width, height=height, negCmap=negCmap, invert=opts.invert, ticks=ticks, ticklabels=ticklabels, tickalign=tickalign, label=display.name, orientation=orient, labelside=labelSide, bgColour=bgColour, textColour=fgColour, cmapResolution=opts.cmapResolution) # The colourBarBitmap function returns a w*h*4 # array, but the fsleyes_widgets.utils.layout.Bitmap # (see the next function) assumes a h*w*4 array cbarBmp = cbarBmp.transpose((1, 0, 2)) return cbarBmp
def _genColourBarTexture(self): """Generates a texture containing an image of the colour bar, according to the current property values. """ if not self._setGLContext(): return w, h = self.GetSize() if w < 50 or h < 50: return if self.orientation == 'horizontal': if self.labelSide == 'top-left': labelSide = 'top' else: labelSide = 'bottom' else: if self.labelSide == 'top-left': labelSide = 'left' else: labelSide = 'right' if self.cmap is None: bitmap = np.zeros((w, h, 4), dtype=np.uint8) else: if self.useNegativeCmap: negCmap = self.negativeCmap ticks = [0.0, 0.49, 0.51, 1.0] ticklabels = [ '{:0.2f}'.format(-self.vrange.xhi), '{:0.2f}'.format(-self.vrange.xlo), '{:0.2f}'.format(self.vrange.xlo), '{:0.2f}'.format(self.vrange.xhi) ] tickalign = ['left', 'right', 'left', 'right'] else: negCmap = None ticks = [0.0, 1.0] tickalign = ['left', 'right'] ticklabels = [ '{:0.2f}'.format(self.vrange.xlo), '{:0.2f}'.format(self.vrange.xhi) ] bitmap = cbarbmp.colourBarBitmap( cmap=self.cmap, negCmap=negCmap, invert=self.invert, ticks=ticks, ticklabels=ticklabels, tickalign=tickalign, width=w, height=h, label=self.label, orientation=self.orientation, labelside=labelSide, textColour=self.textColour, cmapResolution=self.cmapResolution) if self._tex is None: self._tex = textures.Texture2D( '{}_{}'.format(type(self).__name__, id(self)), gl.GL_LINEAR) # The bitmap has shape W*H*4, but the # Texture2D instance needs it in shape # 4*W*H bitmap = np.fliplr(bitmap).transpose([2, 0, 1]) self._tex.setData(bitmap) self._tex.refresh()