Skip to main content
`Ctrl`+`K`

# Source code for pyqtgraph.widgets.ColorMapMenu

    import collections
    import importlib.util
    import re

    from .. import colormap
    from ..graphicsItems.GradientPresets import Gradients
    from ..Qt import QtCore, QtGui, QtWidgets

    __all__ = ['ColorMapMenu']

    # from https://matplotlib.org/stable/gallery/color/colormap_reference.html
    MATPLOTLIB_CMAPS = [
             ('Perceptually Uniform Sequential', [
                'viridis', 'plasma', 'inferno', 'magma', 'cividis']),
             ('Sequential', [
                'Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
                'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
                'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn']),
             ('Sequential (2)', [
                'binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink',
                'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia',
                'hot', 'afmhot', 'gist_heat', 'copper']),
             ('Diverging', [
                'PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu',
                'RdYlBu', 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic']),
             ('Cyclic', ['twilight', 'twilight_shifted', 'hsv']),
             ('Qualitative', [
                'Pastel1', 'Pastel2', 'Paired', 'Accent',
                'Dark2', 'Set1', 'Set2', 'Set3',
                'tab10', 'tab20', 'tab20b', 'tab20c']),
             ('Miscellaneous', [
                'flag', 'prism', 'ocean', 'gist_earth', 'terrain', 'gist_stern',
                'gnuplot', 'gnuplot2', 'CMRmap', 'cubehelix', 'brg',
                'gist_rainbow', 'rainbow', 'jet', 'turbo', 'nipy_spectral',
                'gist_ncar'])
        ]

    PrivateActionData = collections.namedtuple("ColorMapMenuPrivateActionData", ["name", "source"])

    def buildMenuEntryWidget(cmap, text):
        lut = cmap.getLookupTable(nPts=32, alpha=True)
        qimg = QtGui.QImage(lut, len(lut), 1, QtGui.QImage.Format.Format_RGBA8888)
        pixmap = QtGui.QPixmap.fromImage(qimg)

        widget = QtWidgets.QWidget()
        layout = QtWidgets.QHBoxLayout(widget)
        layout.setContentsMargins(1,1,1,1)
        label1 = QtWidgets.QLabel()
        label1.setScaledContents(True)
        label1.setPixmap(pixmap)
        label2 = QtWidgets.QLabel(text)
        layout.addWidget(label1, 0)
        layout.addWidget(label2, 1)

        return widget

    def buildMenuEntryAction(menu, name, source):
        if isinstance(source, colormap.ColorMap):
            cmap = source
        elif source == 'preset-gradient':
            cmap = preset_gradient_to_colormap(name)
        else:
            cmap = colormap.get(name, source=source)
        act = QtWidgets.QWidgetAction(menu)
        act.setData(PrivateActionData(name, source))
        act.setDefaultWidget(buildMenuEntryWidget(cmap, name))
        menu.addAction(act)

    def sorted_filenames(names):
        pattern = re.compile(r'(\d+)')
        key = lambda x: [int(c) if c.isdigit() else c for c in pattern.split(x)]
        return sorted(names, key=key)

    def find_mpl_leftovers():
        names = colormap.listMaps(source="matplotlib")
        # remove entries registered by colorcet
        names = [x for x in names if not x.startswith('cet_')]
        # remove the reversed colormaps
        names = [x for x in names if not x.endswith('_r')]
        # remove entries that are already categorised
        known_names = set()
        for item in MATPLOTLIB_CMAPS:
            known_names.update(item[1])
        names = [x for x in names if x not in known_names]
        return names

    def buildCetSubMenu(menu, source, cet_type):
        names = colormap.listMaps(source=source)
        names = [x for x in names if x.startswith("CET")]

        if cet_type.endswith("Blind"):
            names = [x for x in names if x[4:6] == "CB"]
        else:
            names = [x for x in names if x[4] == cet_type[0] and x[5].isdigit()]

        for name in sorted_filenames(names):
            buildMenuEntryAction(menu, name, source)

    def buildUserSubMenu(menu, userList):
        for item in userList:
            if isinstance(item, colormap.ColorMap):
                name, source = item.name, item
            elif isinstance(item, str):
                name, source = item, None
            elif isinstance(item, tuple):
                name, source = item
            else:
                raise ValueError("userList items must be ColorMap, str or tuple")

            buildMenuEntryAction(menu, name, source)

    def preset_gradient_to_colormap(name):
        # generate the hsv two gradients using makeHslCycle
        if name == 'spectrum':
            # steps=30 for 300 degrees gives the same density as
            # the default steps=36 for 360 degrees
            cmap = colormap.makeHslCycle((0, 300/360), steps=30)
        elif name == 'cyclic':
            cmap = colormap.makeHslCycle((1, 0))
        else:
            cmap = colormap.ColorMap(*zip(*Gradients[name]["ticks"]), name=name)
        return cmap