Coverage for tests / test_plotting_limits.py: 32%
112 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-28 08:31 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-28 08:31 +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/>.
22import unittest
24import numpy as np
26from lsst.utils.plotting.limits import calculate_safe_plotting_limits, make_calculate_safe_plotting_limits
29class PlottingLimitsClosureTestCase(unittest.TestCase):
30 """Tests for `make_calculate_safe_plotting_limits` function."""
32 xs = np.linspace(0, 10, 10000)
33 series1 = np.sin(xs + 3.1415 / 2) + 0.75 # min=-0.24999, max=1.74999
34 series1_min = min(series1)
35 series1_max = max(series1)
37 series2 = np.sin(xs) + 1.2 # min=0.2, max=2.19999
38 series2_min = min(series2)
39 series2_max = max(series2)
41 outliers = series1[:]
42 outliers[1000] = 20
43 outliers[2000] = -1000
45 def testSingleSeries(self):
46 """Test that a single series works and the outliers exclusion works."""
47 # Deliberately test the bounds are the same when using the series
48 # itself, and the copy with the outlier values, i.e. using
49 # self.series1_min/max inside the loop despite changing the series we
50 # loop over is the intent here, not a bug.
51 for series in [self.series1, self.outliers]:
52 ymin, ymax = make_calculate_safe_plotting_limits()(series)
53 self.assertLess(ymin, self.series1_min)
54 self.assertGreater(ymin, self.series1_min - 1)
55 self.assertLess(ymax, self.series1_max + 1)
56 self.assertGreater(ymax, self.series1_max)
58 def testMultipleSeries(self):
59 """Test that passing multiple several series in works wrt outliers."""
60 calculate_safe_plotting_limits_accumulator = make_calculate_safe_plotting_limits()
61 _, _ = calculate_safe_plotting_limits_accumulator(self.series1)
62 ymin, ymax = calculate_safe_plotting_limits_accumulator(self.outliers)
64 self.assertLess(ymin, self.series1_min)
65 self.assertGreater(ymin, self.series1_min - 1)
66 self.assertLess(ymax, self.series1_max + 1)
67 self.assertGreater(ymax, self.series1_max)
69 def testMultipleSeriesCommonRange(self):
70 """Test that passing multiple several series in works wrt outliers."""
71 calculate_safe_plotting_limits_accumulator = make_calculate_safe_plotting_limits()
72 _, _ = calculate_safe_plotting_limits_accumulator(self.series1)
73 ymin, ymax = calculate_safe_plotting_limits_accumulator(self.series2)
74 # lower bound less than the lowest of the two
75 self.assertLess(ymin, min(self.series1_min, self.series2_min))
76 # lower bound less than the lowest of the two, but not by much
77 self.assertGreater(ymin, min(self.series1_min, self.series2_min) - 1)
78 # upper bound greater than the highest of the two
79 self.assertGreater(ymax, max(self.series1_max, self.series2_max))
80 # upper bound greater than the highest of the two, but not by much
81 self.assertLess(ymax, max(self.series1_max, self.series2_max) + 1)
83 def testSymmetric(self):
84 """Test that the symmetric option works."""
85 calc = make_calculate_safe_plotting_limits(symmetric_around_zero=True)
86 _, _ = calc(self.series1)
87 ymin, ymax = calc(self.outliers)
89 self.assertEqual(ymin, -ymax)
90 self.assertGreater(ymax, self.series1_max)
91 self.assertLess(ymin, self.series1_min)
93 def testConstantExtra(self):
94 """Test that the constantExtra option works."""
95 calc = make_calculate_safe_plotting_limits(constant_extra=0)
96 _, _ = calc(self.series1)
97 strictMin, strictMax = calc(self.outliers)
99 self.assertAlmostEqual(strictMin, self.series1_min, places=4)
100 self.assertAlmostEqual(strictMax, self.series1_max, places=4)
102 for extra in [-2.123, -1, 0, 1, 1.5, 23]:
103 calc = make_calculate_safe_plotting_limits(constant_extra=extra)
104 _, _ = calc(self.series1)
105 ymin, ymax = calc(self.outliers)
107 self.assertAlmostEqual(ymin, self.series1_min - extra, places=4)
108 self.assertAlmostEqual(ymax, self.series1_max + extra, places=4)
110 def testSeriesOfSeries(self):
111 """Test that we can pass a list of series to the accumulator in one."""
112 calculate_safe_plotting_limits_accumulator = make_calculate_safe_plotting_limits()
113 ymin, ymax = calculate_safe_plotting_limits_accumulator([self.series1, self.outliers])
115 self.assertLess(ymin, self.series1_min)
116 self.assertGreater(ymin, self.series1_min - 1)
117 self.assertLess(ymax, self.series1_max + 1)
118 self.assertGreater(ymax, self.series1_max)
120 def testRaises(self):
121 with self.assertRaises(TypeError):
122 make_calculate_safe_plotting_limits()(1.234)
125class PlottingLimitsTestCase(unittest.TestCase):
126 """Tests for `calculate_safe_plotting_limits` function."""
128 xs = np.linspace(0, 10, 10000)
129 series1 = np.sin(xs + 3.1415 / 2) + 0.75 # min=-0.24999, max=1.74999
130 series1_min = min(series1)
131 series1_max = max(series1)
133 series2 = np.sin(xs) + 1.2 # min=0.2, max=2.19999
134 series2_min = min(series2)
135 series2_max = max(series2)
137 outliers = series1[:]
138 outliers[1000] = 20
139 outliers[2000] = -1000
141 def testSingleSeries(self):
142 """Test that a single series works and the outliers exclusion works."""
143 # Deliberately test the bounds are the same when using the series
144 # itself, and the copy with the outlier values, i.e. using
145 # self.series1_min/max inside the loop despite changing the series we
146 # loop over is the intent here, not a bug.
147 for series in [self.series1, self.outliers]:
148 ymin, ymax = calculate_safe_plotting_limits(series)
149 self.assertLess(ymin, self.series1_min)
150 self.assertGreater(ymin, self.series1_min - 1)
151 self.assertLess(ymax, self.series1_max + 1)
152 self.assertGreater(ymax, self.series1_max)
154 def testMultipleSeries(self):
155 """Test that passing multiple several series in works wrt outliers."""
156 ymin, ymax = calculate_safe_plotting_limits([self.series1, self.outliers])
157 self.assertLess(ymin, self.series1_min)
158 self.assertGreater(ymin, self.series1_min - 1)
159 self.assertLess(ymax, self.series1_max + 1)
160 self.assertGreater(ymax, self.series1_max)
162 def testMultipleSeriesCommonRange(self):
163 """Test that passing multiple several series in works wrt outliers."""
164 ymin, ymax = calculate_safe_plotting_limits([self.series1, self.series2])
165 # lower bound less than the lowest of the two
166 self.assertLess(ymin, min(self.series1_min, self.series2_min))
167 # lower bound less than the lowest of the two, but not by much
168 self.assertGreater(ymin, min(self.series1_min, self.series2_min) - 1)
169 # upper bound greater than the highest of the two
170 self.assertGreater(ymax, max(self.series1_max, self.series2_max))
171 # upper bound greater than the highest of the two, but not by much
172 self.assertLess(ymax, max(self.series1_max, self.series2_max) + 1)
174 def testSymmetric(self):
175 """Test that the symmetric option works."""
176 ymin, ymax = calculate_safe_plotting_limits([self.series1, self.outliers], symmetric_around_zero=True)
177 self.assertEqual(ymin, -ymax)
178 self.assertGreater(ymax, self.series1_max)
179 self.assertLess(ymin, self.series1_min)
181 def testConstantExtra(self):
182 """Test that the constantExtra option works."""
183 strictMin, strictMax = calculate_safe_plotting_limits([self.series1, self.outliers], constant_extra=0)
184 self.assertAlmostEqual(strictMin, self.series1_min, places=4)
185 self.assertAlmostEqual(strictMax, self.series1_max, places=4)
187 for extra in [-2.123, -1, 0, 1, 1.5, 23]:
188 ymin, ymax = calculate_safe_plotting_limits([self.series1, self.outliers], constant_extra=extra)
189 self.assertAlmostEqual(ymin, self.series1_min - extra, places=4)
190 self.assertAlmostEqual(ymax, self.series1_max + extra, places=4)
192 def testRaises(self):
193 with self.assertRaises(TypeError):
194 calculate_safe_plotting_limits(1.234)
197if __name__ == "__main__":
198 unittest.main()