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)
예제 #11
0
    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
예제 #12
0
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
예제 #13
0
    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()