Skip to content

Plotting

Image

This module is used to plot an image (time, altitude) for a given variable of an instance of the ProfilesData class.

plot(da, var='attenuated_backscatter_0', zref='agl', zmin=None, zmax=None, vmin=None, vmax=None, log=False, show_foc=False, show_pbl=False, show_clouds=False, cmap='coolwarm', show_fig=True, save_fig=None)

Plot image of selected variable from :class:aprofiles.profiles.ProfilesData object.

Parameters:

Name Type Description Default
da DataArray

DataArray.

required
var str

Variable of the DataArray to be plotted.

'attenuated_backscatter_0'
zref {agl, asl}

Base reference for altitude axis.

'agl'
zmin float

Minimum altitude AGL (m).

None
zmax float

Maximum altitude AGL (m).

None
vmin float

Minimum value.

None
vmax float

Maximum value. If None, calculates max from data.

None
log bool

Use logarithmic scale.

False
show_foc bool

Add foc detection.

False
show_pbl bool

Add PBL height.

False
show_clouds bool

Add clouds detection.

False
cmap str

Matplotlib colormap.

'coolwarm'
show_fig bool

Show figure.

True
save_fig str

Path of the saved figure.

None
Example

import aprofiles as apro
# read example file
path = "examples/data/L2_0-20000-001492_A20210909.nc"
reader = apro.reader.ReadProfiles(path)
profiles = reader.read()
# attenuated backscatter image
profiles.plot(vmin=1e-2, vmax=1e1, log=True)
Image of attenuated backscatter profiles

Source code in aprofiles/plot/image.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
def plot(
    da,
    var="attenuated_backscatter_0",
    zref="agl",
    zmin=None,
    zmax=None,
    vmin=None,
    vmax=None,
    log=False,
    show_foc=False,
    show_pbl=False,
    show_clouds=False,
    cmap="coolwarm",
    show_fig=True,
    save_fig = None
):
    """Plot image of selected variable from :class:`aprofiles.profiles.ProfilesData` object.

    Args:
        da (xarray.DataArray): DataArray.
        var (str, optional): Variable of the DataArray to be plotted.
        zref ({'agl', 'asl'}, optional): Base reference for altitude axis.
        zmin (float, optional): Minimum altitude AGL (m).
        zmax (float, optional): Maximum altitude AGL (m).
        vmin (float, optional): Minimum value.
        vmax (float, optional): Maximum value. If `None`, calculates max from data.
        log (bool, optional): Use logarithmic scale.
        show_foc (bool, optional): Add foc detection.
        show_pbl (bool, optional): Add PBL height.
        show_clouds (bool, optional): Add clouds detection.
        cmap (str, optional): Matplotlib colormap.
        show_fig (bool, optional): Show figure.
        save_fig (str, optional): Path of the saved figure.

    Example:
        ``` python
        import aprofiles as apro
        # read example file
        path = "examples/data/L2_0-20000-001492_A20210909.nc"
        reader = apro.reader.ReadProfiles(path)
        profiles = reader.read()
        # attenuated backscatter image
        profiles.plot(vmin=1e-2, vmax=1e1, log=True)
        ```
        ![Image of attenuated backscatter profiles](../../assets/images/attenuated_backscatter.png)
    """

    # calculates max value from data
    if vmax is None:
        perc = np.percentile(da[var].data, 70)
        pow10 = np.ceil(np.log10(perc))
        vmax = 10 ** (pow10)

    # time
    time = da.time.data
    # altitude
    if zref.upper() == "AGL":
        altitude = da.altitude.data - da.station_altitude.data
    elif zref.upper() == "ASL":
        altitude = da.altitude.data

    fig, axs = plt.subplots(1, 1, figsize=(12, 4))

    # 2D array
    C = np.transpose(da[var].data)

    if log:
        import matplotlib.colors as colors

        plt.pcolormesh(
            time,
            altitude,
            C,
            norm=colors.LogNorm(vmin=np.max([0, vmin]), vmax=vmax),
            cmap=cmap,
            shading="nearest",
        )
    else:
        plt.pcolormesh(
            time, altitude, C, vmin=vmin, vmax=vmax, cmap=cmap, shading="nearest"
        )

    # add addition information
    if show_foc:
        _plot_foc(da, zref)
    if show_clouds:
        _plot_clouds(da, zref)
    if show_pbl:
        _plot_pbl(da, zref)

    # limit to altitude range
    plt.ylim([zmin, zmax])

    # set title and axis labels
    yyyy = pd.to_datetime(da.time.values[0]).year
    mm = pd.to_datetime(da.time.values[0]).month
    dd = pd.to_datetime(da.time.values[0]).day
    latitude = da.station_latitude.data
    longitude = da.station_longitude.data
    altitude = da.station_altitude.data
    station_id = da.attrs["site_location"]
    # title
    plt.title(
        f"{station_id} ({latitude:.2f};{longitude:.2f};{altitude:.1f}m) - {yyyy}/{mm:02}/{dd:02}",
        weight="bold",
    )
    # labels
    plt.xlabel("Time")
    plt.ylabel(f"Altitude {zref.upper()} (m)")

    # add legend
    if show_foc or show_clouds or show_pbl:
        plt.legend(loc="upper right")

    # colorbar
    cbar = plt.colorbar()
    # label
    if "units" in list(da[var].attrs) and da[var].units is not None:
        label = f"{da[var].long_name} ({da[var].units})"
    else:
        label = f"{da[var].long_name}"
    cbar.set_label(label)

    plt.tight_layout()
    if save_fig:
        plt.savefig(save_fig)
    if show_fig:
        plt.show()

Profile

This module is used to plot a single profile for a given numpy.datetime64, of a given variable of an instance of the ProfilesData class.

plot(da, datetime, var='attenuated_backscatter_0', zref='agl', zmin=None, zmax=None, vmin=None, vmax=None, log=False, show_foc=False, show_pbl=False, show_clouds=False, show_fig=True, save_fig=None)

Plot single profile of selected variable from (aprofiles.profiles.ProfilesData): object.

Parameters:

Name Type Description Default
da DataArray

DataArray.

required
datetime datetime64

Time for which the profile is plotted.

required
var str

Variable of the DataArray to be plotted.

'attenuated_backscatter_0'
zref {agl, asl}

Base reference for the altitude axis. Defaults to 'agl'.

'agl'
zmin float

Minimum altitude AGL (m). Defaults to minimum available altitude.

None
zmax float

Maximum altitude AGL (m). Defaults to maximum available altitude.

None
vmin float

Minimum value.

None
vmax float

Maximum value. If None, calculates max from data.

None
log bool

Use logarithmic scale.

False
show_foc bool

Add foc detection.

False
show_pbl bool

Add PBL height.

False
show_clouds bool

Add clouds detection.

False
show_fig bool

Show figure.

True
save_fig str

Path of the saved figure.

None
Example
import aprofiles as apro
# read example file
path = "examples/data/L2_0-20000-001492_A20210909.nc"
reader = apro.reader.ReadProfiles(path)
profiles = reader.read()
# some detection
profiles.clouds(inplace=True).pbl(inplace=True)
# attenuated backscatter single profile
datetime = np.datetime64('2021-09-09T10:25:00')
profiles.plot(datetime=datetime, vmin=-1, vmax=10, zmax=12000, show_clouds=True, show_pbl=True)

Single profile of attenuated backscatter

Source code in aprofiles/plot/profile.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
def plot(
    da,
    datetime,
    var="attenuated_backscatter_0",
    zref="agl",
    zmin=None,
    zmax=None,
    vmin=None,
    vmax=None,
    log=False,
    show_foc=False,
    show_pbl=False,
    show_clouds=False,
    show_fig=True,
    save_fig=None
):
    """
    Plot single profile of selected variable from (aprofiles.profiles.ProfilesData): object.

    Args:
        da (xarray.DataArray): DataArray.
        datetime (numpy.datetime64): Time for which the profile is plotted.
        var (str, optional): Variable of the DataArray to be plotted.
        zref ({'agl', 'asl'}, optional): Base reference for the altitude axis. Defaults to 'agl'.
        zmin (float, optional): Minimum altitude AGL (m). Defaults to minimum available altitude.
        zmax (float, optional): Maximum altitude AGL (m). Defaults to maximum available altitude.
        vmin (float, optional): Minimum value.
        vmax (float, optional): Maximum value. If None, calculates max from data.
        log (bool, optional): Use logarithmic scale.
        show_foc (bool, optional): Add foc detection.
        show_pbl (bool, optional): Add PBL height.
        show_clouds (bool, optional): Add clouds detection.
        show_fig (bool, optional): Show figure.
        save_fig (str, optional): Path of the saved figure.

    Example:
        ```python
        import aprofiles as apro
        # read example file
        path = "examples/data/L2_0-20000-001492_A20210909.nc"
        reader = apro.reader.ReadProfiles(path)
        profiles = reader.read()
        # some detection
        profiles.clouds(inplace=True).pbl(inplace=True)
        # attenuated backscatter single profile
        datetime = np.datetime64('2021-09-09T10:25:00')
        profiles.plot(datetime=datetime, vmin=-1, vmax=10, zmax=12000, show_clouds=True, show_pbl=True)
        ```

        ![Single profile of attenuated backscatter](../../assets/images/Profile-Oslo-20210909T212005.png){: style="width: 60%;" }
    """

    if datetime is None:
        raise ValueError(
            "datetime needs to be a np.datetime object, e.g. time=np.datetime(2021-09-09T16:00:00)"
        )
    # get index of closest profile
    da_time = da.time.data
    i_time = np.argmin(abs(da_time - datetime))

    # altitude
    if zref.upper() == "AGL":
        altitude = da.altitude.data - da.station_altitude.data
    elif zref.upper() == "ASL":
        altitude = da.altitude.data

    fig, axs = plt.subplots(1, 1, figsize=(6, 6))
    plt.plot(da[var].data[i_time], altitude)
    # add zeros
    plt.plot(np.zeros(len(altitude)), altitude, ":k", alpha=0.2)

    if log:
        axs.set_xscale("log")

    # add addition information
    if show_foc:
        _plot_foc(da, da_time[i_time], zref)
    if show_clouds:
        _plot_clouds(da, da_time[i_time], var, zref)
    if show_pbl:
        _plot_pbl(da, da_time[i_time], var, zref)

    # set scales
    plt.ylim([zmin, zmax])
    if vmin is not None or vmax is not None:
        plt.xlim([vmin, vmax])

    # set title and axis labels
    latitude = da.station_latitude.data
    longitude = da.station_longitude.data
    altitude = da.station_altitude.data
    station_id = da.attrs["site_location"]
    # title
    plt.title(
        f"{station_id} ({latitude:.2f};{longitude:.2f};{altitude:.1f}m) - {np.datetime_as_string(da_time[i_time]).split('.')[0]}",
        weight="bold",
        fontsize=12,
    )
    # labels
    if "units" in list(da[var].attrs) and da[var].units is not None:
        xlabel = f"{da[var].long_name} ({da[var].units})"
    else:
        xlabel = f"{da[var].long_name}"
    plt.xlabel(xlabel)
    plt.ylabel(f"Altitude {zref.upper()} (m)")

    # add legend
    if show_foc or show_clouds or show_pbl:
        plt.legend(loc="upper right")

    plt.tight_layout()
    if save_fig:
        plt.savefig(save_fig)
    if show_fig:
        plt.show()

Time Series

This module is used to plot a time series of a given variable of an instance of the ProfilesData class.

plot(da, var='aod', show_fig=True, save_fig=None, **kwargs)

Plot time series of selected variable from (aprofiles.profiles.ProfilesData): object.

Parameters:

Name Type Description Default
da DataArray

DataArray

required
var str

Variable of the DataArray to be plotted.

'aod'
show_fig bool

Show Figure.

True
save_fig str

Path of the saved figure.

None
Example
import aprofiles as apro
# read example file
path = "examples/data/L2_0-20000-001492_A20210909.nc"
reader = apro.reader.ReadProfiles(path)
profiles = reader.read()
# retrieve pbl height
profiles.pbl(zmin=200, zmax=3000)
# attenuated backscatter image
profiles.plot(var="pbl" ymin=0., ymax=3000., min_snr=2.)

Time series of Planetary Boundary Layer height

Source code in aprofiles/plot/timeseries.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
def plot(da, var="aod", show_fig=True, save_fig=None, **kwargs):
    """
    Plot time series of selected variable from (aprofiles.profiles.ProfilesData): object.

    Args:
        da (xarray.DataArray): DataArray
        var (str, optional): Variable of the DataArray to be plotted.
        show_fig (bool, optional): Show Figure.
        save_fig (str, optional): Path of the saved figure.

    Example:
        ``` python
        import aprofiles as apro
        # read example file
        path = "examples/data/L2_0-20000-001492_A20210909.nc"
        reader = apro.reader.ReadProfiles(path)
        profiles = reader.read()
        # retrieve pbl height
        profiles.pbl(zmin=200, zmax=3000)
        # attenuated backscatter image
        profiles.plot(var="pbl" ymin=0., ymax=3000., min_snr=2.)
        ```

        ![Time series of Planetary Boundary Layer height](../../assets/images/time_series.png)
    """

    def __init__(self):
        pass

    # get kwargs
    ymin = kwargs.get("ymin", None)
    ymax = kwargs.get("ymax", None)

    # time
    time = da.time.data

    fig, axs = plt.subplots(1, 1, figsize=(12, 4))

    # plot time series
    plt.plot(time, da[var].data)

    # limit to altitude range
    if ymin is not None or ymax is not None:
        plt.ylim([ymin, ymax])

    # set title and axis labels
    yyyy = pd.to_datetime(da.time.values[0]).year
    mm = pd.to_datetime(da.time.values[0]).month
    dd = pd.to_datetime(da.time.values[0]).day
    latitude = da.station_latitude.data
    longitude = da.station_longitude.data
    altitude = da.station_altitude.data
    station_id = da.attrs["site_location"]
    # title
    plt.title(
        f"{station_id} ({latitude:.2f};{longitude:.2f};{altitude:.1f}m) - {yyyy}/{mm:02}/{dd:02}",
        weight="bold",
    )
    # labels
    plt.xlabel("Time")

    if "units" in list(da[var].attrs) and da[var].units is not None:
        ylabel = f"{da[var].long_name} ({da[var].units})"
    else:
        ylabel = f"{da[var].long_name}"
    plt.ylabel(ylabel)

    plt.tight_layout()
    if save_fig:
        plt.savefig(save_fig)
    if show_fig:
        plt.show()