Source code for argopy.plot.plot

#!/bin/env python
# -*coding: UTF-8 -*-
#
# We try to import dependencies and catch missing module errors in order to avoid to load argopy just because
# Matplotlib is not installed.
#
# Decorator warnUnless is mandatory
#
import pandas as pd
from .utils import STYLE, has_seaborn, has_mpl, has_cartopy, has_ipython, has_ipywidgets
from .utils import axes_style, discrete_coloring, latlongrid, land_feature
from ..utilities import warnUnless, check_wmo


if has_mpl:
    import matplotlib.pyplot as plt

if has_seaborn:
    STYLE["axes"] = "dark"
    import seaborn as sns

if has_cartopy:
    import cartopy.crs as ccrs

if has_ipython:
    from IPython.display import Image, display

if has_ipywidgets:
    import ipywidgets


[docs]@warnUnless(has_ipython, "requires IPython to work as expected, only URLs are returned otherwise") def open_sat_altim_report(WMO=None, embed="dropdown"): """ Insert the CLS Satellite Altimeter Report figure in notebook cell This is the method called when using the facade fetcher methods ``plot``: >>> DataFetcher().float(6902745).plot('qc_altimetry') Parameters ---------- WMO: int or list The float WMO to display. By default, this is set to None and will insert the general dashboard. embed: {'list', 'slide', 'dropdown'}, default: 'dropdown' Set the embedding method. If set to None, simply return the list of urls to figures. """ WMOs = check_wmo(WMO) urls = [] urls_dict = {} for this_wmo in WMOs: url = ( "https://data-argo.ifremer.fr/etc/argo-ast9-item13-AltimeterComparison/figures/%i.png" % this_wmo ) if embed == "list": urls.append(Image(url, embed=True)) else: urls.append(url) urls_dict[this_wmo] = url if embed == "list" and has_ipython: return display(*urls) elif embed == "slide" and has_ipython and has_ipywidgets: def f(Float): return Image(url=urls[Float]) return ipywidgets.interact( f, Float=ipywidgets.IntSlider(min=0, max=len(urls) - 1, step=1) ) elif embed == "dropdown" and has_ipython and has_ipywidgets: def f(Float): return Image(url=urls_dict[int(Float)]) return ipywidgets.interact(f, Float=[str(wmo) for wmo in WMOs]) else: return urls_dict
@warnUnless(has_mpl, "requires matplotlib installed") def plot_trajectory( df: pd.core.frame.DataFrame, style: str = STYLE["axes"], add_legend: bool = True, palette: str = STYLE["palette"], set_global: bool = False, with_cartopy: bool = has_cartopy, with_seaborn: bool = has_seaborn, **kwargs ): """ Plot trajectories for an Argo index dataframe This function is called by the Data and Index fetchers method 'plot' with the 'trajectory' option:: from argopy import IndexFetcher as ArgoIndexFetcher from argopy import DataFetcher as ArgoDataFetcher obj = ArgoIndexFetcher().float([6902766, 6902772, 6902914, 6902746]) # OR obj = ArgoDataFetcher().float([6902766, 6902772, 6902914, 6902746]) fig, ax = obj.plot('trajectory') Parameters ---------- df: Pandas DataFrame Input data with columns: 'wmo','longitude','latitude'. style: str Define the axes style: 'white', 'darkgrid', 'whitegrid', 'dark', 'ticks'. Only used if Seaborn is available. add_legend: bool Add a box legend with list of floats. True by default for a maximum of 15 floats, otherwise no legend. palette: str Define colors to be used for floats: 'Set1' (default) or any other matplotlib colormap or name of a Seaborn palette (deep, muted, bright, pastel, dark, colorblind). set_global: bool Plot trajectories on a global world map or not. False by default. Returns ------- fig: :class:`matplotlib.figure.Figure` ax: :class:`matplotlib.axes.Axes` """ with axes_style(style): # Set-up the figure and axis: defaults = {"figsize": (10, 6), "dpi": 90} if with_cartopy: subplot_kw = {"projection": ccrs.PlateCarree()} fig, ax = plt.subplots(**{**defaults, **kwargs}, subplot_kw=subplot_kw) ax.add_feature(land_feature, edgecolor="black") else: fig, ax = plt.subplots(**{**defaults, **kwargs}) # How many float in this dataset ? nfloat = len(df.groupby("wmo").first()) # Let's do the plot: if with_seaborn: mypal = sns.color_palette(palette, nfloat) sns.lineplot( x="longitude", y="latitude", hue="wmo", data=df, sort=False, palette=mypal, legend=False, ) sns.scatterplot( x="longitude", y="latitude", hue="wmo", data=df, palette=mypal ) else: mypal = discrete_coloring(palette, N=nfloat).cmap for k, [name, group] in enumerate(df.groupby("wmo")): group.plot.line( x="longitude", y="latitude", ax=ax, color=mypal(k), legend=False, label="_nolegend_", ) group.plot.scatter( x="longitude", y="latitude", ax=ax, color=mypal(k), label=name ) if with_cartopy: if set_global: ax.set_global() latlongrid(ax, dx="auto", dy="auto", fontsize="auto") if not has_seaborn: ax.get_yaxis().set_visible(False) else: if set_global: ax.set_xlim(-180, 180) ax.set_ylim(-90, 90) ax.grid(visible=True, linewidth=1, color="gray", alpha=0.7, linestyle=":") if add_legend and nfloat <= 15: handles, labels = ax.get_legend_handles_labels() # if has_seaborn: # handles, labels = handles[1:], labels[1:] plt.legend( handles, labels, loc="upper right", bbox_to_anchor=(1.25, 1), title="Floats WMO", ) else: ax.get_legend().remove() return fig, ax @warnUnless(has_mpl, "requires matplotlib installed") def bar_plot( df: pd.core.frame.DataFrame, by: str = "institution", style: str = STYLE["axes"], with_seaborn: bool = has_seaborn, **kwargs ): """ Create a bar plot for an Argo index dataframe Parameters ---------- df: Pandas DataFrame As returned by a fetcher index property by: str The profile property to plot. Default is 'institution' style: str Define the axes style: 'white', 'darkgrid', 'whitegrid', 'dark', 'ticks'. Only used if Seaborn is available. Returns ------- fig: :class:`matplotlib.figure.Figure` ax: :class:`matplotlib.axes.Axes` """ if by not in df: raise ValueError("'%s' is not a valid field for a bar plot" % by) with axes_style(style): defaults = {"figsize": (10, 6), "dpi": 90} fig, ax = plt.subplots(**{**defaults, **kwargs}) if with_seaborn: mind = df.groupby(by).size().sort_values(ascending=False).index sns.countplot(y=by, data=df, order=mind) else: df.groupby(by).size().sort_values(ascending=True).plot.barh(ax) ax.set_xlabel("Number of profiles") ax.set_ylabel("") return fig, ax