asp_plot.altimetry_plots
========================

.. py:module:: asp_plot.altimetry_plots

.. autoapi-nested-parse::

   Altimetry plotting layer.

   All figure rendering for :class:`asp_plot.altimetry.Altimetry`, split out from
   the data-source code so plot methods operate on **already-prepared**
   dataframes. The coordinating ``Altimetry`` instance computes the dh columns
   (``atl06sr_to_dem_dh`` / ``planetary_to_dem_dh``) and resolves the best track
   *before* calling into this module, so no plot body triggers a SlideRule
   request or re-samples a DEM for differencing. Reading a DEM purely to draw a
   hillshade backdrop is a rendering concern and stays here.

   The plotter reads scalar context (``dem_fn``, ``aligned_dem_fn``, the request
   time-range label) from the coordinator passed at construction; the
   dataframes themselves arrive as method arguments.



Attributes
----------

.. autoapisummary::

   asp_plot.altimetry_plots.WORLDCOVER_NAMES
   asp_plot.altimetry_plots.logger


Classes
-------

.. autoapisummary::

   asp_plot.altimetry_plots.AltimetryPlotter


Module Contents
---------------

.. py:class:: AltimetryPlotter(alt)

   Render ICESat-2 and planetary altimetry figures from prepared data.

   :param alt: The coordinating :class:`asp_plot.altimetry.Altimetry` instance.
               Used only to read scalar context (``dem_fn``, ``aligned_dem_fn``,
               and the ICESat-2 request time-range label). All dataframes are
               passed explicitly to each plot method.
   :type alt: Altimetry


   .. py:method:: histogram(atl06sr, key='all', title='Histogram', plot_aligned=False, save_dir=None, fig_fn=None)

      Plot histograms of height differences between ATL06-SR data and DEMs.

      Creates histograms of the height differences between ICESat-2 ATL06-SR
      data and DEMs, with statistics including median and normalized median
      absolute deviation (NMAD).

      :param atl06sr: Prepared ATL06-SR points with the dh column already computed.
      :type atl06sr: geopandas.GeoDataFrame
      :param key: Processing level label, default is "all"
      :type key: str, optional
      :param title: Plot title, default is "Histogram"
      :type title: str, optional
      :param plot_aligned: Whether to include differences with aligned DEM, default is False
      :type plot_aligned: bool, optional
      :param save_dir: Directory to save figure, default is None (don't save)
      :type save_dir: str or None, optional
      :param fig_fn: Filename for saved figure, default is None
      :type fig_fn: str or None, optional

      .. rubric:: Notes

      NMAD is a robust measure of dispersion that is less sensitive
      to outliers than standard deviation, calculated as
      1.4826 * median(abs(x - median(x))).



   .. py:method:: histogram_by_landcover(atl06sr, key='all', top_n=4, title='ICESat-2 ATL06-SR vs DEM', xlim=None, plot_aligned=False, save_dir=None, fig_fn=None)

      Plot histogram of dh with per-landcover-class statistics.

      Creates a histogram of the height differences between ICESat-2
      ATL06-SR data and the DEM, with a text annotation showing overall
      and per-landcover-class statistics (count, median, NMAD).

      When ``plot_aligned=True`` and an aligned DEM is available,
      overlays the pre- and post-alignment distributions and renders two
      vertically stacked stats text boxes whose outline colors match the
      bar colors (color serves as the legend).

      :param atl06sr: Prepared ATL06-SR points with the dh column already computed.
      :type atl06sr: geopandas.GeoDataFrame
      :param key: Processing level label, default is "all"
      :type key: str, optional
      :param top_n: Number of top landcover classes to report, default is 4
      :type top_n: int, optional
      :param title: Plot title, default is "ICESat-2 ATL06-SR vs DEM"
      :type title: str, optional
      :param xlim: Symmetric x-axis limits as (min, max). If None, uses ±3σ
                   range (data is already 3σ-filtered in atl06sr_to_dem_dh).
      :type xlim: tuple or None, optional
      :param plot_aligned: Whether to overlay the aligned-DEM distribution alongside the
                           unaligned one. Requires ``self.alt.aligned_dem_fn`` and the
                           ``icesat_minus_aligned_dem`` column. Default is False.
      :type plot_aligned: bool, optional
      :param save_dir: Directory to save figure, default is None
      :type save_dir: str or None, optional
      :param fig_fn: Filename for saved figure, default is None
      :type fig_fn: str or None, optional



   .. py:method:: histogram_planetary_to_dem(planetary_points, save_dir=None, fig_fn=None, title=None, plot_aligned=False)

      Histogram of planetary altimetry vs DEM height differences.

      :param planetary_points: Prepared planetary points with ``altimetry_minus_dem`` (and,
                               when available, ``altimetry_minus_aligned_dem``) columns.
      :type planetary_points: geopandas.GeoDataFrame
      :param save_dir: Directory to save figure.
      :type save_dir: str or None, optional
      :param fig_fn: Filename for saved figure.
      :type fig_fn: str or None, optional
      :param title: Custom plot title. Auto-detected if None.
      :type title: str or None, optional
      :param plot_aligned: Overlay the post-alignment dh distribution on the same axes.
                           Requires that pc_align has been run successfully.
      :type plot_aligned: bool, optional



   .. py:method:: mapview_plot_atl06sr_to_dem(atl06sr, key='all', clim=None, plot_aligned=False, save_dir=None, fig_fn=None, map_crs=None, **ctx_kwargs)

      Plot height differences between ATL06-SR data and DEMs.

      Creates a map visualization of the height differences between
      ICESat-2 ATL06-SR data and either the original or aligned DEM.

      :param atl06sr: Prepared ATL06-SR points with the dh column already computed.
      :type atl06sr: geopandas.GeoDataFrame
      :param key: Processing level label, default is "all"
      :type key: str, optional
      :param clim: Color limits as (min, max), default is None (auto)
      :type clim: tuple or None, optional
      :param plot_aligned: Whether to plot differences with aligned DEM, default is False
      :type plot_aligned: bool, optional
      :param save_dir: Directory to save figure, default is None (don't save)
      :type save_dir: str or None, optional
      :param fig_fn: Filename for saved figure, default is None
      :type fig_fn: str or None, optional
      :param map_crs: Coordinate reference system for mapping, default is None
                      (use DEM's CRS)
      :type map_crs: str or None, optional
      :param \*\*ctx_kwargs: Additional arguments for contextily basemap
      :type \*\*ctx_kwargs: dict, optional

      .. rubric:: Notes

      The plot uses a divergent colormap (RdBu) to highlight
      positive and negative differences.



   .. py:method:: mapview_plot_planetary_to_dem(planetary_points, clim=None, save_dir=None, fig_fn=None, title=None, plot_aligned=False)

      Map view of planetary altimetry vs DEM height differences.

      Plots the DEM hillshade as background with altimetry dh points
      overlaid using a divergent colourmap. When ``plot_aligned=True``
      and ``self.alt.aligned_dem_fn`` is set, renders pre/post panels side
      by side.

      :param planetary_points: Prepared planetary points with ``altimetry_minus_dem`` (and,
                               when available, ``altimetry_minus_aligned_dem``) columns.
      :type planetary_points: geopandas.GeoDataFrame
      :param clim: Colour limits ``(min, max)`` for dh. Default auto (symmetric
                   ±|max| around zero).
      :type clim: tuple or None, optional
      :param save_dir: Directory to save figure.
      :type save_dir: str or None, optional
      :param fig_fn: Filename for saved figure.
      :type fig_fn: str or None, optional
      :param title: Custom plot title. Auto-detected if None.
      :type title: str or None, optional
      :param plot_aligned: Add a second panel showing dh against the aligned DEM.
                           Requires that pc_align has been run successfully.
      :type plot_aligned: bool, optional



   .. py:method:: plot_atl06sr(atl06sr, key='all', plot_beams=False, plot_dem=False, column_name='h_mean', cbar_label='Height above datum (m)', title='ICESat-2 ATL06-SR', clim=None, symm_clim=False, cmap='inferno', map_crs='EPSG:4326', figsize=(6, 4), save_dir=None, fig_fn=None, **ctx_kwargs)

      Plot ATL06-SR data on a map with customizable options.

      Creates a map view of ATL06-SR data with options to color by various
      attributes, highlight different laser beams, overlay on the DEM,
      and add contextual basemaps.

      :param atl06sr: Prepared ATL06-SR points to plot (one processing level).
      :type atl06sr: geopandas.GeoDataFrame
      :param key: Processing level label for the title, default is "all"
      :type key: str, optional
      :param plot_beams: Whether to color points by ICESat-2 beam, default is False
      :type plot_beams: bool, optional
      :param plot_dem: Whether to plot the DEM as a background, default is False
      :type plot_dem: bool, optional
      :param column_name: Column to use for point coloring, default is "h_mean"
      :type column_name: str, optional
      :param cbar_label: Colorbar label, default is "Height above datum (m)"
      :type cbar_label: str, optional
      :param title: Plot title, default is "ICESat-2 ATL06-SR"
      :type title: str, optional
      :param clim: Color limits as (min, max), default is None (auto)
      :type clim: tuple or None, optional
      :param symm_clim: Whether to use symmetric color limits, default is False
      :type symm_clim: bool, optional
      :param cmap: Matplotlib colormap, default is "inferno"
      :type cmap: str, optional
      :param map_crs: Coordinate reference system for mapping, default is "EPSG:4326"
      :type map_crs: str, optional
      :param figsize: Figure size as (width, height), default is (6, 4)
      :type figsize: tuple, optional
      :param save_dir: Directory to save figure, default is None (don't save)
      :type save_dir: str or None, optional
      :param fig_fn: Filename for saved figure, default is None
      :type fig_fn: str or None, optional
      :param \*\*ctx_kwargs: Additional arguments for contextily basemap
      :type \*\*ctx_kwargs: dict, optional

      .. rubric:: Notes

      When plot_beams is True, points are colored by ICESat-2 laser spot
      number, with strong beams (1, 3, 5) in darker colors and
      weak beams (2, 4, 6) in lighter colors.



   .. py:method:: plot_atl06sr_dem_profile(resolved, seg_info, plot_aligned=False, save_dir=None, fig_fn=None)

      Plot elevation profile comparing ICESat-2 and DEM along the best track.

      Creates a 2×2 figure with the profile stack on the left and a map
      view spanning the full height on the right:
      - Top-left: Absolute elevation profile (DEM, COP30, ICESat-2)
      - Bottom-left: Height difference profile (ICESat-2 minus DEM)
        (shares x-axis with top-left, no vertical space between them)
      - Right column: DEM hillshade map with the full track and segment
        extents, spanning the full vertical height

      :param resolved: The ``(track, rgt, cycle, spot, track_count, track_date, dist,
                       dh_vals)`` tuple from ``Icesat2Source._resolve_best_track``.
      :type resolved: tuple
      :param seg_info: Best/worst segment extents from
                       ``Icesat2Source._find_best_worst_segments``.
      :type seg_info: dict or None
      :param plot_aligned: Whether to also plot the aligned DEM profile, default is False
      :type plot_aligned: bool, optional
      :param save_dir: Directory to save figure, default is None
      :type save_dir: str or None, optional
      :param fig_fn: Filename for saved figure, default is None
      :type fig_fn: str or None, optional



   .. py:method:: plot_atl06sr_time_stamps(filtered, key='all', title='ICESat-2 ATL06-SR Time Stamps', cmap='inferno', map_crs='EPSG:4326', figsize=(15, 10), save_dir=None, fig_fn=None, **ctx_kwargs)

      Plot ATL06-SR data for different temporal filters.

      Creates a 2x2 grid of plots showing ATL06-SR data for different
      temporal filters (unfiltered, 15-day, 45-day, and seasonal)
      colored by height.

      :param filtered: The ``atl06sr_processing_levels_filtered`` mapping of
                       processing-level key -> GeoDataFrame.
      :type filtered: dict
      :param key: Base processing level to plot, default is "all"
      :type key: str, optional
      :param title: Plot title, default is "ICESat-2 ATL06-SR Time Stamps"
      :type title: str, optional
      :param cmap: Matplotlib colormap for elevation, default is "inferno"
      :type cmap: str, optional
      :param map_crs: Coordinate reference system for mapping, default is "EPSG:4326"
      :type map_crs: str, optional
      :param figsize: Figure size as (width, height), default is (15, 10)
      :type figsize: tuple, optional
      :param save_dir: Directory to save figure, default is None (don't save)
      :type save_dir: str or None, optional
      :param fig_fn: Filename for saved figure, default is None
      :type fig_fn: str or None, optional
      :param \*\*ctx_kwargs: Additional arguments for contextily basemap
      :type \*\*ctx_kwargs: dict, optional

      .. rubric:: Notes

      This method requires the filtered data to have been created using
      the predefined_temporal_filter_atl06sr method for the temporal
      variations to be available.



   .. py:method:: plot_best_worst_segments(resolved, seg_info, plot_aligned=False, save_dir=None, fig_fn=None)

      Plot 1 km segments with better and worse agreement as a 1×2 figure.

      Creates a single-row, 2-column figure:
      - Column 1: Better agreement segment (lowest score)
      - Column 2: Worse agreement segment (highest score)

      Segment score is ``3·|median(dh)| + NMAD(dh)`` (see
      ``Icesat2Source._find_best_worst_segments``). Segment selection is
      based on the unaligned dh so best/worst segments remain comparable
      across the pre- and post-alignment variants of this plot.

      :param resolved: The ``(track, rgt, cycle, spot, track_count, track_date, dist,
                       dh_vals)`` tuple from ``Icesat2Source._resolve_best_track``.
      :type resolved: tuple
      :param seg_info: Best/worst segment extents from
                       ``Icesat2Source._find_best_worst_segments``.
      :type seg_info: dict
      :param plot_aligned: Whether to overlay the aligned DEM heights and include aligned
                           Median/NMAD in each segment title. Requires
                           ``self.alt.aligned_dem_fn`` and the ``aligned_dem_height`` /
                           ``icesat_minus_aligned_dem`` columns. Default False.
      :type plot_aligned: bool, optional
      :param save_dir: Directory to save figure, default is None
      :type save_dir: str or None, optional
      :param fig_fn: Filename for saved figure, default is None
      :type fig_fn: str or None, optional



   .. py:attribute:: alt


.. py:data:: WORLDCOVER_NAMES

.. py:data:: logger

