Source code for marine_qc.visualization.plot_qc_outcomes

"""
Plot QC outcomes.

Some plotting routines for QC outcomes
"""

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import figure, lines


[docs] def _get_colours_labels(qc_outcomes: np.ndarray) -> tuple[np.ndarray, list[lines.Line2D]]: """ Get color lebels. Parameters ---------- qc_outcomes : numpy.ndarray Array containing the QC outcomes, with 0 meaning pass and non-zero entries indicating failure. Returns ------- tuple of (numpy.ndarray, list of lines.Line2D) Color names and legend elements. """ colour_passed = "#55ff55" colour_failed = "#ff5555" colour_other = "#808080" passed = 0 failed = 0 other = 0 colours_list = [] for outcome in qc_outcomes: if outcome == 0: colours_list.append(colour_passed) passed += 1 elif outcome == 1: colours_list.append(colour_failed) failed += 1 else: colours_list.append(colour_other) other += 1 colours = np.array(colours_list, dtype=str) legend_elements = [ lines.Line2D( [0], [0], marker="o", color="w", label=f"0: {passed}", markerfacecolor=colour_passed, ), lines.Line2D( [0], [0], marker="o", color="w", label=f"1: {failed}", markerfacecolor=colour_failed, ), lines.Line2D( [0], [0], marker="o", color="w", label=f"other: {other}", markerfacecolor=colour_other, ), ] return colours, legend_elements
[docs] def _make_plot( xvalue: np.ndarray, yvalue: np.ndarray, flags: np.ndarray, xlim: tuple[float, float] | None, ylim: tuple[float, float] | None, xlabel: str, ylabel: str, marker_size: int | None, filename: str | None, add_coastlines: bool, ) -> figure.Figure: """ Make plot. Parameters ---------- xvalue : numpy.ndarray Array of x values. yvalue : numpy.ndarray Array of y values. flags : numpy.ndarray Array containing the QC outcomes, with 0 meaning pass and non-zero entries indicating failure. xlim : tuple of float and float or None If not None: set xlim for plotting. ylim : tuple of float and float or None If not None: set ylim for plotting. xlabel : str Name of the x axis. ylabel : str Name of the y axis. marker_size : int Marker size in points. filename : str or None Filename to save the figure to. If None, the figure is not saved not shown. add_coastlines : bool If True, add coastlines on PlateCarree projection. Returns ------- Figure The main figure obkect created by `plt.subplots()`. """ colours, legend_elements = _get_colours_labels(flags) mask_passed = flags == 0 mask_failed = flags == 1 mask_other = (flags != 0) & (flags != 1) subplots_kwargs = { "figsize": (16, 9), "sharex": True, "sharey": True, } scatter_kwargs = {"s": marker_size or 1} if add_coastlines is True: projection = ccrs.PlateCarree() subplots_kwargs["subplot_kw"] = {"projection": projection} scatter_kwargs["transform"] = projection fig, axes = plt.subplots(2, 2, **subplots_kwargs) axes = axes.flatten() titles = ["QC == 0 (Passed)", "QC == 1 (Failed)", "QC == Other", "All Points"] masks = [mask_passed, mask_failed, mask_other, np.ones_like(flags, dtype=bool)] marker_size = marker_size or 1 for i in range(4): ax = axes[i] ax.scatter(xvalue[masks[i]], yvalue[masks[i]], c=colours[masks[i]], **scatter_kwargs) ax.set_title(titles[i]) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) if xlim: ax.set_xlim(*xlim) if ylim: ax.set_ylim(*ylim) if add_coastlines is True: ax.coastlines() fig.legend( handles=legend_elements, loc="center", ncol=len(legend_elements), bbox_to_anchor=(0.5, 0.53), ) plt.tight_layout(rect=(0.0, 0.05, 1.0, 1.0)) if filename is None: plt.show(block=False) else: plt.savefig(filename) return fig
def plot_variable_longitude( lon: np.ndarray, value: np.ndarray, qc_outcomes: np.ndarray, xlim: tuple[float, float] | None = None, ylim: tuple[float, float] | None = None, marker_size: int | None = None, add_coastlines: bool = False, filename: str | None = None, ) -> figure.Figure: """ Plot a graph of points showing the value and the longitude of a set of observations coloured according to flagged outcomes. Parameters ---------- lon : numpy.ndarray Array of longitude values in degrees. value : numpy.ndarray Array of observed values for the variable. qc_outcomes : numpy.ndarray Array containing the QC outcomes, with 0 meaning pass and non-zero entries indicating failure. xlim : tuple of float and float, optional Limits of the current x axis. If None, set to (-180.0, 180.0). ylim : tuple of float and float, optional Limits of the current y axis. marker_size : int, optional Marker size in points. If None, it is set to 1. add_coastlines : bool If True, add coastlines on PlateCarree projection. filename : str, optional Filename to save the figure to. If None, the figure is not saved but shown. Returns ------- Figure The main figure object created by `plt.subplots()`. """ if xlim is None: xlim = (-180.0, 180.0) return _make_plot( xvalue=lon, yvalue=value, flags=qc_outcomes, xlim=None, ylim=None, xlabel="Longitude", ylabel="Variable", marker_size=marker_size, filename=filename, add_coastlines=add_coastlines, ) def plot_latitude_variable( lat: np.ndarray, value: np.ndarray, qc_outcomes: np.ndarray, xlim: tuple[float, float] | None = None, ylim: tuple[float, float] | None = None, marker_size: int | None = None, add_coastlines: bool = False, filename: str | None = None, ) -> figure.Figure: """ Plot a graph of points showing the latitude and the value of a set of observations coloured according to flagged outcomes. Parameters ---------- lat : numpy.ndarray Array of latitude values in degrees. value : numpy.ndarray Array of observed values for the variable. qc_outcomes : numpy.ndarray Array containing the QC outcomes, with 0 meaning pass and non-zero entries indicating failure. xlim : tuple of float and float, optional Limits of the current x axis. ylim : tuple of float and float, optional Limits of the current y axis. If None, set to (-90.0, 90.0). marker_size : int, optional Marker size in points. If None, it is set to 1. add_coastlines : bool If True, add coastlines on PlateCarree projection. filename : str, optional Filename to save the figure to. If None, the figure is not saved but shown. Returns ------- Figure The main figure object created by `plt.subplots()`. """ if ylim is None: ylim = (-90.0, 90.0) return _make_plot( xvalue=value, yvalue=lat, flags=qc_outcomes, xlim=None, ylim=ylim, xlabel="Variable", ylabel="Latitude", marker_size=marker_size, filename=filename, add_coastlines=add_coastlines, ) def plot_latitude_longitude( lat: np.ndarray, lon: np.ndarray, qc_outcomes: np.ndarray, xlim: tuple[float, float] | None = None, ylim: tuple[float, float] | None = None, marker_size: int | None = None, add_coastlines: bool = False, filename: str | None = None, ) -> figure.Figure: """ Plot a graph of points showing the latitude and the longitude of a set of observations coloured according to flagged outcomes. Parameters ---------- lat : numpy.ndarray Array of latitude values in degrees. lon : numpy.ndarray Array of longitude values in degrees. qc_outcomes : numpy.ndarray Array containing the QC outcomes, with 0 meaning pass and non-zero entries indicating failure. xlim : tuple of float and float, optional Limits of the current x axis. If None, set to (-180.0, 180.0). ylim : tuple of float and float, optional Limits of the current y axis. If None, set to (-90.0, 90.0). marker_size : int, optional Marker size in points. If None, it is set to 1. add_coastlines : bool If True, add coastlines on PlateCarree projection. filename : str, optional Filename to save the figure to. If None, the figure is not saved but shown. Returns ------- Figure The main figure object created by `plt.subplots()`. """ if xlim is None: xlim = (-180.0, 180.0) if ylim is None: ylim = (-90.0, 90.0) return _make_plot( xvalue=lon, yvalue=lat, flags=qc_outcomes, xlim=xlim, ylim=ylim, xlabel="Longitude", ylabel="Latitude", marker_size=marker_size, filename=filename, add_coastlines=add_coastlines, ) plot_latitude_longitude.__module__ = "marine_qc.visualization" plot_latitude_variable.__module__ = "marine_qc.visualization" plot_variable_longitude.__module__ = "marine_qc.visualization"