Source code for glue.core.visual

from __future__ import absolute_import, division, print_function

from glue.config import settings
from glue.external.echo import callback_property
from glue.external import six

# Define acceptable line styles
VALID_LINESTYLES = ['solid', 'dashed', 'dash-dot', 'dotted', 'none']

__all__ = ['VisualAttributes']


[docs]class VisualAttributes(object): ''' This class is used to define visual attributes for any kind of objects The essential attributes of a VisualAttributes instance are: :param color: A matplotlib color string :param alpha: Opacity (0-1) :param linewidth: The linewidth (float or int) :param linestyle: The linestyle (``'solid' | 'dashed' | 'dash-dot' | 'dotted' | 'none'``) :param marker: The matplotlib marker shape (``'o' | 's' | '^' | etc``) :param markersize: The size of the marker (int) ''' def __init__(self, parent=None, washout=False, color=settings.DATA_COLOR): self.parent = parent self._atts = ['color', 'alpha', 'linewidth', 'linestyle', 'marker', 'markersize'] self.color = color self.alpha = 0.5 self.linewidth = 1 self.linestyle = 'solid' self.marker = 'o' self.markersize = 3 def __eq__(self, other): if not isinstance(other, VisualAttributes): return False elif self is other: return True else: return all(getattr(self, a) == getattr(other, a) for a in self._atts) # In Python 3, if __eq__ is defined, then __hash__ has to be re-defined if six.PY3: __hash__ = object.__hash__
[docs] def set(self, other): """ Update this instance's properties based on another VisualAttributes instance. """ for att in self._atts: setattr(self, att, getattr(other, att))
[docs] def copy(self, new_parent=None): """ Create a new instance with the same visual properties """ result = VisualAttributes() result.set(self) if new_parent is not None: result.parent = new_parent return result
@callback_property def color(self): """ Color specified using Matplotlib notation Specifically, it can be: * A string with a common color (e.g. 'black', 'red', 'orange') * A string containing a float in the rng [0:1] for a shade of gray ('0.0' = black,'1.0' = white) * A tuple of three floats in the rng [0:1] for (R, G, B) * An HTML hexadecimal string (e.g. '#eeefff') """ return self._color @color.setter def color(self, value): if isinstance(value, six.string_types): self._color = value.lower() else: self._color = value @callback_property def alpha(self): """ Transparency, given as a floating point value between 0 and 1. """ return self._alpha @alpha.setter def alpha(self, value): self._alpha = value @callback_property def linestyle(self): """ The line style, which can be one of 'solid', 'dashed', 'dash-dot', 'dotted', or 'none'. """ return self._linestyle @linestyle.setter def linestyle(self, value): if value not in VALID_LINESTYLES: raise Exception("Line style should be one of %s" % '/'.join(VALID_LINESTYLES)) self._linestyle = value @callback_property def linewidth(self): """ The line width, in points. """ return self._linewidth @linewidth.setter def linewidth(self, value): if type(value) not in [float, int]: raise Exception("Line width should be a float or an int") if value < 0: raise Exception("Line width should be positive") self._linewidth = value @callback_property def marker(self): """ The marker symbol. """ return self._marker @marker.setter def marker(self, value): self._marker = value @callback_property def markersize(self): return self._markersize @markersize.setter def markersize(self, value): self._markersize = int(value) def __setattr__(self, attribute, value): # Check that the attribute exists (don't allow new attributes) allowed = set(['color', 'linewidth', 'linestyle', 'alpha', 'parent', 'marker', 'markersize']) if attribute not in allowed and not attribute.startswith('_'): raise Exception("Attribute %s does not exist" % attribute) changed = getattr(self, attribute, None) != value super(VisualAttributes, self).__setattr__(attribute, value) # if parent has a broadcast method, broadcast the change if (changed and hasattr(self, 'parent') and hasattr(self.parent, 'broadcast') and attribute != 'parent' and not attribute.startswith('_')): self.parent.broadcast('style')