cloudnetpy 1.56.8__py3-none-any.whl → 1.56.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cloudnetpy/plotting/__init__.py +1 -1
- cloudnetpy/plotting/plot_meta.py +2 -2
- cloudnetpy/plotting/plotting.py +65 -40
- cloudnetpy/version.py +1 -1
- {cloudnetpy-1.56.8.dist-info → cloudnetpy-1.56.9.dist-info}/METADATA +1 -1
- {cloudnetpy-1.56.8.dist-info → cloudnetpy-1.56.9.dist-info}/RECORD +9 -9
- {cloudnetpy-1.56.8.dist-info → cloudnetpy-1.56.9.dist-info}/LICENSE +0 -0
- {cloudnetpy-1.56.8.dist-info → cloudnetpy-1.56.9.dist-info}/WHEEL +0 -0
- {cloudnetpy-1.56.8.dist-info → cloudnetpy-1.56.9.dist-info}/top_level.txt +0 -0
cloudnetpy/plotting/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
from .plot_meta import PlotMeta
|
2
|
-
from .plotting import PlotParameters, generate_figure, plot_2d
|
2
|
+
from .plotting import Dimensions, PlotParameters, generate_figure, plot_2d
|
cloudnetpy/plotting/plot_meta.py
CHANGED
@@ -15,8 +15,8 @@ class PlotMeta(NamedTuple):
|
|
15
15
|
plot_range: The range of values to be plotted. It can be a tuple
|
16
16
|
containing the minimum and maximum values, or None if the range should
|
17
17
|
be automatically determined.
|
18
|
-
log_scale: Whether to
|
19
|
-
moving_average: Whether to
|
18
|
+
log_scale: Whether to plot data values in a logarithmic scale.
|
19
|
+
moving_average: Whether to plot a moving average in a 1d plot.
|
20
20
|
contour: Whether to plot contours on top of a filled colormap.
|
21
21
|
"""
|
22
22
|
|
cloudnetpy/plotting/plotting.py
CHANGED
@@ -34,7 +34,8 @@ class PlotParameters:
|
|
34
34
|
mark_data_gaps: Whether to mark data gaps in the plot.
|
35
35
|
grid: Whether to display grid lines in the plot.
|
36
36
|
edge_tick_labels: Whether to display tick labels on the edges of the plot.
|
37
|
-
show_sources: Whether to display the sources of plotted data.
|
37
|
+
show_sources: Whether to display the sources of plotted data (i.e.
|
38
|
+
instruments and model).
|
38
39
|
footer_text: The text to display in the footer of the plot.
|
39
40
|
plot_meta: Additional metadata for the plot.
|
40
41
|
"""
|
@@ -52,14 +53,20 @@ class PlotParameters:
|
|
52
53
|
|
53
54
|
|
54
55
|
class Dimensions:
|
55
|
-
"""
|
56
|
+
"""
|
57
|
+
Dimensions of a generated figure in pixels. Elements such as the figure
|
58
|
+
title, labels, colorbar and legend are exluded from the margins.
|
56
59
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
Attributes:
|
61
|
+
width (int): Figure width in pixels.
|
62
|
+
height (int): Figure height in pixels.
|
63
|
+
margin_top (int): Space between top edge of image and plotted data in pixels.
|
64
|
+
margin_right (int): Space between right edge of image and plotted data
|
65
|
+
in pixels.
|
66
|
+
margin_bottom (int): Space between bottom edge of image and plotted
|
67
|
+
data in pixels.
|
68
|
+
margin_left (int): Space between left edge of image and plotted data in pixels.
|
69
|
+
"""
|
63
70
|
|
64
71
|
def __init__(self, fig, axes, pad_inches: float | None = None):
|
65
72
|
if pad_inches is None:
|
@@ -284,7 +291,7 @@ class Plot:
|
|
284
291
|
self._is_log = sub_plot.plot_meta.log_scale
|
285
292
|
self._ax = sub_plot.ax
|
286
293
|
|
287
|
-
def _convert_units(self) -> str
|
294
|
+
def _convert_units(self) -> str:
|
288
295
|
multiply, add = "multiply", "add"
|
289
296
|
units_conversion = {
|
290
297
|
"rainfall_rate": (multiply, 360000, "mm h$^{-1}$"),
|
@@ -303,6 +310,7 @@ class Plot:
|
|
303
310
|
self._data += conversion
|
304
311
|
self._data_orig += conversion
|
305
312
|
if units is not None:
|
313
|
+
self._plot_meta = self._plot_meta._replace(clabel=units)
|
306
314
|
return units
|
307
315
|
units = getattr(self.sub_plot.variable, "units", "")
|
308
316
|
return _reformat_units(units)
|
@@ -509,6 +517,28 @@ class Plot2D(Plot):
|
|
509
517
|
|
510
518
|
|
511
519
|
class Plot1D(Plot):
|
520
|
+
def plot(self, figure_data: FigureData) -> None:
|
521
|
+
units = self._convert_units()
|
522
|
+
self._mark_gaps(figure_data)
|
523
|
+
self._ax.plot(
|
524
|
+
figure_data.time_including_gaps,
|
525
|
+
self._data,
|
526
|
+
label="_nolegend_",
|
527
|
+
**self._get_plot_options(),
|
528
|
+
zorder=_get_zorder("data"),
|
529
|
+
)
|
530
|
+
if self._plot_meta.moving_average:
|
531
|
+
self._plot_moving_average(figure_data)
|
532
|
+
self._fill_between_data_gaps(figure_data)
|
533
|
+
self.sub_plot.set_yax(ylabel=units, y_limits=self._get_y_limits())
|
534
|
+
pos = self._ax.get_position()
|
535
|
+
self._ax.set_position((pos.x0, pos.y0, pos.width * 0.965, pos.height))
|
536
|
+
if figure_data.is_mwrpy_product():
|
537
|
+
flags = self._read_flagged_data(figure_data)
|
538
|
+
if np.any(flags):
|
539
|
+
self._plot_flag_data(figure_data.time[flags], self._data_orig[flags])
|
540
|
+
self._add_legend()
|
541
|
+
|
512
542
|
def plot_tb(self, figure_data: FigureData, freq_ind: int) -> None:
|
513
543
|
self._data = self._data[:, freq_ind]
|
514
544
|
self._data_orig = self._data_orig[:, freq_ind]
|
@@ -518,11 +548,28 @@ class Plot1D(Plot):
|
|
518
548
|
flags = self._read_flagged_data(figure_data)[:, freq_ind]
|
519
549
|
flags[is_bad_zenith] = False
|
520
550
|
if np.any(flags):
|
521
|
-
self.
|
522
|
-
self.
|
551
|
+
self._plot_flag_data(figure_data.time[flags], self._data_orig[flags])
|
552
|
+
self._add_legend()
|
523
553
|
self.plot(figure_data)
|
554
|
+
self._show_frequency(figure_data, freq_ind)
|
555
|
+
|
556
|
+
def _show_frequency(self, figure_data: FigureData, freq_ind: int) -> None:
|
557
|
+
frequency = figure_data.file.variables["frequency"][freq_ind]
|
558
|
+
self._ax.text(
|
559
|
+
0.0,
|
560
|
+
-0.13,
|
561
|
+
f"Freq: {frequency:.2f} GHz",
|
562
|
+
transform=self._ax.transAxes,
|
563
|
+
fontsize=12,
|
564
|
+
color="dimgrey",
|
565
|
+
bbox={
|
566
|
+
"facecolor": "white",
|
567
|
+
"linewidth": 0,
|
568
|
+
"boxstyle": "round",
|
569
|
+
},
|
570
|
+
)
|
524
571
|
|
525
|
-
def
|
572
|
+
def _plot_flag_data(self, time: ndarray, values: ndarray) -> None:
|
526
573
|
self._ax.plot(
|
527
574
|
time,
|
528
575
|
values,
|
@@ -533,7 +580,7 @@ class Plot1D(Plot):
|
|
533
580
|
zorder=_get_zorder("flags"),
|
534
581
|
)
|
535
582
|
|
536
|
-
def
|
583
|
+
def _add_legend(self) -> None:
|
537
584
|
self._ax.legend(
|
538
585
|
["Flagged data"],
|
539
586
|
markerscale=3,
|
@@ -541,28 +588,6 @@ class Plot1D(Plot):
|
|
541
588
|
frameon=False,
|
542
589
|
)
|
543
590
|
|
544
|
-
def plot(self, figure_data: FigureData) -> None:
|
545
|
-
units = self._convert_units()
|
546
|
-
self._mark_gaps(figure_data)
|
547
|
-
self._ax.plot(
|
548
|
-
figure_data.time_including_gaps,
|
549
|
-
self._data,
|
550
|
-
label="_nolegend_",
|
551
|
-
**self._get_plot_options(),
|
552
|
-
zorder=_get_zorder("data"),
|
553
|
-
)
|
554
|
-
if self._plot_meta.moving_average:
|
555
|
-
self._plot_moving_average(figure_data)
|
556
|
-
self._fill_between_data_gaps(figure_data)
|
557
|
-
self.sub_plot.set_yax(ylabel=units, y_limits=self._get_y_limits())
|
558
|
-
pos = self._ax.get_position()
|
559
|
-
self._ax.set_position((pos.x0, pos.y0, pos.width * 0.965, pos.height))
|
560
|
-
if figure_data.is_mwrpy_product():
|
561
|
-
flags = self._read_flagged_data(figure_data)
|
562
|
-
if np.any(flags):
|
563
|
-
self.plot_flag_data(figure_data.time[flags], self._data_orig[flags])
|
564
|
-
self.add_legend()
|
565
|
-
|
566
591
|
def _get_y_limits(self) -> tuple[float, float]:
|
567
592
|
percent_gap = 0.05
|
568
593
|
fallback = (-percent_gap, percent_gap)
|
@@ -597,11 +622,6 @@ class Plot1D(Plot):
|
|
597
622
|
|
598
623
|
return default_options
|
599
624
|
|
600
|
-
@staticmethod
|
601
|
-
def _get_line_width(time: ndarray) -> float:
|
602
|
-
line_width = np.median(np.diff(time)) * 1000
|
603
|
-
return min(max(line_width, 0.25), 0.9)
|
604
|
-
|
605
625
|
def _plot_moving_average(self, figure_data: FigureData) -> None:
|
606
626
|
time = figure_data.time.copy()
|
607
627
|
data = self._data_orig.copy()
|
@@ -620,6 +640,11 @@ class Plot1D(Plot):
|
|
620
640
|
zorder=_get_zorder("mean_curve"),
|
621
641
|
)
|
622
642
|
|
643
|
+
@staticmethod
|
644
|
+
def _get_line_width(time: ndarray) -> float:
|
645
|
+
line_width = np.median(np.diff(time)) * 1000
|
646
|
+
return min(max(line_width, 0.25), 0.9)
|
647
|
+
|
623
648
|
@staticmethod
|
624
649
|
def _get_unmasked_values(
|
625
650
|
data: ma.MaskedArray,
|
cloudnetpy/version.py
CHANGED
@@ -8,7 +8,7 @@ cloudnetpy/metadata.py,sha256=Bcu1a9UyUq61jomuZ0_6hYIOzf61e5qCXeiwLm46ikw,5040
|
|
8
8
|
cloudnetpy/output.py,sha256=jD1pfBb4OQhVOrlhPEk-8FAi4bUW7zjAL468r6BPkJg,14586
|
9
9
|
cloudnetpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
cloudnetpy/utils.py,sha256=yY5a5HLuAks2uzA4XbbqsGFEmXoyqECn_TjD3sMa0lI,27193
|
11
|
-
cloudnetpy/version.py,sha256=
|
11
|
+
cloudnetpy/version.py,sha256=L5yTOc1IUQ52ak-q9sb2zqco0z_mepJx_hFuzl6k6JY,72
|
12
12
|
cloudnetpy/categorize/__init__.py,sha256=gP5q3Vis1y9u9OWgA_idlbjfWXYN_S0IBSWdwBhL_uU,69
|
13
13
|
cloudnetpy/categorize/atmos.py,sha256=cax3iRmvr7S-VkUZqz0JCfAN3WEsUVbGfH4zSHy1APo,12384
|
14
14
|
cloudnetpy/categorize/atmos_utils.py,sha256=wndpwJxc2-QnNTkV8tc8I11Vs_WkNz9sVMX1fuGgUC4,3777
|
@@ -90,9 +90,9 @@ cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py,sha256=YeeJdS2JO5F645z
|
|
90
90
|
cloudnetpy/model_evaluation/tests/unit/test_plotting.py,sha256=h9V8JKmrO4v9bOvv-UjRa06sZJQPhDNVHGBSImDdtkI,3277
|
91
91
|
cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py,sha256=Ra3r4V0qbqkpDuaTYvEIbaasl0nZ5gmTLR4eGC0glBQ,9724
|
92
92
|
cloudnetpy/model_evaluation/tests/unit/test_tools.py,sha256=Ia_VrLdV2NstX5gbx_3AZTOAlrgLAy_xFZ8fHYVX0xI,3817
|
93
|
-
cloudnetpy/plotting/__init__.py,sha256=
|
94
|
-
cloudnetpy/plotting/plot_meta.py,sha256=
|
95
|
-
cloudnetpy/plotting/plotting.py,sha256=
|
93
|
+
cloudnetpy/plotting/__init__.py,sha256=lg9Smn4BI0dVBgnDLC3JVJ4GmwoSnO-qoSd4ApvwV6Y,107
|
94
|
+
cloudnetpy/plotting/plot_meta.py,sha256=NWI8ECKMypN5YyM9XKCAp1WEthbFlKMvilxqXmYSEK4,14631
|
95
|
+
cloudnetpy/plotting/plotting.py,sha256=AU7WWEfemlXXQ17IgybagQMx8JRJBF4y9DSv5DF_2Ho,30683
|
96
96
|
cloudnetpy/products/__init__.py,sha256=2hRb5HG9hNrxH1if5laJkLeFeaZCd5W1q3hh4ewsX0E,273
|
97
97
|
cloudnetpy/products/classification.py,sha256=J_FOMUSyxvFaT-hvdKVVcKPtuQ0u3V9PsV5xaIKzMjg,7843
|
98
98
|
cloudnetpy/products/der.py,sha256=HAdPvbJySEqkIwDrdZDPnli_wnN2qwm72_D1a82ZWIs,12398
|
@@ -106,8 +106,8 @@ cloudnetpy/products/mie_lu_tables.nc,sha256=It4fYpqJXlqOgL8jeZ-PxGzP08PMrELIDVe5
|
|
106
106
|
cloudnetpy/products/mwr_tools.py,sha256=PRm5aCULccUehU-Byk55wYhhEHseMjoAjGBu5TSyHao,4621
|
107
107
|
cloudnetpy/products/product_tools.py,sha256=E8CSijBY8cr70BH2JFa0lGQ-RzI9EcHQ0Fzt8CQ8rY4,10442
|
108
108
|
docs/source/conf.py,sha256=IKiFWw6xhUd8NrCg0q7l596Ck1d61XWeVjIFHVSG9Og,1490
|
109
|
-
cloudnetpy-1.56.
|
110
|
-
cloudnetpy-1.56.
|
111
|
-
cloudnetpy-1.56.
|
112
|
-
cloudnetpy-1.56.
|
113
|
-
cloudnetpy-1.56.
|
109
|
+
cloudnetpy-1.56.9.dist-info/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
|
110
|
+
cloudnetpy-1.56.9.dist-info/METADATA,sha256=HgNqhO700XNh1uBoHccsDiA73n4R48XgLctfsB8Qczs,5733
|
111
|
+
cloudnetpy-1.56.9.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
112
|
+
cloudnetpy-1.56.9.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
|
113
|
+
cloudnetpy-1.56.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|