Ignore:
Timestamp:
14/12/09 14:57:03 (10 years ago)
Author:
pnorton
Message:

Fixed lots of small bugs and tidied up the layer drawer code a bit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • qesdi/geoplot/trunk/lib/geoplot/colour_scheme.py

    r6103 r6118  
    1414from geoplot.range import Range 
    1515from geoplot.fixed_boundary_norm import FixedBoundaryNorm 
    16 from geoplot.colour_bar import COLOUR_BAR_STYLES, COLOUR_SCHEME_SCALE 
     16from geoplot.colour_bar import COLOUR_SCHEME_SCALE 
    1717from geoplot.colour_scheme_intervals import ColourSchemeIntervalBuilder 
    1818 
     
    2222 
    2323class ColourScheme(object): 
     24    """ 
     25    A colour scheme object used to keep track of the colourbar, normalization and 
     26    intervals asociated with a plot 
     27    """ 
    2428     
    25     def __init__(self, colourMap, norm, scale): 
    26         self.colourMap = colourMap 
     29    def __init__(self, cmap, norm, intervals, scale): 
     30        ''' 
     31        @param cmap: the supplied matplotlib colourmap (may be listed if one 
     32          was given) 
     33        @type cmap: 
     34        @param norm: a Normalize instance for the colour bar boundaries given 
     35        @type norm: 
     36        @param intervals: the colour bar intervals supplied (or default intervals) 
     37        @type intervals: 
     38        ''' 
     39         
     40        self.cmap = cmap 
    2741        self.norm = norm 
     42        self.intervals = intervals 
    2843        self.scale = scale 
     44         
     45    def getListedCmap(self): 
     46        if self.cmap.__class__ != matplotlib.colors.ListedColormap: 
     47             
     48            if len(self.intervals.midpoints) == 1: 
     49                #only one interval value so pick the middle of the cmap 
     50                colors = [ self.cmap(0.5) ] 
     51                cmap = matplotlib.colors.ListedColormap(colors) 
     52            else: 
     53                colors = [self.cmap(self.norm(x)) for x in self.intervals.midpoints] 
     54                cmap = matplotlib.colors.ListedColormap(colors) 
     55        else: 
     56            cmap = self.cmap 
     57         
     58        return cmap      
     59     
     60    def getBoundaryNorm(self): 
     61        return FixedBoundaryNorm(self.intervals.bounds, len(self.intervals.bounds) - 1 ) 
    2962 
    30 class ContinuousColourScheme(ColourScheme): 
    31     pass 
    32  
    33 class IntervalColourScheme(ColourScheme): 
    34          
    35     def __init__(self, colourMap, norm, scale, labels, midpoints, bounds, labelFormat): 
    36         self.labels = labels 
    37         self.midpoints = midpoints 
    38         self.bounds = bounds 
    39         self.labelFormat = labelFormat 
    40         ColourScheme.__init__(self, colourMap, norm, scale) 
    41          
    4263 
    4364class ColourSchemeBuilder(object): 
    4465     
    45     def __init__(self, cmap=None,  
     66    def __init__(self, cmap='jet',  
    4667                 colourBarMin=None,  
    4768                 colourBarMax=None, 
    48                  colourBarScale=COLOUR_SCHEME_SCALE.LINEAR,  
    49                  hideOutsideBounds=False, 
     69                 colourBarScale=COLOUR_SCHEME_SCALE.LINEAR, 
    5070                 numIntervals=6, 
    51                  labelFormat=None, 
    52                  intervals=None, 
    53                  intervalNames=None): 
     71                 intervals=None): 
    5472 
    55         self._numIntervals = None 
    56          
     73        self._numIntervals = 6 
    5774        self.cmap = cmap 
    5875        self.colourBarMin = colourBarMin 
    5976        self.colourBarMax = colourBarMax 
    6077        self.colourBarScale = colourBarScale 
    61         self.hideOutsideBounds = hideOutsideBounds 
    6278        self.numIntervals = numIntervals 
    6379        self.intervals = intervals 
    64         self.intervalNames = intervalNames 
    6580        self._intervalBuilder = ColourSchemeIntervalBuilder() 
    66         self.labelFormat = labelFormat 
    6781         
    68     def buildScheme(self, colourBarStyle, grid=None): 
     82    def buildScheme(self, grid=None): 
    6983         
    7084        cbRange = self._getCbarRange(grid) 
    71         initialCmap = self._getColourMap() 
    7285         
    73         assert colourBarStyle in COLOUR_BAR_STYLES.all(), " %s not in %s" % (colourBarStyle, COLOUR_BAR_STYLES.all()) 
    74  
     86        if self.colourBarScale == COLOUR_SCHEME_SCALE.LOG: 
     87            cbRange = self._adjustCBRangeForLog(cbRange) 
    7588         
    76         if self.labelFormat is None: 
    77             if self.colourBarScale == COLOUR_SCHEME_SCALE.LINEAR: 
    78                 self.labelFormat = "%.2f" 
     89        cmap = self._getColourMap() 
     90         
     91        intervals = self._intervalBuilder.buildCSInterval(cbRange,  
     92                            self.colourBarScale,  
     93                            self.intervals,  
     94                            numIntervals=self.numIntervals) 
     95         
     96        norm = self._buildNorm(cbRange)         
     97         
     98        return ColourScheme(cmap, norm, intervals, self.colourBarScale) 
     99     
     100    def _buildNorm(self, cbRange): 
     101         
     102        norm = None 
     103         
     104        if self.colourBarScale == COLOUR_SCHEME_SCALE.LOG: 
     105             
     106            if cbRange.minimum is not None and cbRange.minimum > 0 \ 
     107               and cbRange.maximum is not None and cbRange.maximum > 0: 
     108                norm = matplotlib.colors.LogNorm(cbRange.minimum, cbRange.maximum) 
    79109            else: 
    80                 self.labelFormat = "%.1E" 
    81   
     110                log.warning("Can't create a log colour scheme with min = %s and max = %s"  
     111                             % (cbRange.minimum, cbRange.maximum)) 
     112                
     113        if norm == None:     
     114            norm = matplotlib.colors.Normalize(cbRange.minimum, cbRange.maximum) 
    82115         
    83         if colourBarStyle in [COLOUR_BAR_STYLES.LEGEND, 
    84                               COLOUR_BAR_STYLES.LINE]: 
    85             builder = self._getIntervalBuilder(cbRange, initialCmap) 
    86         else: 
    87             builder = self._getContinuousBuilder(cbRange, initialCmap) 
    88  
    89         scheme = builder.buildScheme() 
    90          
    91         if self.hideOutsideBounds: 
    92             scheme.norm.clip = False 
    93          
    94         return scheme 
     116        return norm 
    95117     
    96     def _getIntervalBuilder(self,cbRange, initialCmap): 
    97          
    98         interval = self._intervalBuilder.buildCSInterval(cbRange, self.colourBarScale, self.labelFormat,  
    99                                                          self.intervals, self.intervalNames,  
    100                                                          numIntervals=self.numIntervals) 
    101         log.debug("interval = %s" % (interval,)) 
    102         builder = _IntervalSchemeBuidler(cbRange, self.colourBarScale, initialCmap, interval, self.labelFormat) 
    103          
    104         return builder 
    105      
    106     def _getContinuousBuilder(self, cbRange, initialCmap): 
    107         builder = _ConinuousSchemeBuilder(cbRange, self.colourBarScale, initialCmap) 
    108         return builder 
    109  
    110118    def _getColourMap(self): 
    111119        """ 
     
    127135            cmap = self.cmap 
    128136                 
    129         if self.hideOutsideBounds: 
    130             log.debug("self.hideOutsideBounds = %s" % (self.hideOutsideBounds,)) 
    131             cmap.set_under('0.25', alpha=0.0) 
    132             cmap.set_over('0.75', alpha=0.0) 
    133              
    134137        return cmap 
    135138     
     
    156159        return Range(cbMin, cbMax) 
    157160     
    158      
     161    def _adjustCBRangeForLog(self, cbRange): 
     162        adjustedRange = Range(cbRange.minimum, cbRange.maximum) 
     163         
     164        if adjustedRange.maximum <= 0.0: 
     165            adjustedRange.maximum = 1.0 
     166         
     167        if adjustedRange.minimum <= 0.0: 
     168                             
     169            if adjustedRange.maximum >= 10.0: 
     170                adjustedRange.minimum = 1.0 
     171            else: 
     172                adjustedRange.minimum = 10 ** (numpy.log10(adjustedRange.maximum) - 2) 
     173         
     174        return adjustedRange 
    159175     
    160176    def __set_numIntervals(self, value): 
     
    168184         
    169185    numIntervals = property(__get_numIntervals, __set_numIntervals, None, None) 
    170  
    171 class _ConinuousSchemeBuilder(): 
    172     """ 
    173     This class knows how to buld a continuous colour scheme. 
    174     """ 
    175      
    176     def __init__(self, cbRange, cbScale, initialCmap): 
    177         self.cbRange = cbRange 
    178         self.initialCmap = initialCmap 
    179         self.cbScale = cbScale 
    180      
    181     def buildScheme(self): 
    182         cmap = self._buildColourMap() 
    183         norm = self._buildNorm() 
    184         return ContinuousColourScheme(cmap, norm, self.cbScale) 
    185      
    186     def _buildColourMap(self): 
    187         return self.initialCmap 
    188      
    189     def _buildNorm(self): 
    190          
    191         norm = None 
    192          
    193         if self.cbScale == 'log': 
    194              
    195             if self.cbRange.minimum is not None and self.cbRange.minimum > 0 \ 
    196                and self.cbRange.maximum is not None and self.cbRange.maximum > 0: 
    197                 norm = matplotlib.colors.LogNorm(self.cbRange.minimum, self.cbRange.maximum) 
    198             else: 
    199                 log.warning("Can't create a log colour scheme with min = %s and max = %s"  
    200                              % (self.cbRange.minimum, self.cbRange.maximum)) 
    201                  
    202          
    203         if norm == None:     
    204             norm = matplotlib.colors.Normalize(self.cbRange.minimum, self.cbRange.maximum) 
    205          
    206         return norm 
    207  
    208 class _IntervalSchemeBuidler(): 
    209      
    210     def __init__(self, cbRange, cbScale, initialCmap, csInterval, labelFormat): 
    211         self.cbRange = cbRange 
    212         self.cbScale = cbScale 
    213         self.initialCmap = initialCmap 
    214         self.csInterval = csInterval 
    215         self.labelFormat = labelFormat 
    216          
    217     def buildScheme(self): 
    218         """ 
    219         Builds an interval colour scheme using either the unique values form 
    220         the grid or the bounds in the intervalBoundsString 
    221         """ 
    222          
    223         labels = self.csInterval.labels 
    224         cmap = self._buildColourMap() 
    225         norm = self._getNorm() 
    226          
    227         return IntervalColourScheme(cmap, norm, self.cbScale, labels, self.csInterval.midpoints, self.csInterval.bounds, self.labelFormat) 
    228      
    229     def _buildColourMap(self): 
    230         """ 
    231         Returns a (possibly) modified version of the initialCmap that corresponds 
    232         to the values given by the _ColourSchemeInterval. 
    233         """         
    234         if self.initialCmap.__class__ != matplotlib.colors.ListedColormap: 
    235              
    236             if len(self.csInterval.midpoints) == 1: 
    237                 #only one interval value so pick the middle of the cmap 
    238                 colors = [ self.initialCmap(0.5) ] 
    239                 cmap = matplotlib.colors.ListedColormap(colors) 
    240             else: 
    241                 n = matplotlib.colors.Normalize(self.csInterval.midpoints.min(),  
    242                                                 self.csInterval.midpoints.max()) 
    243      
    244                 colors = [self.initialCmap(n(x)) for x in self.csInterval.midpoints] 
    245                 cmap = matplotlib.colors.ListedColormap(colors) 
    246         else: 
    247             cmap = self.initialCmap 
    248          
    249         return cmap      
    250                          
    251     def _getNorm(self): 
    252         """ 
    253         Returns a Boundary Normalisation object for the given _ColourSchemeInterval. 
    254         """ 
    255         norm = FixedBoundaryNorm(self.csInterval.bounds, len(self.csInterval.bounds) - 1 ) 
    256         return norm 
    257      
Note: See TracChangeset for help on using the changeset viewer.