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

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

Improved the colour bar code so it now accepts the data array instead of just a minimum + maximum. It also now defaults to creating a Normalize instance with vmin=None and vmax=None instead of 0 and 1.

Also modified the layer_drawer objects to use the ColourBar? class instead of implementing it themselves.

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