• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ghiggi / gpm_api / 8518249396

02 Apr 2024 06:11AM UTC coverage: 87.861% (+0.2%) from 87.669%
8518249396

push

github

ghiggi
Add and fix pydocstyle rules

28 of 29 new or added lines in 15 files covered. (96.55%)

534 existing lines in 45 files now uncovered.

9004 of 10248 relevant lines covered (87.86%)

0.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.63
/gpm/tests/test_visualization/test_plot.py
1
# -----------------------------------------------------------------------------.
2
# MIT License
3

4
# Copyright (c) 2024 GPM-API developers
5
#
6
# This file is part of GPM-API.
7

8
# Permission is hereby granted, free of charge, to any person obtaining a copy
9
# of this software and associated documentation files (the "Software"), to deal
10
# in the Software without restriction, including without limitation the rights
11
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
# copies of the Software, and to permit persons to whom the Software is
13
# furnished to do so, subject to the following conditions:
14
#
15
# The above copyright notice and this permission notice shall be included in all
16
# copies or substantial portions of the Software.
17
#
18
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
# SOFTWARE.
25

26
# -----------------------------------------------------------------------------.
27
import platform
1✔
28

29
import cartopy.crs as ccrs
1✔
30
import numpy as np
1✔
31
import pytest
1✔
32
import xarray as xr
1✔
33
from matplotlib import pyplot as plt
1✔
34

35
import gpm.configs
1✔
36
from gpm.tests.test_visualization.utils import (
1✔
37
    expand_dims,
38
    get_test_name,
39
    save_and_check_figure,
40
    skip_tests_if_no_data,
41
)
42
from gpm.visualization import plot
1✔
43

44
# Fixtures imported from gpm.tests.conftest:
45
# - orbit_dataarray
46
# - orbit_antimeridian_dataarray
47
# - orbit_pole_dataarray
48
# - orbit_nan_cross_track_dataarray
49
# - orbit_nan_along_track_dataarray
50
# - orbit_nan_lon_cross_track_dataarray
51
# - orbit_nan_lon_along_track_dataarray
52
# - grid_dataarray
53
# - grid_nan_lon_dataarray
54

55

56
pytestmark = pytest.mark.skipif(
1✔
57
    platform.system() == "Windows",
58
    reason="Minor figure differences on Windows",
59
)
60
skip_tests_if_no_data()
1✔
61

62

63
def test_is_generator() -> None:
1✔
64
    """Test the _is_generator function."""
65

66
    def generator():
1✔
UNCOV
67
        yield 1
×
68

69
    assert plot.is_generator(generator())
1✔
70
    assert plot.is_generator(i for i in range(10))
1✔
71
    assert not plot.is_generator([1, 2, 3])
1✔
72

73

74
def test_preprocess_figure_args() -> None:
1✔
75
    """Test the preprocess_figure_args function."""
76
    nothing = {}
1✔
77
    something = {"": 0}
1✔
78

79
    # Test with ax None
80
    _ = plot.preprocess_figure_args(None, fig_kwargs=nothing, subplot_kwargs=nothing)
1✔
81
    _ = plot.preprocess_figure_args(None, fig_kwargs=something, subplot_kwargs=nothing)
1✔
82
    _ = plot.preprocess_figure_args(None, fig_kwargs=nothing, subplot_kwargs=something)
1✔
83

84
    # Test with ax not None
85
    ax = plt.subplot()
1✔
86
    _ = plot.preprocess_figure_args(ax, fig_kwargs=nothing, subplot_kwargs=nothing)
1✔
87

88
    with pytest.raises(ValueError):
1✔
89
        plot.preprocess_figure_args(ax, fig_kwargs=something, subplot_kwargs=nothing)
1✔
90

91
    with pytest.raises(ValueError):
1✔
92
        plot.preprocess_figure_args(ax, fig_kwargs=nothing, subplot_kwargs=something)
1✔
93

94

95
class TestGetDataArrayExtent:
1✔
96
    """Test the get_extent function."""
1✔
97

98
    def test_orbit(
1✔
99
        self,
100
        orbit_dataarray: xr.DataArray,
101
    ) -> None:
102
        """Test getting the extent of orbit data."""
103
        returned_extent = plot.get_dataarray_extent(orbit_dataarray)
1✔
104
        expected_extent = (-2.77663454, 22.65579744, -3.53830585, 18.64709521)
1✔
105
        np.testing.assert_allclose(returned_extent, expected_extent, rtol=1e-9)
1✔
106

107
    def test_grid(
1✔
108
        self,
109
        grid_dataarray: xr.DataArray,
110
    ) -> None:
111
        """Test getting the extent of grid data."""
112
        returned_extent = plot.get_dataarray_extent(grid_dataarray)
1✔
113
        expected_extent = (-5, 20, -5, 15)
1✔
114
        assert returned_extent == expected_extent
1✔
115

116

117
def test_get_antimeridian_mask(
1✔
118
    orbit_antimeridian_dataarray: xr.DataArray,
119
) -> None:
120
    """Test the get_antimeridian_mask function."""
121
    lon = orbit_antimeridian_dataarray["lon"].data
1✔
122
    returned_mask = plot.get_antimeridian_mask(lon)
1✔
123
    # fmt: off
124
    expected_mask = np.array([
1✔
125
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
126
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
127
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
128
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
129
    ], dtype=bool)
130
    np.testing.assert_array_equal(returned_mask, expected_mask)
1✔
131

132

133
class TestPlotMap:
1✔
134
    """Test the plot_map function."""
1✔
135

136
    def test_orbit(
1✔
137
        self,
138
        orbit_dataarray: xr.DataArray,
139
    ) -> None:
140
        """Test plotting orbit data."""
141
        p = plot.plot_map(orbit_dataarray)
1✔
142
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
143

144
    def test_orbit_antimeridian(
1✔
145
        self,
146
        orbit_antimeridian_dataarray: xr.DataArray,
147
    ) -> None:
148
        """Test plotting orbit data going over the antimeridian."""
149
        p = plot.plot_map(orbit_antimeridian_dataarray)
1✔
150
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
151

152
    def test_orbit_antimeridian_recentered(
1✔
153
        self,
154
        orbit_antimeridian_dataarray: xr.DataArray,
155
    ) -> None:
156
        """Test plotting orbit data going over the antimeridian with recentering."""
157
        crs_proj = ccrs.PlateCarree(central_longitude=180)
1✔
158
        p = plot.plot_map(orbit_antimeridian_dataarray, subplot_kwargs={"projection": crs_proj})
1✔
159
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
160

161
    def test_orbit_antimeridian_projection(
1✔
162
        self,
163
        orbit_antimeridian_dataarray: xr.DataArray,
164
    ) -> None:
165
        """Test plotting orbit data going over the antimeridian on orthographic projection."""
166
        crs_proj = ccrs.Orthographic(180, 0)
1✔
167
        p = plot.plot_map(orbit_antimeridian_dataarray, subplot_kwargs={"projection": crs_proj})
1✔
168
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
169

170
    def test_orbit_antimeridian_not_masked_recentered(
1✔
171
        self,
172
        orbit_antimeridian_dataarray: xr.DataArray,
173
    ) -> None:
174
        """Test plotting orbit data going over the antimeridian without masking (recentered)."""
175
        crs_proj = ccrs.PlateCarree(central_longitude=180)
1✔
176
        with gpm.config.set({"viz_hide_antimeridian_data": False}):
1✔
177
            p = plot.plot_map(orbit_antimeridian_dataarray, subplot_kwargs={"projection": crs_proj})
1✔
178
            save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
179

180
    def test_orbit_pole(
1✔
181
        self,
182
        orbit_pole_dataarray: xr.DataArray,
183
    ) -> None:
184
        """Test plotting orbit data going over the south pole."""
185
        p = plot.plot_map(orbit_pole_dataarray)
1✔
186
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
187

188
    def test_orbit_pole_projection(
1✔
189
        self,
190
        orbit_pole_dataarray: xr.DataArray,
191
    ) -> None:
192
        """Test plotting orbit data going over the south pole on orthographic projection."""
193
        crs_proj = ccrs.Orthographic(0, -90)
1✔
194
        p = plot.plot_map(orbit_pole_dataarray, subplot_kwargs={"projection": crs_proj})
1✔
195
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
196

197
    ## Test data with nan
198

199
    def test_orbit_data_nan_cross_track(
1✔
200
        self,
201
        orbit_data_nan_cross_track_dataarray: xr.DataArray,
202
    ) -> None:
203
        """Test plotting orbit with NaN values in the data at cross-track edges."""
204
        p = plot.plot_map(orbit_data_nan_cross_track_dataarray)
1✔
205
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
206

207
    def test_orbit_data_nan_along_track(
1✔
208
        self,
209
        orbit_data_nan_along_track_dataarray: xr.DataArray,
210
    ) -> None:
211
        """Test plotting orbit with NaN values in the data at along-track edges."""
212
        p = plot.plot_map(orbit_data_nan_along_track_dataarray)
1✔
213
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
214

215
    def test_orbit_data_nan_values(
1✔
216
        self,
217
        orbit_dataarray: xr.DataArray,
218
    ) -> None:
219
        """Test plotting orbit with NaN values in the data at one cell."""
220
        orbit_dataarray.data[2, 2] = np.nan
1✔
221
        p = plot.plot_map(orbit_dataarray)
1✔
222
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
223

224
    #### Test with NaN coordinates
225

226
    def test_orbit_nan_coordinate_at_one_cell(
1✔
227
        self,
228
        orbit_dataarray: xr.DataArray,
229
    ) -> None:
230
        """Test plotting orbit data with NaN coordinates at one cell."""
231
        # NOTE: here we test linear interpolation of coordinates
232
        orbit_dataarray["lon"].data[1, 3] = np.nan
1✔
233
        orbit_dataarray["lat"].data[1, 3] = np.nan
1✔
234
        p = plot.plot_map(orbit_dataarray)
1✔
235
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
236

237
    @pytest.mark.skipif(platform.system() == "Windows", reason="Minor figure difference on Windows")
1✔
238
    def test_orbit_nan_coordinate_at_corners(
1✔
239
        self,
240
        orbit_dataarray: xr.DataArray,
241
    ) -> None:
242
        """Test plotting orbit data with NaN coordinates at the swath corners."""
243
        # NOTE: here we test nearest neighbour interpolation of coordinates
244
        orbit_dataarray["lon"].data[0:2, 0:2] = np.nan
1✔
245
        orbit_dataarray["lat"].data[0:2, 0:2] = np.nan
1✔
246
        p = plot.plot_map(orbit_dataarray)
1✔
247
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
248

249
    def test_orbit_nan_coordinate_at_cross_track_center(
1✔
250
        self,
251
        orbit_dataarray: xr.DataArray,
252
    ) -> None:
253
        """Test plotting orbit data with NaN coordinates at one cell on the cross-track centerline."""
254
        # NOTE: centerline used to identify contiguoues slices. So here assumed not contiguous.
255
        orbit_dataarray["lon"].data[2, 3] = np.nan
1✔
256
        orbit_dataarray["lat"].data[2, 3] = np.nan
1✔
257
        p = plot.plot_map(orbit_dataarray)
1✔
258
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
259

260
    def test_orbit_nan_outer_cross_track(
1✔
261
        self,
262
        orbit_nan_outer_cross_track_dataarray: xr.DataArray,
263
    ) -> None:
264
        """Test plotting orbit data with some NaN coordinates on the outer cross-track cells."""
265
        p = plot.plot_map(orbit_nan_outer_cross_track_dataarray)
1✔
266
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
267

268
    def test_orbit_nan_inner_cross_track(
1✔
269
        self,
270
        orbit_nan_inner_cross_track_dataarray: xr.DataArray,
271
    ) -> None:
272
        """Test plotting orbit data with all NaN coordinates on the outer cross-track cells."""
273
        p = plot.plot_map(orbit_nan_inner_cross_track_dataarray)
1✔
274
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
275

276
    def test_orbit_nan_slice_along_track(
1✔
277
        self,
278
        orbit_nan_slice_along_track_dataarray: xr.DataArray,
279
    ) -> None:
280
        """Test plotting orbit data with some NaN latitudes along-track."""
281
        p = plot.plot_map(orbit_nan_slice_along_track_dataarray)
1✔
282
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
283

284
    #### Test colorbar kwargs
285

286
    def test_orbit_cbar_kwargs(
1✔
287
        self,
288
        orbit_dataarray: xr.DataArray,
289
    ) -> None:
290
        """Test plotting orbit data with colorbar keyword arguments."""
291
        cbar_kwargs = {"ticks": [0.1, 0.2, 0.4, 0.6, 0.8], "ticklabels": [42.5, 43, 44, 45, 46]}
1✔
292

293
        p = plot.plot_map(orbit_dataarray, cbar_kwargs=cbar_kwargs)
1✔
294
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
295

296
    def test_orbit_horizontal_colorbar(
1✔
297
        self,
298
        orbit_dataarray: xr.DataArray,
299
    ) -> None:
300
        """Test plotting orbit data with a horizontal colorbar."""
301
        cbar_kwargs = {"orientation": "horizontal"}
1✔
302
        p = plot.plot_map(orbit_dataarray, cbar_kwargs=cbar_kwargs)
1✔
303
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
304

305
    def test_orbit_rgb(
1✔
306
        self,
307
        orbit_dataarray: xr.DataArray,
308
    ) -> None:
309
        """Test plotting orbit RGB data."""
310
        orbit_dataarray = expand_dims(orbit_dataarray, 3, dim="rgb", axis=2)
1✔
311
        p = plot.plot_map(orbit_dataarray, rgb=True)
1✔
312
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
313

314
    def test_orbit_rgba(
1✔
315
        self,
316
        orbit_dataarray: xr.DataArray,
317
    ) -> None:
318
        """Test plotting orbit RGBA data."""
319
        orbit_dataarray = expand_dims(orbit_dataarray, 4, dim="rgb", axis=2)
1✔
320
        p = plot.plot_map(orbit_dataarray, rgb=True)
1✔
321
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
322

323
    def test_orbit_rgb_antimeridian_recentered(
1✔
324
        self,
325
        orbit_antimeridian_dataarray: xr.DataArray,
326
    ) -> None:
327
        """Test plotting orbit RGB data going over the antimeridian without masking (recentered)."""
328
        orbit_dataarray = expand_dims(orbit_antimeridian_dataarray, 3, dim="rgb", axis=2)
1✔
329
        crs_proj = ccrs.PlateCarree(central_longitude=180)
1✔
330
        p = plot.plot_map(orbit_dataarray, subplot_kwargs={"projection": crs_proj}, rgb=True)
1✔
331
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
332

333
    def test_orbit_rgb_antimeridian_not_masked_recentered(
1✔
334
        self,
335
        orbit_antimeridian_dataarray: xr.DataArray,
336
    ) -> None:
337
        """Test plotting orbit RGB data going over the antimeridian without masking (recentered)."""
338
        orbit_dataarray = expand_dims(orbit_antimeridian_dataarray, 3, dim="rgb", axis=2)
1✔
339
        crs_proj = ccrs.PlateCarree(central_longitude=180)
1✔
340
        with gpm.config.set({"viz_hide_antimeridian_data": False}):
1✔
341
            p = plot.plot_map(orbit_dataarray, subplot_kwargs={"projection": crs_proj}, rgb=True)
1✔
342
            save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
343

344
    def test_orbit_rgb_invalid(
1✔
345
        self,
346
        orbit_dataarray: xr.DataArray,
347
    ) -> None:
348
        """Test plotting orbit data with RGB flag on non RGB data."""
349
        with pytest.raises(ValueError):
1✔
350
            plot.plot_map(orbit_dataarray, rgb=True)
1✔
351

352
    def test_orbit_invalid_values(
1✔
353
        self,
354
        orbit_dataarray: xr.DataArray,
355
    ) -> None:
356
        """Test plotting orbit data with some invalid values."""
357
        orbit_dataarray.data[1:4, 1:4] = np.nan
1✔
358
        p = plot.plot_map(orbit_dataarray)
1✔
359
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
360

361
    def test_grid(
1✔
362
        self,
363
        grid_dataarray: xr.DataArray,
364
    ) -> None:
365
        """Test plotting grid data."""
366
        p = plot.plot_map(grid_dataarray)
1✔
367
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
368

369
    def test_grid_nan_lon(
1✔
370
        self,
371
        grid_nan_lon_dataarray: xr.DataArray,
372
    ) -> None:
373
        """Test plotting grid data with NaN longitudes."""
374
        p = plot.plot_map(grid_nan_lon_dataarray)
1✔
375
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
376

377
    def test_grid_time_dim(
1✔
378
        self,
379
        grid_dataarray: xr.DataArray,
380
    ) -> None:
381
        """Test plotting grid data with time dimension."""
382
        grid_dataarray = expand_dims(grid_dataarray, 4, "time")
1✔
383
        with pytest.raises(ValueError):  # Expecting a 2D GPM field
1✔
384
            plot.plot_map(grid_dataarray)
1✔
385

386
    def test_invalid(
1✔
387
        self,
388
    ) -> None:
389
        """Test invalid data."""
390
        da = xr.DataArray()
1✔
391
        with pytest.raises(ValueError):
1✔
392
            plot.plot_map(da)
1✔
393

394

395
class TestPlotImage:
1✔
396
    """Test the plot_image function."""
1✔
397

398
    def test_orbit(
1✔
399
        self,
400
        orbit_dataarray: xr.DataArray,
401
    ) -> None:
402
        """Test plotting orbit data."""
403
        p = plot.plot_image(orbit_dataarray)
1✔
404
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
405

406
    def test_orbit_cbar_kwargs(
1✔
407
        self,
408
        orbit_dataarray: xr.DataArray,
409
    ) -> None:
410
        """Test plotting orbit data with colorbar keyword arguments."""
411
        cbar_kwargs = {"ticks": [0.1, 0.2, 0.4, 0.6, 0.8], "ticklabels": [42.5, 43, 44, 45, 46]}
1✔
412

413
        p = plot.plot_image(orbit_dataarray, cbar_kwargs=cbar_kwargs)
1✔
414
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
415

416
    def test_orbit_horizontal_colorbar(
1✔
417
        self,
418
        orbit_dataarray: xr.DataArray,
419
    ) -> None:
420
        """Test plotting orbit data with a horizontal colorbar."""
421
        cbar_kwargs = {"orientation": "horizontal"}
1✔
422
        p = plot.plot_image(orbit_dataarray, cbar_kwargs=cbar_kwargs)
1✔
423
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
424

425
    def test_orbit_no_cbar(
1✔
426
        self,
427
        orbit_dataarray: xr.DataArray,
428
    ) -> None:
429
        """Test plotting orbit data without colorbar."""
430
        p = plot.plot_image(orbit_dataarray, add_colorbar=False)
1✔
431
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
432

433
    def test_grid(
1✔
434
        self,
435
        grid_dataarray: xr.DataArray,
436
    ) -> None:
437
        """Test plotting grid data."""
438
        p = plot.plot_image(grid_dataarray)
1✔
439
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
440

441
    def test_invalid(
1✔
442
        self,
443
    ) -> None:
444
        """Test invalid data."""
445
        da = xr.DataArray()
1✔
446
        with pytest.raises(ValueError):
1✔
447
            plot.plot_image(da)
1✔
448

449

450
class TestPlotMapMesh:
1✔
451
    """Test the plot_map_mesh function."""
1✔
452

453
    def test_orbit(
1✔
454
        self,
455
        orbit_dataarray: xr.DataArray,
456
    ) -> None:
457
        """Test plotting orbit data."""
458
        p = plot.plot_map_mesh(orbit_dataarray)
1✔
459
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
460

461
    # def test_orbit_antimeridian(  # Does not work, issue in cartopy
462
    #     self,
463
    #     orbit_antimeridian_dataarray: xr.DataArray,
464
    # ) -> None:
465
    #     """Test plotting orbit data going over the antimeridian"""
466

467
    #     p = plot.plot_map_mesh(orbit_antimeridian_dataarray)
468
    #     save_and_check_figure(figure=p.figure, name=get_test_name())
469

470
    def test_orbit_antimeridian_projection(
1✔
471
        self,
472
        orbit_antimeridian_dataarray: xr.DataArray,
473
    ) -> None:
474
        """Test plotting orbit data going over the antimeridian on orthographic projection."""
475
        crs_proj = ccrs.Orthographic(180, 0)
1✔
476
        p = plot.plot_map_mesh(
1✔
477
            orbit_antimeridian_dataarray,
478
            subplot_kwargs={"projection": crs_proj},
479
        )
480
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
481

482
    def test_orbit_pole(
1✔
483
        self,
484
        orbit_pole_dataarray: xr.DataArray,
485
    ) -> None:
486
        """Test plotting orbit data going over the south pole."""
487
        p = plot.plot_map_mesh(orbit_pole_dataarray)
1✔
488
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
489

490
    def test_orbit_pole_projection(
1✔
491
        self,
492
        orbit_pole_dataarray: xr.DataArray,
493
    ) -> None:
494
        """Test plotting orbit data going over the south pole on orthographic projection."""
495
        crs_proj = ccrs.Orthographic(0, -90)
1✔
496
        p = plot.plot_map_mesh(orbit_pole_dataarray, subplot_kwargs={"projection": crs_proj})
1✔
497
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
498

499
    def test_grid(
1✔
500
        self,
501
        grid_dataarray: xr.DataArray,
502
    ) -> None:
503
        """Test plotting grid data."""
504
        p = plot.plot_map_mesh(grid_dataarray)
1✔
505
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
506

507
    def test_grid_nan_lon(
1✔
508
        self,
509
        grid_nan_lon_dataarray: xr.DataArray,
510
    ) -> None:
511
        """Test plotting grid data with NaN longitudes."""
512
        p = plot.plot_map_mesh(grid_nan_lon_dataarray)
1✔
513
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
514

515

516
class TestPlotMapMeshCentroids:
1✔
517
    """Test the plot_map_mesh_centroids function."""
1✔
518

519
    def test_orbit(
1✔
520
        self,
521
        orbit_dataarray: xr.DataArray,
522
    ) -> None:
523
        """Test plotting orbit data."""
524
        p = plot.plot_map_mesh_centroids(orbit_dataarray)
1✔
525
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
526

527
    def test_grid(
1✔
528
        self,
529
        grid_dataarray: xr.DataArray,
530
    ) -> None:
531
        """Test plotting grid data."""
532
        p = plot.plot_map_mesh_centroids(grid_dataarray)
1✔
533
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
534

535

536
class TestPlotLabels:
1✔
537
    """Test the plot_labels function."""
1✔
538

539
    label_name = "label"
1✔
540

541
    @pytest.fixture()
1✔
542
    def orbit_labels_dataarray(
1✔
543
        self,
544
        orbit_dataarray: xr.DataArray,
545
    ) -> xr.DataArray:
546
        """Create an orbit data array with label coordinates."""
547
        labels = np.random.randint(0, 10, orbit_dataarray.shape)
1✔
548
        return orbit_dataarray.assign_coords(
1✔
549
            {self.label_name: (("cross_track", "along_track"), labels)},
550
        )
551

552
    @pytest.fixture()
1✔
553
    def grid_labels_dataarray(
1✔
554
        self,
555
        grid_dataarray: xr.DataArray,
556
    ) -> xr.DataArray:
557
        """Create a grid data array with label coordinates."""
558
        labels = np.random.randint(0, 10, grid_dataarray.shape)
1✔
559
        return grid_dataarray.assign_coords({self.label_name: (("lat", "lon"), labels)})
1✔
560

561
    def test_orbit(
1✔
562
        self,
563
        orbit_labels_dataarray: xr.DataArray,
564
    ) -> None:
565
        """Test plotting orbit data."""
566
        p = plot.plot_labels(orbit_labels_dataarray, label_name=self.label_name)
1✔
567
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
568

569
    def test_orbit_dataset(
1✔
570
        self,
571
        orbit_labels_dataarray: xr.DataArray,
572
    ) -> None:
573
        """Test plotting orbit data from a dataset."""
574
        ds = xr.Dataset({self.label_name: orbit_labels_dataarray[self.label_name]})
1✔
575
        p = plot.plot_labels(ds, label_name=self.label_name)
1✔
576
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
577

578
    def test_orbit_labels_dataarray(
1✔
579
        self,
580
        orbit_labels_dataarray: xr.DataArray,
581
    ) -> None:
582
        """Test plotting orbit data from labels data array directly."""
583
        p = plot.plot_labels(orbit_labels_dataarray[self.label_name])
1✔
584
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
585

586
    def test_orbit_exceed_labels(
1✔
587
        self,
588
        orbit_labels_dataarray: xr.DataArray,
589
    ) -> None:
590
        """Test plotting orbit data with too many labels for colorbar."""
591
        p = plot.plot_labels(orbit_labels_dataarray, label_name=self.label_name, max_n_labels=5)
1✔
592
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
593

594
    def test_grid(
1✔
595
        self,
596
        grid_labels_dataarray: xr.DataArray,
597
    ) -> None:
598
        """Test plotting grid data."""
599
        p = plot.plot_labels(grid_labels_dataarray, label_name=self.label_name)
1✔
600
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
601

602
    @pytest.mark.usefixtures("_prevent_pyplot_show")
1✔
603
    def test_generator(
1✔
604
        self,
605
        orbit_labels_dataarray: xr.DataArray,
606
    ) -> None:
607
        """Test plotting orbit data form a generator."""
608
        da_list = [
1✔
609
            (0, orbit_labels_dataarray),
610
            (1, orbit_labels_dataarray),
611
        ]
612
        generator = (t for t in da_list)
1✔
613

614
        p = plot.plot_labels(generator, label_name=self.label_name)  # only last plot is returned
1✔
615
        save_and_check_figure(figure=p.figure, name=get_test_name())
1✔
616

617

618
class TestPlotPatches:
1✔
619
    """Test the plot_patches function."""
1✔
620

621
    @pytest.mark.usefixtures("_prevent_pyplot_show")
1✔
622
    def test_orbit(
1✔
623
        self,
624
        orbit_dataarray: xr.DataArray,
625
    ) -> None:
626
        """Test plotting orbit data."""
627
        da_list = [
1✔
628
            (0, orbit_dataarray),
629
            (1, orbit_dataarray),
630
        ]
631
        generator = (t for t in da_list)
1✔
632
        plot.plot_patches(generator)  # does not return plotter
1✔
633
        save_and_check_figure(name=get_test_name())
1✔
634

635
    @pytest.mark.usefixtures("_prevent_pyplot_show")
1✔
636
    def test_orbit_dataset(
1✔
637
        self,
638
        orbit_dataarray: xr.DataArray,
639
    ) -> None:
640
        """Test plotting orbit data from a dataset."""
641
        variable_name = "variable"
1✔
642
        ds = xr.Dataset({variable_name: orbit_dataarray})
1✔
643
        ds_list = [
1✔
644
            (0, ds),
645
            (1, ds),
646
        ]
647
        generator = (t for t in ds_list)
1✔
648

649
        # Test with missing variable
650
        with pytest.raises(ValueError):
1✔
651
            plot.plot_patches(generator)
1✔
652

653
        plot.plot_patches(generator, variable=variable_name)  # does not return plotter
1✔
654
        save_and_check_figure(name=get_test_name())
1✔
655

656
    @pytest.mark.usefixtures("_prevent_pyplot_show")
1✔
657
    def test_grid(
1✔
658
        self,
659
        grid_dataarray: xr.DataArray,
660
    ) -> None:
661
        """Test plotting grid data."""
662
        da_list = [
1✔
663
            (0, grid_dataarray),
664
            (1, grid_dataarray),
665
        ]
666
        generator = (t for t in da_list)
1✔
667
        plot.plot_patches(generator)  # does not return plotter
1✔
668
        save_and_check_figure(name=get_test_name())
1✔
669

670
    def test_invalid(
1✔
671
        self,
672
    ) -> None:
673
        """Test invalid data."""
674
        invalid_list = [
1✔
675
            (0, xr.DataArray()),
676
            (1, xr.DataArray()),
677
        ]
678
        generator = (t for t in invalid_list)
1✔
679
        plot.plot_patches(generator)  # passes without error
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc