source: qesdi/geoplot/trunk/lib/geoplot/utils.py @ 5876

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/qesdi/geoplot/trunk/lib/geoplot/utils.py@5876
Revision 5876, 5.0 KB checked in by pnorton, 10 years ago (diff)

Added a faster layer drawer for the grid, a new style of colour bar and colour schemes which now hold the normalisation and colour map instances.

Line 
1"""
2utils.py
3============
4
5Holds functions which dont fit within any of the other geoplot files.
6
7"""
8import time
9
10import StringIO
11import logging
12import numpy
13
14import matplotlib.colors as colors
15#from matplotlib import colors
16
17# was having problems with alpha belnding so swapped the backend
18#from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
19#from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas
20from geoplot.custom_cairo_renderer import CustomFigureCanvasCairo as FigureCanvas
21
22from geoplot.image_import import Image
23
24log = logging.getLogger(__name__) 
25
26def generateDiscreteCmap(rgbList, name):
27    """
28    Generates a discrete colour map form a given list of rgb colours.
29
30    @param rgbList: A list of rgb tuples given in values 0-255, i.e
31        [(1,4,5), (243,0,34), ... (r, g, b)]
32    @type  rgbList: A list of tuples
33    @param    name:The name for the new colour map
34    @type     name:string
35    @return       :returns a a colour map
36    @rtype        :a matplotlib.colors.ListedColormap instance
37    """
38
39    #first need to scale the values so they are between 0 and 1
40    scaledRGBList = _scaleRGBList(rgbList)
41
42    return colors.ListedColormap(scaledRGBList, name, len(scaledRGBList))
43
44def _scaleRGBList(rgbList):
45    """
46    Reduces a list of rgb tuples to values between 0 and 1 from 0 and 255
47
48    @param list: A list of rgb tuples with values between 0 and 255
49    @type  list: A list of tuples
50    @return    : A list of rgb tuples with values between 0 and 1
51    @rtype     : A list of tuplese
52    """
53
54    newList = []
55    for (r,g,b) in rgbList:
56        (r,g,b) = (float(r), float(g), float(b))
57
58        #check the values are less than 255
59        if r > 255.0 or g > 255.0 or b > 255.0:
60            raise Exception("Value in RGB tuple is grater than 255 (%f,%f,%f)" % (r,g,b))
61
62        newList.append(((float(r)/255.0), (float(g)/255.0), (float(b)/255.0)))
63
64    return newList
65
66
67def figureToImage(fig):
68    #st = time.time()
69   
70    canvas = FigureCanvas(fig)
71       
72    # a shortcut with the agg backend
73#    canvas.draw()
74#    size = canvas.get_width_height()
75#    buffer = canvas.buffer_rgba(0,0)
76#    im = Image.fromstring('RGBA', size, buffer, 'raw', 'RGBA', 0, 1)
77   
78#    log.debug("im.palette.mode = %s" % (im.palette.mode,))
79    #im.-convert("RGBA")
80   
81    buffer = StringIO.StringIO()
82    canvas.print_figure(buffer, dpi=fig.get_dpi(), facecolor=fig.get_facecolor(), edgecolor=fig.get_edgecolor())
83    buffer.seek(0)   
84    im = Image.open(buffer)
85   
86    #log.debug("converted figure to image in %s" % (time.time() - st,))
87   
88    return im
89
90def round_to_n(arr, n):
91   
92    a = abs(arr)
93    c = numpy.log10(a)
94   
95    if c.__class__ == numpy.ndarray:
96        c[numpy.isinf(c)] = 0.0
97    else:
98        if numpy.isinf(c) :
99            c = 0.0
100    c = numpy.power(10,numpy.floor(c))
101    res = (arr/c).round(n-1) * c
102
103    #log.debug("arr = %s, a = %s, n=%s, c=%s, res = %s" % (arr, a, n, c, res,))
104
105    return res
106
107def getAllIndices(shape):
108    totalSize = 1
109    for dim in shape:
110        totalSize *= dim
111
112    #build a list to hold the results
113    res = [0] * len(shape)
114
115    for i in range(totalSize):
116       
117        for dimInd, dim in enumerate(shape):
118           
119            step = i % dim # step along this dimension
120            i = i / dim    # reduce the remaining steps
121            res[dimInd] = step
122       
123        yield tuple(res)
124   
125       
126
127def ispointInLimits(point, xLimits, yLimits):
128    x,y = point
129   
130    if isValueInLimits(x, xLimits) and isValueInLimits(y, yLimits):
131        return True
132    else:
133        return False
134
135def isRangeInLimits(range, limits):
136       
137    if isValueInLimits(range[0], limits):
138        return True
139   
140    if isValueInLimits(range[1], limits):
141        return True
142   
143    if range[0] <= limits[0] and range[1] >= limits[1]:
144        return True
145   
146    return False
147       
148def isValueInLimits(val, limits):   
149    return  val >= limits[0] and val <= limits[1]
150
151def isListUnique(items):
152    seen = {}
153   
154    for item in items:
155        if item in seen:
156            return False
157       
158        seen[item] = 1
159       
160    return True           
161 
162def getUniqueList(items):
163    seen = {}
164    l = []
165    for item in items:
166        if item in seen:
167            continue
168       
169        seen[item] = 1
170        l.append(item)
171       
172    return l
173
174def getBounds(arr):
175   
176    assert len(arr.shape) == 1
177   
178    if len(arr) == 1:
179        return numpy.array([arr[0]/2.0, arr[0] * 2.0])
180   
181    #guess the first and the last bounds
182    start = arr[0] - (arr[1]- arr[0])/2.0 
183    end = (arr[-1] - arr[-2])/2.0 + arr[-1]
184   
185    shape = (arr.shape[0] + 1,)
186    arrA = numpy.zeros(shape, dtype=arr.dtype)
187    arrB = numpy.zeros(shape, dtype=arr.dtype)
188   
189    arrA[:-1] = arr
190    arrB[1:] = arr
191   
192    arrC = (arrA + arrB) / 2.0
193    arrC[0] = start
194    arrC[-1] = end
195   
196    return arrC
197   
198def getMidpoints(bounds):
199    x = [(bounds[i] + bounds[i+1])/2.0 for i in range(len(bounds) -1)]
200    return  numpy.array(x)   
201   
202   
Note: See TracBrowser for help on using the repository browser.