Exemple #1
0
def color_translator(**kw):
    """
    Translates colors specified in the Matplotlib system into pyqtgraph color descriptions

    :param kw: dict
        Dictionary of Matplotlib style plot keywords in which color may be specified. The entire set of mpl plot
        keywords may be passed in, although only color-relevant ones will be used.

    :return: iterable
        An RGBA color description (each from 0 to 255) for use with pyqtgraph
    """
    if 'color' in kw and kw['color'] is not None:
        try:
            printd(
                '    color_translator input: kw["color"] = {}, to_rgba(kw.get("color", None)) = {}'
                .format(kw.get('color', None), to_rgba(kw.get('color', None))),
                level=3)
        except ValueError:
            printd('    color_translator input: kw["color"] = {}'.format(
                kw.get('color', None)),
                   level=3)
        if kw['color'] in ['', ' ']:
            return 0, 0, 0, 0  # Empty strings and spaces are code for invisible (alpha = 0)
        elif 'alpha' in kw and kw['alpha'] is not None:
            return np.append(np.array(to_rgba(kw['color']))[0:3],
                             kw['alpha']) * 255
        else:
            return np.array(to_rgba(kw['color'])) * 255
    else:
        return (0, 0, 0, int(
            round(kw['alpha'] *
                  255))) if 'alpha' in kw and kw['alpha'] is not None else None
Exemple #2
0
    def plot(self, *args, **kwargs):
        """
        Translates arguments and keywords to matplotlib.axes.Axes.plot() method so they can be passed to
        pg.PlotItem.plot() instead.

        See https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.plot.html

        :param args: Plot arguments
            They will be passed straight through to plot()

        :param kwargs: Plot keywords
            They will be translated from mpl to pg conventions and then passed to plot()

        :return: plotItem instance returned by pg.PlotItem.plot()
        """
        need_cycle = any(
            [k not in kwargs.keys() for k in self.prop_cycle.keys])
        if need_cycle:
            printd('keys needed', list(self.prop_cycle.keys), level=2)
            cur = self.cyc
            for k in self.prop_cycle.keys:
                if k not in kwargs.keys():
                    kwargs[str(k)] = cur[self.prop_cycle_index][k]
                    printd('kwargs["{}"] = {}'.format(k, kwargs[str(k)]),
                           level=2)
            self.prop_cycle_index += 1
            if self.prop_cycle_index > len(self.prop_cycle):
                self.prop_cycle_index = 0
        return super(Axes, self).plot(*args, **plotkw_translator(**kwargs))
Exemple #3
0
 def clear(self):
     """Removes the legend from Axes instance"""
     printd('  Clearing legend {}...'.format(self.leg))
     try:
         self.leg.scene().removeItem(self.leg)  # https://stackoverflow.com/a/42794442/6605826
     except AttributeError:
         printd('  Could not clear legend (maybe it is already invisible?')
Exemple #4
0
 def window_closed(self, win):
     if win in self.open_windows:
         printd('  tracker detected window closed: {}'.format(win))
         self.open_windows.remove(win)
     else:
         warnings.warn(
             '  tracker received notification of closing of untracked window!'
         )
     self.status()
Exemple #5
0
    def clear(self):
        """
        Clears the axes

        https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.clear.html
        """
        printd('  Clearing Axes instance {}...'.format(self))
        super(Axes, self).clear()
        self.legend.clear()
        self.prop_cycle_index = 0
Exemple #6
0
 def closeEvent(self, event):
     """
     Intercepts window closing events and updates window tracker
     Not an imitation of matplotlib, but used for interfacing with pyqtgraph behavior
     :param event: window closing event
     """
     printd('window closing')
     tracker.window_closed(self)
     event.accept()
     return
Exemple #7
0
    def contourf(self, *args, **kwargs):
        """
        Initializes a QuadContourSet instance for the current Axes with filled=True enforced

        https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.contourf.html

        :return: QuadContourSet instance
        """
        printd('  pgmpl.axes.Axes.contourf()...')
        kwargs['filled'] = True
        return QuadContourSet(self, *args, **kwargs)
Exemple #8
0
 def handle_info(handles, comment=None):
     """For debugging: prints information on legend handles"""
     if comment is not None:
         printd(comment)
     for i, handle in enumerate(tolist(handles)):
         printd('  {i:02d} handle name: {name:}, class: {cls:}, isVisible: {isvis:}'.format(
             i=i,
             name=getattr(handle, 'name', None),
             cls=getattr(handle, '__class__', ' not found '),
             isvis=getattr(handle, 'isVisible', None),
         ))
Exemple #9
0
def color_map_translator(x, **kw):
    """
    Translates colors for a matplotlib colormap and a dataset, such as would be used for scatter, imshow, contour, etc.

    :param x: numeric scalar or iterable
        Data to be mapped. Very boring if scalar.

    :param cmap: string
        Color map nape, passed to matplotlib.cm.get_cmap()

    :param norm: matplotlib normalization class
        Defaults to new instance of mpl.colors.Normalize

    :param vmin: numeric
        Lower limit passed to new Normalize instance if norm is None; ignored if norm is provided.

    :param vmax: numeric
        Lower limit passed to new Normalize instance if norm is None; ignored if norm is provided.

    :param clip: bool
        Passed to Normalize if a new Normalize instance is created. Otherwise, not used.

    :param ncol: int
        passed to Colormap to set number of colors

    :param alpha: float:
        opacity from 0 to 1 or None

    :return: list
        List of pyqtgraph-compatible color specifications with length matching x
    """
    printd('color_map_translator...')
    norm = kw.pop('norm', None)
    if norm is None:
        printd('  norm was None, normalizing...')
        norm = Normalize(vmin=kw.pop('vmin', None),
                         vmax=kw.pop('vmax', None),
                         clip=kw.pop('clip', False))
    comap = matplotlib.cm.get_cmap(kw.pop('cmap', None),
                                   lut=kw.pop('ncol', 256))
    colors = comap(norm(np.atleast_1d(x)))
    return [
        color_translator(color=color, alpha=kw.get('alpha', None))
        for color in tolist(colors)
    ]
Exemple #10
0
    def __call__(self, handles=None, labels=None, **kw):
        """
        Adds a legend to the plot axes. This class should be added to axes as they are created so that calling it acts
        like a method of the class and adds a legend, imitating matplotlib legend calling.
        """
        printd('  custom legend call')
        self.leg = self.ax.addLegend()
        # ax.addLegend modifies ax.legend, so we have to put it back in order to
        # preserve a reference to pgmpl.axes.Legend.
        self.ax.legend = self

        handles = tolist(handles if handles is not None else self.get_visible_handles())

        for handle, label in zip(*self._cleanup_legend_labels(handles, labels)):
            if self.supported(handle):
                self.leg.addItem(handle, label)

        self.check_call_kw(**kw)

        return self
Exemple #11
0
 def test_printd(self):
     test_string_1 = '\nthis string should print, but the other string should not'
     test_string_2 = '\nthis string should NOT print, but the other string SHOULD'
     debug = os.environ.get('PGMPL_DEBUG', "0")
     os.environ['PGMPL_DEBUG'] = "1"
     printd(test_string_1)
     printd('this-should-print:', 'test-item-1a',
            'test_item_2a_in-list-of-things', 5, 6,
            'more-things-in-the-list')
     os.environ['PGMPL_DEBUG'] = "0"
     printd(test_string_2)
     printd('SHOULD-NOT-PRINT:', 'test-item-1b',
            'testitem2b-in-a-listofthings', 5, 6.1, 'morelistlol', 'blah')
     os.environ['PGMPL_DEBUG'] = debug  # Put it back how it was (polite~~)
Exemple #12
0
    def _setup_fill_between_colors(**kwargs):
        """
        Prepares edge plotting keywords and brush for fill_between
        :param kwargs: dictionary of keywords from fill_between
        :return: dict, brush
        """
        # Set up colors and display settings
        ekw = copy.deepcopy(kwargs)
        ekw['color'] = ekw.pop('edgecolor', ekw.pop('color', 'k'))

        if 'facecolor' in kwargs:
            brush = color_translator(color=kwargs['facecolor'],
                                     alpha=kwargs.get('alpha', None))
        elif 'color' in kwargs:
            brush = color_translator(color=kwargs['color'],
                                     alpha=kwargs.get('alpha', None))
        else:
            brush = color_translator(color='b',
                                     alpha=kwargs.get('alpha', None))
        printd(
            '  pgmpl.axes.Axes.fill_between(): brush = {}, ekw = {}, setup_pen_kw(**ekw) = {}'
            .format(brush, ekw, setup_pen_kw(**ekw)))
        return ekw, brush
Exemple #13
0
    def __init__(self, ax, **kw):

        self.check_kw(**kw)
        self.orientation = kw.pop('orientation', 'vertical')

        printd(
            'ColorbarBase.__init__: mappable.vmin = {}, mappable.vmax = {}, '
            'orientation = {}'.format(self.mappable.vmin, self.mappable.vmax,
                                      self.orientation))
        a = np.linspace(0, 1, 256).reshape(256, 1)
        if self.orientation == 'horizontal':
            ylim = [0, 1]
            xlim = [self.mappable.vmin, self.mappable.vmax]
            a = a.T
            show_ax = 'bottom'
        else:
            xlim = [0, 1]
            ylim = [self.mappable.vmin, self.mappable.vmax]
            show_ax = 'right'
        extent = tuple(xlim + ylim)
        ax.imshow(
            a,
            cmap=kw.get('cmap', None),
            norm=kw.get('norm', None),
            alpha=kw.get('alpha', None),
            origin='lower',
            extent=extent,
        )
        ax.set_ylim(ylim)
        ax.set_xlim(xlim)
        for ax_side in ['top', 'bottom', 'right', 'left']:
            if ax_side == show_ax:
                ax.showAxis(ax_side)
            else:
                ax.hideAxis(ax_side)
        ax.setLabel(show_ax, text=kw.get('label', ''))
        ax.setMouseEnabled(x=False, y=False)
Exemple #14
0
    def _setup_fill_between_where(x, **kwargs):
        """
        Handles where and interpolate keywords
        :param x: x values
        :param kwargs: dictionary of keywords received by fill_between
        :return: tuple with two lists of ints giving start and end indices for each segment of data passing where
        """
        if kwargs.get('where', None) is not None:
            if kwargs.pop('interpolate', False):
                warnings.warn(
                    'Warning: interpolate keyword to fill_between is not handled yet.'
                )
            d = np.diff(np.append(0, kwargs['where']))
            start_i = np.where(d == 1)[0]
            end_i = np.where(d == -1)[0]
            if len(end_i) < len(start_i):
                end_i = np.append(end_i, len(d))
            printd('  fill_between where: start_i = {}, end_i = {}'.format(
                start_i, end_i))

        else:
            start_i = [0]
            end_i = [len(x)]
        return start_i, end_i
Exemple #15
0
from pyqtgraph import QtGui

# Plotting imports
import pyqtgraph as pg
from matplotlib import rcParams

# pgmpl imports
from pgmpl.info import *  # Defines __version__, etc.
from pgmpl.util import printd
from pgmpl.translate import color_translator

__all__ = ['figure', 'axes', 'pyplot', 'translate', 'text', 'util']

# Handle debugging
if os.environ.get('PGMPL_DEBUG', None) is None:
    os.environ['PGMPL_DEBUG'] = "0"

# Setup style, etc.
pg.setConfigOption('background',
                   color_translator(**{'color': rcParams['axes.facecolor']}))
pg.setConfigOption('foreground',
                   color_translator(**{'color': rcParams['axes.edgecolor']}))

# Check for an existing QApp and make one if none found so that windows can be opened
app = QtGui.QApplication.instance()
if app is None:
    printd('No pre-existing QApplication found. Creating one...')
    app = QtGui.QApplication(sys.argv)
else:
    printd('Using pre-existing QApplication.')
Exemple #16
0
 def status(self):
     printd('  {} tracked windows = {}'.format(len(self.open_windows),
                                               self.open_windows))
Exemple #17
0
 def window_opened(self, win):
     printd('  tracker detected new window opened: {}'.format(win))
     self.open_windows += [win]
     self.status()
Exemple #18
0
 def __init__(self, ax, mappable, **kw):
     printd('pgmpl.colorbar.Colorbar.__init__()...')
     self.mappable = mappable
     kw['cmap'] = mappable.cmap
     kw['norm'] = mappable.norm
     super(Colorbar, self).__init__(ax, **kw)