Coverage for tests/test_plotting_limits.py: 31%

112 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-03-20 10:50 +0000

1# This file is part of utils. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22import unittest 

23 

24import numpy as np 

25from lsst.utils.plotting.limits import calculate_safe_plotting_limits, make_calculate_safe_plotting_limits 

26 

27 

28class PlottingLimitsClosureTestCase(unittest.TestCase): 

29 """Tests for `make_calculate_safe_plotting_limits` function.""" 

30 

31 xs = np.linspace(0, 10, 10000) 

32 series1 = np.sin(xs + 3.1415 / 2) + 0.75 # min=-0.24999, max=1.74999 

33 series1_min = min(series1) 

34 series1_max = max(series1) 

35 

36 series2 = np.sin(xs) + 1.2 # min=0.2, max=2.19999 

37 series2_min = min(series2) 

38 series2_max = max(series2) 

39 

40 outliers = series1[:] 

41 outliers[1000] = 20 

42 outliers[2000] = -1000 

43 

44 def testSingleSeries(self): 

45 """Test that a single series works and the outliers exclusion works.""" 

46 # Deliberately test the bounds are the same when using the series 

47 # itself, and the copy with the outlier values, i.e. using 

48 # self.series1_min/max inside the loop despite changing the series we 

49 # loop over is the intent here, not a bug. 

50 for series in [self.series1, self.outliers]: 

51 ymin, ymax = make_calculate_safe_plotting_limits()(series) 

52 self.assertLess(ymin, self.series1_min) 

53 self.assertGreater(ymin, self.series1_min - 1) 

54 self.assertLess(ymax, self.series1_max + 1) 

55 self.assertGreater(ymax, self.series1_max) 

56 

57 def testMultipleSeries(self): 

58 """Test that passing multiple several series in works wrt outliers.""" 

59 calculate_safe_plotting_limits_accumulator = make_calculate_safe_plotting_limits() 

60 _, _ = calculate_safe_plotting_limits_accumulator(self.series1) 

61 ymin, ymax = calculate_safe_plotting_limits_accumulator(self.outliers) 

62 

63 self.assertLess(ymin, self.series1_min) 

64 self.assertGreater(ymin, self.series1_min - 1) 

65 self.assertLess(ymax, self.series1_max + 1) 

66 self.assertGreater(ymax, self.series1_max) 

67 

68 def testMultipleSeriesCommonRange(self): 

69 """Test that passing multiple several series in works wrt outliers.""" 

70 calculate_safe_plotting_limits_accumulator = make_calculate_safe_plotting_limits() 

71 _, _ = calculate_safe_plotting_limits_accumulator(self.series1) 

72 ymin, ymax = calculate_safe_plotting_limits_accumulator(self.series2) 

73 # lower bound less than the lowest of the two 

74 self.assertLess(ymin, min(self.series1_min, self.series2_min)) 

75 # lower bound less than the lowest of the two, but not by much 

76 self.assertGreater(ymin, min(self.series1_min, self.series2_min) - 1) 

77 # upper bound greater than the highest of the two 

78 self.assertGreater(ymax, max(self.series1_max, self.series2_max)) 

79 # upper bound greater than the highest of the two, but not by much 

80 self.assertLess(ymax, max(self.series1_max, self.series2_max) + 1) 

81 

82 def testSymmetric(self): 

83 """Test that the symmetric option works.""" 

84 calc = make_calculate_safe_plotting_limits(symmetric_around_zero=True) 

85 _, _ = calc(self.series1) 

86 ymin, ymax = calc(self.outliers) 

87 

88 self.assertEqual(ymin, -ymax) 

89 self.assertGreater(ymax, self.series1_max) 

90 self.assertLess(ymin, self.series1_min) 

91 

92 def testConstantExtra(self): 

93 """Test that the constantExtra option works.""" 

94 calc = make_calculate_safe_plotting_limits(constant_extra=0) 

95 _, _ = calc(self.series1) 

96 strictMin, strictMax = calc(self.outliers) 

97 

98 self.assertAlmostEqual(strictMin, self.series1_min, places=4) 

99 self.assertAlmostEqual(strictMax, self.series1_max, places=4) 

100 

101 for extra in [-2.123, -1, 0, 1, 1.5, 23]: 

102 calc = make_calculate_safe_plotting_limits(constant_extra=extra) 

103 _, _ = calc(self.series1) 

104 ymin, ymax = calc(self.outliers) 

105 

106 self.assertAlmostEqual(ymin, self.series1_min - extra, places=4) 

107 self.assertAlmostEqual(ymax, self.series1_max + extra, places=4) 

108 

109 def testSeriesOfSeries(self): 

110 """Test that we can pass a list of series to the accumulator in one.""" 

111 calculate_safe_plotting_limits_accumulator = make_calculate_safe_plotting_limits() 

112 ymin, ymax = calculate_safe_plotting_limits_accumulator([self.series1, self.outliers]) 

113 

114 self.assertLess(ymin, self.series1_min) 

115 self.assertGreater(ymin, self.series1_min - 1) 

116 self.assertLess(ymax, self.series1_max + 1) 

117 self.assertGreater(ymax, self.series1_max) 

118 

119 def testRaises(self): 

120 with self.assertRaises(TypeError): 

121 make_calculate_safe_plotting_limits()(1.234) 

122 

123 

124class PlottingLimitsTestCase(unittest.TestCase): 

125 """Tests for `calculate_safe_plotting_limits` function.""" 

126 

127 xs = np.linspace(0, 10, 10000) 

128 series1 = np.sin(xs + 3.1415 / 2) + 0.75 # min=-0.24999, max=1.74999 

129 series1_min = min(series1) 

130 series1_max = max(series1) 

131 

132 series2 = np.sin(xs) + 1.2 # min=0.2, max=2.19999 

133 series2_min = min(series2) 

134 series2_max = max(series2) 

135 

136 outliers = series1[:] 

137 outliers[1000] = 20 

138 outliers[2000] = -1000 

139 

140 def testSingleSeries(self): 

141 """Test that a single series works and the outliers exclusion works.""" 

142 # Deliberately test the bounds are the same when using the series 

143 # itself, and the copy with the outlier values, i.e. using 

144 # self.series1_min/max inside the loop despite changing the series we 

145 # loop over is the intent here, not a bug. 

146 for series in [self.series1, self.outliers]: 

147 ymin, ymax = calculate_safe_plotting_limits(series) 

148 self.assertLess(ymin, self.series1_min) 

149 self.assertGreater(ymin, self.series1_min - 1) 

150 self.assertLess(ymax, self.series1_max + 1) 

151 self.assertGreater(ymax, self.series1_max) 

152 

153 def testMultipleSeries(self): 

154 """Test that passing multiple several series in works wrt outliers.""" 

155 ymin, ymax = calculate_safe_plotting_limits([self.series1, self.outliers]) 

156 self.assertLess(ymin, self.series1_min) 

157 self.assertGreater(ymin, self.series1_min - 1) 

158 self.assertLess(ymax, self.series1_max + 1) 

159 self.assertGreater(ymax, self.series1_max) 

160 

161 def testMultipleSeriesCommonRange(self): 

162 """Test that passing multiple several series in works wrt outliers.""" 

163 ymin, ymax = calculate_safe_plotting_limits([self.series1, self.series2]) 

164 # lower bound less than the lowest of the two 

165 self.assertLess(ymin, min(self.series1_min, self.series2_min)) 

166 # lower bound less than the lowest of the two, but not by much 

167 self.assertGreater(ymin, min(self.series1_min, self.series2_min) - 1) 

168 # upper bound greater than the highest of the two 

169 self.assertGreater(ymax, max(self.series1_max, self.series2_max)) 

170 # upper bound greater than the highest of the two, but not by much 

171 self.assertLess(ymax, max(self.series1_max, self.series2_max) + 1) 

172 

173 def testSymmetric(self): 

174 """Test that the symmetric option works.""" 

175 ymin, ymax = calculate_safe_plotting_limits([self.series1, self.outliers], symmetric_around_zero=True) 

176 self.assertEqual(ymin, -ymax) 

177 self.assertGreater(ymax, self.series1_max) 

178 self.assertLess(ymin, self.series1_min) 

179 

180 def testConstantExtra(self): 

181 """Test that the constantExtra option works.""" 

182 strictMin, strictMax = calculate_safe_plotting_limits([self.series1, self.outliers], constant_extra=0) 

183 self.assertAlmostEqual(strictMin, self.series1_min, places=4) 

184 self.assertAlmostEqual(strictMax, self.series1_max, places=4) 

185 

186 for extra in [-2.123, -1, 0, 1, 1.5, 23]: 

187 ymin, ymax = calculate_safe_plotting_limits([self.series1, self.outliers], constant_extra=extra) 

188 self.assertAlmostEqual(ymin, self.series1_min - extra, places=4) 

189 self.assertAlmostEqual(ymax, self.series1_max + extra, places=4) 

190 

191 def testRaises(self): 

192 with self.assertRaises(TypeError): 

193 calculate_safe_plotting_limits(1.234) 

194 

195 

196if __name__ == "__main__": 

197 unittest.main()