ampycloud.plots#

Copyright (c) 2021-2026 MeteoSwiss, contributors listed in AUTHORS.

Distributed under the terms of the 3-Clause BSD License.

SPDX-License-Identifier: BSD-3-Clause

Submodules#

Attributes#

Classes#

CeiloChunk

Child class for timeseries of Ceilometers hits, referred to as data 'chunks'.

DiagnosticPlot

Class used to create diagnostic plots.

Functions#

log_func_call(→ Callable)

Intended as a decorator to log function calls.

set_mplstyle(→ Callable)

Intended to be used as a decorator around plotting functions, to set the plotting style.

diagnostic(→ None)

A function to create the ampycloud diagnostic plot all the way to the layering step

Package Contents#

class CeiloChunk(data: pandas.DataFrame, prms: dict | None = None, geoloc: str | None = None, ref_dt: str | None = None)[source]#

Bases: ampycloud.data.AbstractChunk, ampycloud.metarize.MetarizeMixin

Child class for timeseries of Ceilometers hits, referred to as data ‘chunks’.

This class essentially gathers all the data and processing methods under one roof.

Warning

Some of these methods are actually intended to be used in order … Some safety mechanisms have been put in place to ensure this actually happens, but still …

You’ve been warned.

data_rescaled(dt_mode: str | None = None, height_mode: str | None = None, dt_kwargs: dict | None = None, height_kwargs: dict | None = None) pandas.DataFrame[source]#

Returns a copy of the data, rescaled according to the provided parameters.

Parameters:
  • dt_mode (str, optional) – scaling rule for the time deltas. Defaults to None.

  • height_mode (str, optional) – scaling rule for the heights. Defaults to None.

  • dt_kwargs (dict, optional) – dict of arguments to be fed to the chosen dt scaling routine. Defaults to None.

  • height_kwargs (dict, optinal) – dict of arguments to be fed to the chosen height scaling routine. Defaults to None.

Returns:

pd.DataFrame – a copy of the data, rescaled.

Note

The kwargs approach was inspired by the reply from Jonathan Eunice on SO.

property ceilos: list#

The list of all ceilometers included in the data chunk.

Returns:

list of str – the list of ceilo names.

property max_hits_per_layer: int#

The maximum number of ceilometer hits possible for a given layer, given the chunk data.

Returns:

int – the max number of ceilometer hit for a layer. Divide by len(self.ceilos) to get the average max number of hits per ceilometer per layer (remember: not all ceilometers may have the same number of timestamps over the chunk time period !).

This is the total number of unique timesteps from all ceilometers considered.

Note

This value assumes that a layer can contain only 1 hit per ceilometer per timestep, i.e. 2 simultaneous hits from a given ceilometer can never belong to the same cloud layer.

find_slices() None[source]#

Identify general height slices in the chunk data. Intended as the first stage towards the identification of cloud layers.

Important

The “parameters” of this function are all set in self.prms[‘SLICING_PRMS’].

find_groups() None[source]#

Identifies groups of coherent hits accross overlapping slices. Intended as the second stage towards the identification of cloud layers.

Important

The “parameters” of this function are all set in self.prms[‘GROUPING_PRMS’].

find_layers() None[source]#

Identifies individual layers from a list of groups, splitting these in 2 or 3 (if warranted) significant cloud sub-layers. Intended as the third stage towards the identification of cloud layers.

Important

The “parameters” of this function are set in self.prms[‘LAYERING_PRMS’].

property n_slices: None | int#

Returns the number of slices identified in the data.

Returns:

int – the number of slices

property slices: pandas.DataFrame#

Returns a pandas.DataFrame with information regarding the different slices identified by the slicing step.

property n_groups: None | int#

Returns the number of groups identified in the data.

Returns:

int – the number of groups

property groups: pandas.DataFrame#

Returns a pandas.DataFrame with information regarding the different groups identified by the grouping algorithm.

property n_layers: None | int#

Returns the number of layers identified in the data.

Returns:

int – the number of layers.

property layers: pandas.DataFrame#

Returns a pandas.DataFrame with information regarding the different layers identified by the layering algorithm.

property clouds_above_msa_buffer: bool#

Returns whether a number of hits exceeding the threshold for 1 okta is detected above MSA + MSA_HIT_BUFFER.

Returns:

bool – whether high clouds were detected.

log_func_call(logger: logging.Logger) Callable[source]#

Intended as a decorator to log function calls.

Parameters:

logger (logging.Logger) – a logger to feed info to.

The first part of the message containing the function name is at the ‘INFO’ level. The second part of the message containing the argument values is at the ‘DEBUG’ level.

Note

Adapted from the similar dvas function, which itself was adapted from this post on SO, in particular the reply from Kfir Eisner and Peter Mortensen. See also this.

class DiagnosticPlot(chunk: ampycloud.ceilo_data.CeiloChunk)[source]#

Class used to create diagnostic plots.

static setup_fig() tuple[source]#

Setups a diagnsotic plot figure.

Returns:

fig, axs – the matplotlib figure, and the axes stored in a list.

new_fig() None[source]#

Assign the fig attribute.

show_hits_only(show_ceilos: bool = False) None[source]#

Shows the ceilometer hits alone.

Parameters:

show_ceilos (bool, optional) – whether to distinguish between the different ceilos, or not.

Important

This will clear the plot first !

show_slices() None[source]#

Show the slice data.

show_groups(show_points: bool = False) None[source]#

Show the group data.

Parameters:

show_points (bool, optional) – whether to actually draw the groups, or simply add the info about them. Defaults to False.

show_layers() None[source]#

Show the layer data.

add_vv_legend() None[source]#

Adds a legend about the VV hits.

add_ceilo_count() None[source]#

Adds the number of ceilometer present in the data.

add_max_hits() None[source]#

Adds the max_hit_per_layer info.

add_geoloc_and_ref_dt() None[source]#

Adds info about the chunk geoloc and reference date & time.

add_ref_metar(name: str | None, metar: str | None) None[source]#

Display a reference METAR, for example from human observers, different code, etc …

Parameters:
  • name (str) – the name of the reference, e.g. ‘Human Observers’.

  • metar (str) – the METAR code.

add_metar() None[source]#

Display the ampycloud METAR message.

format_primary_axes() None[source]#

Deals with the main plot axes

format_slice_axes() None[source]#

Format the duplicate axes related to the slicing part.

format_group_axes() None[source]#

Format the duplicate axes related to the grouping part.

TODO: add secondary axis for the height rescaling as well. See #91.

save(fn_out: str, fmts: list | None = None) None[source]#

Saves the plot to file.

Parameters:
  • fn_out (str) – file name out.

  • fmts (list or str, optional) – list of formats to export the plot to. Defaults to None == ‘pdf’.

show() None[source]#

Shows the plot

close_fig() None[source]#

Close the figure to free the memory.

If you need to re-create them, start by generating the figure with the .new_fig() method.

set_mplstyle(func: Callable) Callable[source]#

Intended to be used as a decorator around plotting functions, to set the plotting style.

Returns:

Callable – the decorator.

By defaults, the base ampycloud style will be enabled. Motivated users can tweak it further by setting the MPL_STYLE entry of ampycloud.dynamic.AMPYCLOUD_PRMS to:

  • latex: to enable the use of a system-wide LaTeX engine, and the Computer Modern font.

  • metsymb: to enable the use of a system-wide LaTeX engine, the Computer Modern font, and the metsymb LaTeX package to display proper okta symbols.

Important

The metsymb LaTeX package is NOT included with ampycloud, and must be installed separately. It is available at: MeteoSwiss/metsymb

Caution

Specifying the latex or metsymb style requires a working system-wide LaTeX installation. In particular, the following LaTeX packages must be installed:

logger[source]#
diagnostic(chunk: ampycloud.ceilo_data.CeiloChunk, upto: str = 'layers', show_ceilos: bool = False, ref_metar: str | None = None, ref_metar_origin: str | None = None, show: bool = True, save_stem: str | None = None, save_fmts: list | str | None = None) None[source]#

A function to create the ampycloud diagnostic plot all the way to the layering step (included). This is the ultimate ampycloud plot that shows it all (or not - you choose !).

Parameters:
  • chunk (CeiloChunk) – the CeiloChunk to look at.

  • upto (str, optional) – up to which algorithm steps to plot. Can be one of [‘raw_data’, ‘slices’, ‘groups’, ‘layers’]. Defaults to ‘layers’.

  • show_ceilos (bool, optional) – if True, hits will be colored as a function of the responsible ceilometer. Defaults to False. No effects unless upto='raw data'.

  • ref_metar (str, optional) – reference METAR message. Defaults to None.

  • ref_metar_origin (str, optional) – name of the source of the reference METAR set with ref_metar. Defaults to None.

  • show (bool, optional) – will show the plot on the screen if True. Defaults to False.

  • save_stem (str, optional) – if set, will save the plot with this stem (which can include a path as well). Deafults to None.

  • save_fmts (list|str, optional) – a list of file formats to export the plot to. Defaults to None = [‘pdf’].

Example:

from datetime import datetime
import ampycloud
from ampycloud.utils import mocker
from ampycloud.plots import diagnostic

# First create some mock data for the example
mock_data = mocker.canonical_demo_data()

# Then run the ampycloud algorithm on it
chunk = ampycloud.run(mock_data, geoloc='Mock data', ref_dt=datetime.now())

# Create the full ampycloud diagnostic plot
diagnostic(chunk, upto='layers', show=True)