source: qesdi/geoplot/trunk/lib/geoplot/tests/unit/test_colour_bar.py @ 5946

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

Added the ability to set the scale on the colour scheme to a log scale.

Line 
1#/urs/bin/env python
2"""
3test_colour_bar.py
4"""
5
6import nose
7import nose.tools as nt
8
9import numpy
10
11from mock import patch, patch_object, Mock, sentinel
12
13import matplotlib
14import matplotlib.ticker
15import matplotlib.colorbar
16import matplotlib.cm
17
18import geoplot.colour_bar
19import geoplot.utils
20import geoplot.tests.test_utils
21from geoplot.grid import Grid
22from geoplot.plot_font import PlotFont
23from geoplot.colour_bar import ColourBar
24import geoplot.colour_scheme 
25
26import geoplot.tests.test_config as testConfig
27config = testConfig.getConfig()
28
29FONTS_SECTION = 'Fonts'
30
31class Test_ColourBar(object):
32
33    def setUp(self):
34        #replace the colour bar config
35        self.oldConfig = geoplot.colour_bar.config
36        geoplot.colour_bar.config = config
37       
38        self.colourBarLabel = "A label"
39        self.colourBarPosition = "horizontal"
40        self.colourBarRange = (25.0, 75.0)
41        self.cb = ColourBar(colourBarLabel=self.colourBarLabel, 
42                            colourBarPosition=self.colourBarPosition)
43
44        self.sm = matplotlib.cm.ScalarMappable(cmap=matplotlib.cm.prism)
45        self.sm.set_clim(15.5, 95.5)
46
47    def tearDown(self):
48        geoplot.colour_bar.config = self.oldConfig
49
50    def test_001_drawContinuousColourBar(self):
51       
52        cb = ColourBar('label', 'horizontal', 'continuous')
53       
54        mockAxes = Mock(spec=matplotlib.axes.Axes)
55        scheme = Mock(spec=geoplot.colour_scheme.ContinuousColourScheme)
56       
57        cb.draw(mockAxes, scheme)
58       
59       
60       
61
62    def te_st_001_checkInitialisaion(self):
63        assert(self.cb.colourBarLabel == self.colourBarLabel)
64        assert(self.cb.colourBarPosition == self.colourBarPosition)
65        assert(self.cb.colourBarMin == self.colourBarRange[0])
66        assert(self.cb.colourBarMax == self.colourBarRange[1])
67
68    def te_st_002_checkLabelFont(self):
69        colourBarFont = config[FONTS_SECTION]['ColourBarLabel']
70        assert(self.cb.labelFont.getDict('small')  == colourBarFont.getDict('small'))
71        assert(self.cb.labelFont.getDict('medium') == colourBarFont.getDict('medium'))
72        assert(self.cb.labelFont.getDict('large')  == colourBarFont.getDict('large'))
73
74    def te_st_003_getNormalize(self):
75        #check returns limits when no data provided
76        norm = self.cb.getNormalize()
77        nt.assert_equal((norm.vmin, norm.vmax), self.colourBarRange)
78        #fixes the norm if the limits are given the wrong way round
79        self.cb.colourBarMin = self.colourBarRange[1]       
80        self.cb.colourBarMax = self.colourBarRange[0]       
81        norm = self.cb.getNormalize()
82        nt.assert_equal((norm.vmin, norm.vmax), self.colourBarRange)       
83       
84        #check returns None,None when no data and no limits
85        self.cb.colourBarMin = None
86        self.cb.colourBarMax = None
87        norm = self.cb.getNormalize()
88        nt.assert_equal((norm.vmin, norm.vmax), (None, None))
89       
90        #set up some mock data
91        grid = Mock(spec=Grid)
92        grid.values = Mock(spec=numpy.ndarray)
93        dMin = -10.0; dMax = 143.2
94        grid.values = numpy.array([-9.43, -10.0, 23.232, 143.2, 13.111])
95
96        #still returns set limits when data present
97        self.cb.colourBarMin = self.colourBarRange[0]       
98        self.cb.colourBarMax = self.colourBarRange[1]       
99        norm = self.cb.getNormalize(grid=grid)
100        nt.assert_equal((norm.vmin, norm.vmax), self.colourBarRange)
101       
102        #returns data minimum when colourBarMin = None
103        self.cb.colourBarMin = None
104        self.cb.colourBarMax = self.colourBarRange[1]
105        norm = self.cb.getNormalize(grid=grid)
106        nt.assert_equal((norm.vmin, norm.vmax), (dMin, self.colourBarRange[1]))
107       
108        #returns data maximum when colourBarMax = None
109        self.cb.colourBarMin = self.colourBarRange[0]
110        self.cb.colourBarMax = None
111        norm = self.cb.getNormalize(grid=grid)
112        nt.assert_equal((norm.vmin, norm.vmax), (self.colourBarRange[0], dMax))
113       
114        #returns data range when limits are both None
115        self.cb.colourBarMin = None
116        self.cb.colourBarMax = None
117        norm = self.cb.getNormalize(grid=grid)
118        nt.assert_equal((norm.vmin, norm.vmax), (dMin, dMax))
119       
120        #check it dosent fall over when data is all masked
121        grid.values = numpy.ma.MaskedArray([-9.43, -10.0, 23.232, 143.2, 13.111],
122                                    mask=[True, True, True, True, True])
123        dMin = numpy.ma.MaskedArray([0], mask=True)
124        dMax = numpy.ma.MaskedArray([0], mask=True)
125               
126        self.cb.colourBarMin = None
127        self.cb.colourBarMax = None
128       
129        #still returns 0,1 as the default
130        norm = self.cb.getNormalize(grid=grid)
131        nt.assert_equal((norm.vmin, norm.vmax), (None,None))
132       
133        #will still use limits when data is masked
134        self.cb.colourBarMin = self.colourBarRange[0]       
135        self.cb.colourBarMax = self.colourBarRange[1]
136        norm = self.cb.getNormalize(grid=grid)
137        nt.assert_equal((norm.vmin, norm.vmax), self.colourBarRange)
138       
139
140    #position ticks (if
141    def te_st_012_repositionsTicksToDiscreteCmapBounds(self):
142        #create a 6 element discreet colour map
143        cmap = geoplot.utils.generateDiscreteCmap(
144           [(0,0,0), (20,20,20), (40,40,40), (60,60,60), (80,80,80)], "temp")
145        #create a mock colour bar, decided not to use a real one as it would
146        #involve setting up a figure and an axis
147        mcb = MockColourBar(0,6,cmap)
148
149        #make sure the max ticks is 10
150        geoplot.colour_bar.MAX_CBAR_TICKS = 10
151
152        ColourBar._repositionColourBarTicks(mcb)
153
154        #check the formatter and the locator have been set correctly and that
155        #the .draw_all function has been called
156        assert(mcb.locator.__class__ == matplotlib.ticker.FixedLocator)
157        assert(mcb.formatter.__class__ == matplotlib.ticker.FormatStrFormatter)
158        assert(mcb.redrawn == True)
159        assert(geoplot.tests.test_utils._areNumericListsEqual(mcb.locator.locs,
160                                                [0.0, 1.2, 2.4, 3.6, 4.8, 6.0]))
161       
162
163    def test_013_raiseErrorWhenSettingInvalidPositionValue(self):
164        nose.tools.assert_raises(ValueError, setattr, self.cb, 'colourBarPosition', 'sideways')
165
166       
167def not_a_method():
168    raise Exception("Not a method!")
169
170
171class MockColourBar:
172    def __init__(self, vmin, vmax, cmap):
173        self.vmin = vmin
174        self.vmax = vmax
175        self.cmap = cmap
176        self.locator = None
177        self.formatter = None
178        self.redrawn = False
179        self.outline = MockOutline()
180        self.ax = MockAxes()
181
182    def draw_all(self):
183        self.redrawn = True
184
185class MockAxes(object):
186    def __init__(self):
187        self.yaxis = MockAxis()
188        self.xaxis = MockAxis()
189
190class MockOutline(object):
191    def __init__(self):
192        self.linewidth = None
193       
194    def set_linewidth(self, value):
195        self.linewidth = value
196
197class MockAxis(object):
198    def __init__(self):
199        self._tickPosition = "default"
200   
201    def get_ticks_position(self):
202        return self._tickPosition
203
204    def set_ticks_position(self, val):
205        self._tickPosition = val
206
207if __name__ == '__main__':
208
209    nose.runmodule()
210   
Note: See TracBrowser for help on using the repository browser.