/usr/lib/python2.7/dist-packages/Scientific/Visualization/Color.py is in python-scientific 2.9.4-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | # This module provides color definitions for use in Visualization.
#
# Written by: Konrad Hinsen <hinsen@cnrs-orleans.fr>
# Last revision: 2009-6-10
#
"""
Color definitions for use in the modules VRML, VRML2, VMD, and PyMOL.
"""
from Scientific import N
import string
#
# Colors
#
class Color:
"""
RGB Color specification
Color objects can be added and multiplied with scalars.
"""
def __init__(self, rgb):
"""
@param rgb: a sequence of three numbers between zero and one,
specifying the intensities of red, green, and blue.
@type rgb: C{int} or C{float}
"""
self.rgb = (min(1.,max(0.,rgb[0])),
min(1.,max(0.,rgb[1])),
min(1.,max(0.,rgb[2])))
def __mul__(self, scale):
return Color(map(lambda i, s=scale: s*i, self.rgb))
__rmul__ = __mul__
def __add__(self, other):
return Color(map(lambda a, b: a+b, self.rgb, other.rgb))
def __cmp__(self, other):
if not isinstance(other, Color):
return NotImplemented
return cmp(self.rgb, other.rgb)
def __hash__(self):
return hash(self.rgb)
def __str__(self):
return str(self.rgb[0])+' '+str(self.rgb[1])+' '+str(self.rgb[2])
def __repr__(self):
return 'Color(' + repr(self.rgb) + ')'
#
# Color scales
#
class ColorScale:
"""
Mapping from a number interval to a color range
The color scale is blue - green - yellow - orange - red.
"""
def __init__(self, range):
"""
@param range: a tuple of two numbers (the lower and upper limits
of the interval), or a single number specifying the
upper limit for a default lower limit of zero
@type range: C{float} or C{tuple}
"""
if isinstance(range, tuple):
self.zero, self.range = range
self.range = self.range-self.zero
else:
self.range = range
self.zero = 0.
def __call__(self, value):
"""
@param value: the value within the range for which the color
is requested. If the value is outside of the
specified range, the edge of the range is used instead.
@type value: C{float}
@returns: the color corresponding to value
@rtype: L{Color}
"""
value = (value-self.zero)/self.range
value = max(min(value, 1.), 0.)
if value <= 0.25:
red = 0.
green = 4.*value
blue = 1.
elif value <= 0.5:
red = 0.
green = 1.
blue = 1.-4.*(value-0.25)
elif value <= 0.75:
red = 4.*(value-0.5)
green = 1.
blue = 0.
else:
red = 1.
green = 1.-4.*(value-0.75)
blue = 0.
return Color((red, green, blue))
class SymmetricColorScale:
"""
Mapping of a symmetric number interval to a color range
The colors are red for negative numbers and green for positive
numbers, with a color intensity proportional to the absolute
value of the argument. Zero is mapped to white.
"""
def __init__(self, max, n = 20):
"""
@param max: a positive number defining the range, which is from
-max to +max.
@type max: C{float}
"""
self.range = max
self.n = n
self.colors = {}
def __call__(self, value):
"""
@param value: the value within the range for which the color
is requested. If the value is outside of the
specified range, the edge of the range is used instead.
@type value: C{float}
@returns: the color corresponding to value
@rtype: L{Color}
"""
negative = value < 0.
index = N.floor(abs(value)*self.n/self.range)
if index > self.n:
raise ValueError('Value outside range')
try:
return self.colors[(negative, index)]
except KeyError:
white = 1.*(self.n-index)/self.n
if negative:
color = Color((1., white, white))
else:
color = Color((white, 1., white))
self.colors[(negative, index)] = color
return color
#
# Predefined colors
#
_full_colors = {
'black': Color((0.,0.,0.)),
'white': Color((1.,1.,1.)),
'grey': Color((0.5,0.5,0.5)),
'red': Color((1.,0.,0.)),
'green': Color((0.,1.,0.)),
'blue': Color((0.,0.,1.)),
'yellow': Color((1.,1.,0.)),
'magenta': Color((1.,0.,1.)),
'cyan': Color((0.,1.,1.)),
'orange': Color((1.,0.5,0.)),
'violet': Color((1.,0.,0.5)),
'olive': Color((0.1,0.6,0.2)),
'brown': Color((0.6,0.4,0.)),
}
_dark_colors = {}
for name, value in _full_colors.items():
_dark_colors[name] = 0.3*value
_light_colors = {}
for name, value in _full_colors.items():
_light_colors[name] = 0.7*value + 0.3*_full_colors['white']
del name
del value
def ColorByName(name):
"""
@param name: one of the predefined color names: black, white, grey,
red, green, blue, yellow, magenta, cyan, orange, violet, olive,
and brown. Any color can be prefixed by "light " or "dark " to yield
a variant. The prefix must be separated from the color name by white
space, e.g. "light green".
@type name: C{str}
@returns: the color associated with name
@rtype: L{Color}
@raises KeyError: if the color name is not defined
"""
name = string.split(string.lower(name))
dict = _full_colors
if len(name) == 2:
if name[0] == 'light':
dict = _light_colors
elif name[0] == 'dark':
dict = _dark_colors
return dict[name[-1]]
|