Back to index

python-biopython  1.60
_Colors.py
Go to the documentation of this file.
00001 # Copyright 2003-2008 by Leighton Pritchard.  All rights reserved.
00002 # This code is part of the Biopython distribution and governed by its
00003 # license.  Please see the LICENSE file that should have been included
00004 # as part of this package.
00005 #
00006 # Contact:       Leighton Pritchard, Scottish Crop Research Institute,
00007 #                Invergowrie, Dundee, Scotland, DD2 5DA, UK
00008 #                L.Pritchard@scri.ac.uk
00009 ################################################################################
00010 
00011 """ Colors module
00012 
00013     Provides:
00014 
00015     o ColorTranslator -  class to convert tuples of integers and floats into
00016                             colors.Color objects
00017 
00018     For drawing capabilities, this module uses reportlab to define colors:
00019 
00020     http://www.reportlab.com
00021 """
00022 
00023 # ReportLab imports
00024 from reportlab.lib import colors
00025 
00026 class ColorTranslator(object):
00027     """ Class providing methods for translating representations of color into
00028     """
00029     def __init__(self, filename=None):
00030         """ __init__(self, filename)
00031 
00032             o filename      Location of a file containing colorscheme
00033                             information
00034 
00035             Optional parameters set the color scheme 
00036         """
00037         self._artemis_colorscheme = {0: (colors.Color(1, 1, 1,), "pathogenicity, adaptation, chaperones"),
00038                1: (colors.Color(0.39, 0.39, 0.39), "energy metabolism"),
00039                2: (colors.Color(1, 0, 0), "information transfer"),
00040                3: (colors.Color(0, 1, 0), "surface"),
00041                4: (colors.Color(0, 0, 1), "stable RNA"),
00042                5: (colors.Color(0, 1, 1), "degradation of large molecules"),
00043                6: (colors.Color(1, 0, 1), "degradation of small molecules"),
00044                7: (colors.Color(1, 1, 0), "central/intermediary/miscellaneous metabolism"),
00045                8: (colors.Color(0.60, 0.98, 0.60), "unknown"),
00046                9: (colors.Color(0.53, 0.81, 0.98), "regulators"),
00047                10: (colors.Color(1, 0.65, 0), "conserved hypotheticals"),
00048                11: (colors.Color(0.78, 0.59, 0.39), "pseudogenes and partial genes"),
00049                12: (colors.Color(1, 0.78, 0.78), "phage/IS elements"),
00050                13: (colors.Color(0.70, 0.70, 0.70), "some miscellaneous information"),
00051                14: (colors.Color(0, 0, 0), ""),
00052                15: (colors.Color(1, 0.25, 0.25), "secondary metabolism"),
00053                16: (colors.Color(1, 0.5, 0.5), ""),
00054                17: (colors.Color(1, 0.75, 0.75), "")
00055                 }      # Hardwired Artemis color scheme                                                                        
00056         self._colorscheme = {}
00057         if filename is not None:
00058             self.read_colorscheme(filename)# Imported color scheme
00059         else:
00060             self._colorscheme = self._artemis_colorscheme
00061 
00062 
00063     def translate(self, color=None, colour=None):
00064         """ translate(self, color)
00065 
00066             o color    Color defined as an int, a tuple of three ints 0->255
00067                        or a tuple of three floats 0 -> 1, or a string giving
00068                        one of the named colors defined by ReportLab, or a
00069                        ReportLab color object (returned as is).
00070 
00071                        (This argument is overridden by a backwards compatible
00072                        argument with UK spelling, colour).
00073 
00074             Returns a colors.Color object, determined semi-intelligently
00075             depending on the input values
00076         """
00077         #Let the UK spelling (colour) override the USA spelling (color)
00078         if colour is not None:
00079             color = colour
00080         
00081         if color is None:
00082             raise ValueError, "Passed color (or colour) must be a valid color type"
00083         elif isinstance(color, int):
00084             color = self.scheme_color(color)
00085         elif isinstance(color, colors.Color):
00086             return color
00087         elif isinstance(color, basestring):
00088             #Assume its a named reportlab color like "red".
00089             color = colors.toColor(color)
00090         elif type(color) == type((1., 2., 3.)) and type(color[0]) == type(1.):
00091             color = self.float1_color(color)        
00092         elif type(color) == type((1, 2, 3)) and type(color[0]) == type(1):
00093             color = self.int255_color(color)
00094         return color
00095         
00096 
00097     def read_colorscheme(self, filename):
00098         """ read_colorscheme(self, filename)
00099 
00100             o filename      The location of a file defining colors in tab-separated
00101                             format plaintext as:
00102                             INT \t RED \t GREEN \t BLUE \t Comment
00103                             Where RED, GREEN and BLUE are intensities in the range
00104                             0 -> 255
00105                             e.g.
00106                             2 \t 255 \t 0 \t 0 \t Red: Information transfer
00107 
00108             Reads information from a file containing color information and
00109             stores it internally
00110         """
00111         lines = open(filename, 'r').readlines()
00112         for line in lines:
00113             data = line.strip().split('\t')
00114             try:
00115                 label = int(data[0])
00116                 red, green, blue = int(data[1]), int(data[2]), int(data[3])
00117                 if len(data) > 4:
00118                     comment = data[4]
00119                 else:
00120                     comment = ""
00121                 self._colorscheme[label] = (self.int255_color((red, green, blue)),
00122                                              comment)
00123             except:
00124                 raise IOError, "Expected INT \t INT \t INT \t INT \t string input"
00125 
00126     def get_artemis_colorscheme(self):
00127         """ get_artemis_colorscheme(self)
00128 
00129             Return the Artemis color scheme as a dictionary
00130         """
00131         return self._artemis_colorscheme
00132         
00133 
00134     def artemis_color(self, value):
00135         """ artemis_color(self, value)
00136 
00137             o value     An int representing a functional class in the Artemis
00138                         color scheme (see www.sanger.ac.uk for a description),
00139                         or a string from a GenBank feature annotation for the
00140                         color which may be dot delimited (in which case the
00141                         first value is used).
00142 
00143             Takes an int representing a functional class in the Artemis color
00144             scheme, and returns the appropriate colors.Color object
00145         """
00146         try:
00147             value = int(value)
00148         except ValueError:
00149             if value.count('.'):                           # dot-delimited
00150                 value = int(artemis_color.split('.',1)[0]) # Use only first integer
00151             else:
00152                 raise
00153         if value in self._artemis_colorscheme:
00154             return self._artemis_colorscheme[value][0]
00155         else:
00156             raise ValueError, "Artemis color out of range: %d" % value
00157 
00158 
00159     def get_colorscheme(self):
00160         """ get_colorscheme(self)
00161 
00162             Return the user-defined color scheme as a dictionary
00163         """
00164         return self._colorscheme
00165 
00166 
00167     def scheme_color(self, value):
00168         """ scheme_color(self, value)
00169 
00170             o value     An int representing a single color in the user-defined
00171                         color scheme
00172 
00173             Takes an int representing a user-defined color and returns the
00174             appropriate colors.Color object
00175         """
00176         if value in self._colorscheme:
00177             return self._colorscheme[value][0]
00178         else:
00179             raise ValueError, "Scheme color out of range: %d" % value
00180 
00181 
00182     def int255_color(self, values):
00183         """ int255_color(self, values)
00184 
00185             o values        A tuple of (red, green, blue) intensities as
00186                             integers in the range 0->255
00187 
00188             Takes a tuple of (red, green, blue) intensity values in the range
00189             0 -> 255 and returns an appropriate colors.Color object
00190         """
00191         red, green, blue = values
00192         factor = 1/255.
00193         red, green, blue = red * factor, green * factor, blue * factor
00194         return colors.Color(red, green, blue)
00195 
00196 
00197     def float1_color(self, values):
00198         """ float1_color(self, values)
00199 
00200             o values        A tuple of (red, green, blue) intensities as floats
00201                             in the range 0 -> 1
00202 
00203             Takes a tuple of (red, green, blue) intensity values in the range
00204             0 -> 1 and returns an appropriate colors.Color object
00205         """
00206         red, green, blue = values
00207         return colors.Color(red, green, blue)
00208 
00209 
00210 ################################################################################
00211 # RUN AS SCRIPT
00212 ################################################################################
00213 
00214 if __name__ == '__main__':
00215 
00216     # Test code
00217     gdct = ColorTranslator()
00218     print gdct.float1_color((0.5, 0.5, 0.5))
00219     print gdct.int255_color((1, 75, 240))
00220     print gdct.artemis_color(7)
00221     print gdct.scheme_color(2)
00222 
00223     print gdct.translate((0.5, 0.5, 0.5))
00224     print gdct.translate((1, 75, 240))
00225     print gdct.translate(7)
00226     print gdct.translate(2)
00227 
00228                 
00229                         
00230