mgplot.fill_between_plot
Plot a filled region between two bounds.
1"""Plot a filled region between two bounds.""" 2 3from typing import Final, NotRequired, Unpack 4 5from matplotlib.axes import Axes 6from pandas import DataFrame 7 8from mgplot.axis_utils import map_periodindex, set_labels 9from mgplot.keyword_checking import BaseKwargs, report_kwargs, validate_kwargs 10from mgplot.settings import get_setting 11from mgplot.utilities import check_clean_timeseries, constrain_data, get_axes 12 13# --- constants 14ME: Final[str] = "fill_between_plot" 15REQUIRED_COLUMNS: Final[int] = 2 16DEFAULT_COLOR: Final[str] = "steelblue" 17DEFAULT_ALPHA: Final[float] = 0.3 18 19 20class FillBetweenKwargs(BaseKwargs): 21 """Keyword arguments for the fill_between_plot function.""" 22 23 ax: NotRequired[Axes | None] 24 color: NotRequired[str] 25 alpha: NotRequired[float] 26 label: NotRequired[str | None] 27 linewidth: NotRequired[float] 28 edgecolor: NotRequired[str | None] 29 zorder: NotRequired[int | float] 30 plot_from: NotRequired[int | None] 31 max_ticks: NotRequired[int] 32 33 34def fill_between_plot(data: DataFrame, **kwargs: Unpack[FillBetweenKwargs]) -> Axes: 35 """Plot a filled region between lower and upper bounds. 36 37 Args: 38 data: DataFrame - A two-column DataFrame with PeriodIndex. 39 The first column is the lower bound, the second is the upper bound. 40 kwargs: FillBetweenKwargs - keyword arguments for the plot. 41 42 Returns: 43 Axes - matplotlib Axes object. 44 45 Raises: 46 TypeError: If data is not a DataFrame. 47 ValueError: If data does not have exactly two columns. 48 49 """ 50 # --- validate inputs 51 report_kwargs(caller=ME, **kwargs) 52 validate_kwargs(schema=FillBetweenKwargs, caller=ME, **kwargs) 53 54 if not isinstance(data, DataFrame): 55 raise TypeError(f"data must be a DataFrame for {ME}()") 56 57 if len(data.columns) != REQUIRED_COLUMNS: 58 raise ValueError(f"data must have exactly two columns for {ME}(), got {len(data.columns)}") 59 60 # --- check and constrain data 61 data = check_clean_timeseries(data, ME) 62 data, kwargs_d = constrain_data(data, **kwargs) 63 64 # --- handle PeriodIndex conversion 65 saved_pi = map_periodindex(data) 66 if saved_pi is not None: 67 data = saved_pi[0] 68 69 # --- get axes 70 axes, kwargs_d = get_axes(**kwargs_d) 71 72 if data.empty or data.isna().all().all(): 73 print(f"Warning: No data to plot in {ME}().") 74 return axes 75 76 # --- extract bounds 77 lower = data.iloc[:, 0] 78 upper = data.iloc[:, 1] 79 80 # --- extract plot arguments 81 color = kwargs_d.get("color", DEFAULT_COLOR) 82 alpha = kwargs_d.get("alpha", DEFAULT_ALPHA) 83 label = kwargs_d.get("label", None) 84 linewidth = kwargs_d.get("linewidth", 0) 85 edgecolor = kwargs_d.get("edgecolor", None) 86 zorder = kwargs_d.get("zorder", None) 87 88 # --- plot 89 axes.fill_between( 90 data.index, 91 lower, 92 upper, 93 color=color, 94 alpha=alpha, 95 label=label, 96 linewidth=linewidth, 97 edgecolor=edgecolor, 98 zorder=zorder, 99 ) 100 101 # --- set axis labels 102 if saved_pi is not None: 103 set_labels(axes, saved_pi[1], kwargs_d.get("max_ticks", get_setting("max_ticks"))) 104 105 return axes
ME: Final[str] =
'fill_between_plot'
REQUIRED_COLUMNS: Final[int] =
2
DEFAULT_COLOR: Final[str] =
'steelblue'
DEFAULT_ALPHA: Final[float] =
0.3
class
FillBetweenKwargs(mgplot.keyword_checking.BaseKwargs):
21class FillBetweenKwargs(BaseKwargs): 22 """Keyword arguments for the fill_between_plot function.""" 23 24 ax: NotRequired[Axes | None] 25 color: NotRequired[str] 26 alpha: NotRequired[float] 27 label: NotRequired[str | None] 28 linewidth: NotRequired[float] 29 edgecolor: NotRequired[str | None] 30 zorder: NotRequired[int | float] 31 plot_from: NotRequired[int | None] 32 max_ticks: NotRequired[int]
Keyword arguments for the fill_between_plot function.
def
fill_between_plot( data: pandas.DataFrame, **kwargs: Unpack[FillBetweenKwargs]) -> matplotlib.axes._axes.Axes:
35def fill_between_plot(data: DataFrame, **kwargs: Unpack[FillBetweenKwargs]) -> Axes: 36 """Plot a filled region between lower and upper bounds. 37 38 Args: 39 data: DataFrame - A two-column DataFrame with PeriodIndex. 40 The first column is the lower bound, the second is the upper bound. 41 kwargs: FillBetweenKwargs - keyword arguments for the plot. 42 43 Returns: 44 Axes - matplotlib Axes object. 45 46 Raises: 47 TypeError: If data is not a DataFrame. 48 ValueError: If data does not have exactly two columns. 49 50 """ 51 # --- validate inputs 52 report_kwargs(caller=ME, **kwargs) 53 validate_kwargs(schema=FillBetweenKwargs, caller=ME, **kwargs) 54 55 if not isinstance(data, DataFrame): 56 raise TypeError(f"data must be a DataFrame for {ME}()") 57 58 if len(data.columns) != REQUIRED_COLUMNS: 59 raise ValueError(f"data must have exactly two columns for {ME}(), got {len(data.columns)}") 60 61 # --- check and constrain data 62 data = check_clean_timeseries(data, ME) 63 data, kwargs_d = constrain_data(data, **kwargs) 64 65 # --- handle PeriodIndex conversion 66 saved_pi = map_periodindex(data) 67 if saved_pi is not None: 68 data = saved_pi[0] 69 70 # --- get axes 71 axes, kwargs_d = get_axes(**kwargs_d) 72 73 if data.empty or data.isna().all().all(): 74 print(f"Warning: No data to plot in {ME}().") 75 return axes 76 77 # --- extract bounds 78 lower = data.iloc[:, 0] 79 upper = data.iloc[:, 1] 80 81 # --- extract plot arguments 82 color = kwargs_d.get("color", DEFAULT_COLOR) 83 alpha = kwargs_d.get("alpha", DEFAULT_ALPHA) 84 label = kwargs_d.get("label", None) 85 linewidth = kwargs_d.get("linewidth", 0) 86 edgecolor = kwargs_d.get("edgecolor", None) 87 zorder = kwargs_d.get("zorder", None) 88 89 # --- plot 90 axes.fill_between( 91 data.index, 92 lower, 93 upper, 94 color=color, 95 alpha=alpha, 96 label=label, 97 linewidth=linewidth, 98 edgecolor=edgecolor, 99 zorder=zorder, 100 ) 101 102 # --- set axis labels 103 if saved_pi is not None: 104 set_labels(axes, saved_pi[1], kwargs_d.get("max_ticks", get_setting("max_ticks"))) 105 106 return axes
Plot a filled region between lower and upper bounds.
Args: data: DataFrame - A two-column DataFrame with PeriodIndex. The first column is the lower bound, the second is the upper bound. kwargs: FillBetweenKwargs - keyword arguments for the plot.
Returns: Axes - matplotlib Axes object.
Raises: TypeError: If data is not a DataFrame. ValueError: If data does not have exactly two columns.