source: qesdi/geoplot/trunk/lib/geoplot/tests/unit/test_colour_scheme_builder.py @ 6089

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/qesdi/geoplot/trunk/lib/geoplot/tests/unit/test_colour_scheme_builder.py@6089
Revision 6089, 10.0 KB checked in by pnorton, 12 years ago (diff)

Imroved the colour bar code so that a legend colour bar can be used without specifying any intervals.

Line 
1#/urs/bin/env python
2"""
3test_grid_builder_base.py
4"""
5
6import logging
7
8import nose
9import numpy
10from mock import Mock, patch, patch_object
11
12import nose.tools as nt
13import matplotlib
14import geoplot
15from geoplot.colour_scheme import ColourSchemeBuilder, _ConinuousSchemeBuilder, _IntervalSchemeBuidler
16from geoplot.colour_scheme_intervals import ColourSchemeInterval
17from geoplot.grid import Grid
18from geoplot.range import Range
19import geoplot.colour_scheme
20
21log = logging.getLogger(__name__)
22
23class Test_ColourSchemeBuilder(object):
24   
25    def setUp(self):
26        self.builder = ColourSchemeBuilder()
27   
28    @patch('matplotlib.cm.get_cmap')
29    def test_001_getColouMap(self, mockGetCmap):
30       
31        # make sure that the _getColourMap function returns the correct
32        # colour map for the value of the cmap attribute
33       
34        # when a cmap object is provided then that is used as the initial
35        # colour map
36        self.builder.cmap = Mock(spec=matplotlib.colors.ListedColormap)
37        returnedCmap = self.builder._getColourMap()
38        nt.assert_equal(id(self.builder.cmap), id(returnedCmap))       
39       
40        # when a string is provided then the named colour map is retireved
41        self.builder.cmap = 'jet'
42       
43        returnedCmap = self.builder._getColourMap()
44        nt.assert_equal(mockGetCmap.call_count, 1) # called the get_cmap function
45        nt.assert_equal(mockGetCmap.call_args, (('jet',), {})) # called with the right name
46        #check that the bad colour has been set on the new cmap
47        nt.assert_equal(returnedCmap.method_calls, [('set_bad', ('w',), {})])
48       
49        mockGetCmap.reset_mock()
50       
51        # when cmap is None then get_cmap is called with no arguments to return
52        # the defaul colourmap
53        self.builder.cmap = None
54       
55        returnedCmap = self.builder._getColourMap()
56        nt.assert_equal(mockGetCmap.call_count, 1) # called the get_cmap function
57        nt.assert_equal(mockGetCmap.call_args, ((), {})) # called with no arguments
58        #check that the bad colour has been set on the new cmap
59        nt.assert_equal(returnedCmap.method_calls, [('set_bad', ('w',), {})])
60       
61    def test_002_getCBMinMaxSwapsValues(self):
62       
63        # when the values are the wrong way round the getCBMinMax function
64        # swaps them round the right way
65       
66        # test them the right way first
67        minVal, maxVal = 10, 100
68        self.builder.colourBarMin, self.builder.colourBarMax =  minVal, maxVal
69        nt.assert_equal(
70            Range(minVal, maxVal), self.builder._getCbarRange()
71        )
72       
73        # now set them round the wrong way
74        self.builder.colourBarMin, self.builder.colourBarMax =  maxVal, minVal
75        nt.assert_equal(
76            Range(minVal, maxVal), self.builder._getCbarRange()
77        )       
78   
79    @patch('geoplot.colour_scheme._ConinuousSchemeBuilder', spec=True)
80    @patch('geoplot.colour_scheme._IntervalSchemeBuidler', spec=True)
81    def test_003_usesCorrectSchemeBuilders(self, 
82                                        mockIntSchemeBuilder, mockContSchemeBuilder):
83       
84        # make sure that the right scheme builder classes are used to
85        # build the colour schemes.
86       
87        # set the attributes
88        self.builder.cmap = Mock()
89        self.builder.colourBarMin, self.builder.colourBarMax =  10, 100
90        self.builder.intervals = None
91        self.builder.intervalNames = None
92        mockGrid = Mock(spec=Grid)
93        mockIntBuilder = Mock(spec=geoplot.colour_scheme_intervals.ColourSchemeIntervalBuilder)
94        mockIntBuilder.buildCSInterval.return_value = Mock(spec=geoplot.colour_scheme_intervals.ColourSchemeInterval)
95       
96        self.builder._intervalBuilder = mockIntBuilder
97       
98        # when intervalColourbar is false should use the _ConinuousSchemeBuilder
99        self.builder.intervalColourbar = False
100       
101        scheme = self.builder.buildScheme('continuous', mockGrid)
102       
103        nt.assert_equal(mockContSchemeBuilder.call_count, 1)
104        nt.assert_equal(mockIntSchemeBuilder.call_count, 0)
105        nt.assert_equals(mockContSchemeBuilder.call_args, ((Range(10, 100), self.builder.colourBarScale, self.builder.cmap, ),{}))
106
107        # check the build command was called on the object returned from the class
108        nt.assert_equal(mockContSchemeBuilder.return_value.buildScheme.call_count, 1)
109        nt.assert_equals(mockContSchemeBuilder.return_value.buildScheme.call_args, ((),{}))
110       
111        # check the scheme is the result of this call
112        nt.assert_equal(mockContSchemeBuilder.return_value.buildScheme.return_value, scheme)
113       
114        mockIntSchemeBuilder.reset_mock()
115        mockContSchemeBuilder.reset_mock()
116       
117        # when intervalColourbar is true use the _IntervalSchemeBuidler
118       
119        scheme = self.builder.buildScheme('legend',mockGrid)
120       
121        nt.assert_equal(mockIntSchemeBuilder.call_count, 1)
122        nt.assert_equal(mockContSchemeBuilder.call_count, 0)
123        nt.assert_equals(mockIntSchemeBuilder.call_args, 
124            ((Range(10, 100), 
125              self.builder.colourBarScale, 
126              self.builder.cmap, 
127              mockIntBuilder.buildCSInterval.return_value ),{}))
128
129        # check the build command was called on the object returned
130        nt.assert_equal(mockIntSchemeBuilder.return_value.buildScheme.call_count, 1)
131        nt.assert_equals(mockIntSchemeBuilder.return_value.buildScheme.call_args, ((),{}))
132       
133        # check the scheme is the result of this call
134        nt.assert_equal(mockIntSchemeBuilder.return_value.buildScheme.return_value, scheme)
135               
136       
137    def test_004_checkHideOutsideBoundsSet(self):
138       
139        # when HideOutsideBounds is true the set_under and set_over methods
140        # should be called on the colour map
141       
142        # test without first
143        self.builder.hideOutsideBounds = False       
144        self.builder.cmap = Mock(spec=matplotlib.colors.ListedColormap)
145        returnedCmap = self.builder._getColourMap()
146       
147        nt.assert_equal(self.builder.cmap, returnedCmap)
148        nt.assert_equal(returnedCmap.method_calls, [])
149       
150        self.builder.cmap.reset_mock()
151       
152        #test with
153        self.builder.hideOutsideBounds = True
154        returnedCmap = self.builder._getColourMap()
155       
156        nt.assert_equal(self.builder.cmap, returnedCmap)
157        nt.assert_equal(returnedCmap.method_calls, [('set_under', ('0.25',), {'alpha': 0.0}), ('set_over', ('0.75',), {'alpha': 0.0})])
158       
159        self.builder.cmap.reset_mock()
160       
161
162class Test_ContinuousColourSchemeBuilder(object):
163   
164    def setUp(self):
165        self.builder = _ConinuousSchemeBuilder(Range(10, 100), 'linear' ,
166                                               Mock(spec=matplotlib.colors.LinearSegmentedColormap))
167   
168    def test_001_returnedSchemeIsContinuouse(self):
169       
170        scheme = self.builder.buildScheme()
171        nt.assert_true(isinstance(scheme, geoplot.colour_scheme.ContinuousColourScheme))
172   
173    def test_002_returndCmapIsUnchanged(self):
174       
175        # for a continuous colour scheme the cmap should be unchanged form the
176        # inital cmap
177       
178        scheme = self.builder.buildScheme()
179        nt.assert_equal(scheme.colourMap, self.builder.initialCmap)
180        nt.assert_equal(scheme.colourMap.method_calls, [])
181   
182    def test_003_returnedNormHasVminVmaxSet(self):
183       
184        # make sure the min/max of the grid values are used when the colour bar
185        # min/max is set to None
186       
187
188        self.builder.cbRange = Range(5.0, 10.0)
189        scheme = self.builder.buildScheme()
190           
191        nt.assert_equal((scheme.norm.vmin, scheme.norm.vmax), (5.0, 10.0))                   
192       
193    def test_004_returnsLogNorm(self):
194        self.builder.cbScale = 'log'
195        scheme = self.builder.buildScheme()
196
197        nt.assert_true(isinstance(scheme.norm, matplotlib.colors.LogNorm))
198       
199class Test_IntervalSchemeBuidler(object):
200   
201    def setUp(self):
202        interval = ColourSchemeInterval(numpy.array([25.0,35.0,45.0,55.0]), 
203                                        numpy.array([20.0,30.0,40.0,50.0,60.0]), 
204                                        ['a','b','c','d'])
205        self.builder = _IntervalSchemeBuidler(Range(10.0, 100.0),  'linear' ,
206                                              Mock(spec=matplotlib.colors.LinearSegmentedColormap), 
207                                              interval)
208   
209    def test_001_returnedCmapForNamedIntervals(self):
210       
211        #check that the right number of colours appear in the listed colourmap
212       
213        scheme = self.builder.buildScheme()
214               
215        nt.assert_equal(scheme.colourMap.N, 4)
216        nt.assert_equal(scheme.colourMap.__class__, matplotlib.colors.ListedColormap)
217   
218
219    def test_002_returnIntervalCmapUntouched(self):
220       
221        colours = [(0.4, 0.4, 0.5, 1.0),
222                   (0.5, 0.5, 0.6, 1.0),
223                   (0.6, 0.6, 0.7, 1.0),]
224       
225        self.builder.initialCmap = matplotlib.colors.ListedColormap(colours, "test_colourmap")
226       
227        scheme = self.builder.buildScheme()
228        nt.assert_equal(scheme.colourMap.colors, colours)
229        nt.assert_equal(scheme.colourMap.name, "test_colourmap")
230   
231    def test_003_returnedLabelsCorrect(self):
232       
233        #labels for the unique values
234        self.builder.csInterval.bounds = numpy.array([5.0,15.0,25.0,35.0])
235        self.builder.csInterval.midpoints = numpy.array([10.0,20.0,30.0])
236        self.builder.csInterval.labels = ['5.0 - 15.0', '15.0 - 25.0', '25.0 - 35.0']
237        self.builder.cbRange = Range(0, 100)
238
239        #labels for specified bounds
240        scheme = self.builder.buildScheme()
241        nt.assert_equal(scheme.labels, ['5.0 - 15.0', '15.0 - 25.0', '25.0 - 35.0'])
242
243        #labels for given bounds
244        self.builder.csInterval.labels = ["one","two","three"]
245        scheme = self.builder.buildScheme()
246       
247        nt.assert_equal(scheme.labels, ["one", "two", "three"])
248               
249
250     
251
252if __name__ == '__main__':
253
254    nose.runmodule()
Note: See TracBrowser for help on using the repository browser.