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 plot_from: NotRequired[int | None] 30 max_ticks: NotRequired[int] 31 32 33def fill_between_plot(data: DataFrame, **kwargs: Unpack[FillBetweenKwargs]) -> Axes: 34 """Plot a filled region between lower and upper bounds. 35 36 Args: 37 data: DataFrame - A two-column DataFrame with PeriodIndex. 38 The first column is the lower bound, the second is the upper bound. 39 kwargs: FillBetweenKwargs - keyword arguments for the plot. 40 41 Returns: 42 Axes - matplotlib Axes object. 43 44 Raises: 45 TypeError: If data is not a DataFrame. 46 ValueError: If data does not have exactly two columns. 47 48 """ 49 # --- validate inputs 50 report_kwargs(caller=ME, **kwargs) 51 validate_kwargs(schema=FillBetweenKwargs, caller=ME, **kwargs) 52 53 if not isinstance(data, DataFrame): 54 raise TypeError(f"data must be a DataFrame for {ME}()") 55 56 if len(data.columns) != REQUIRED_COLUMNS: 57 raise ValueError(f"data must have exactly two columns for {ME}(), got {len(data.columns)}") 58 59 # --- check and constrain data 60 data = check_clean_timeseries(data, ME) 61 data, kwargs_d = constrain_data(data, **kwargs) 62 63 # --- handle PeriodIndex conversion 64 saved_pi = map_periodindex(data) 65 if saved_pi is not None: 66 data = saved_pi[0] 67 68 # --- get axes 69 axes, kwargs_d = get_axes(**kwargs_d) 70 71 if data.empty or data.isna().all().all(): 72 print(f"Warning: No data to plot in {ME}().") 73 return axes 74 75 # --- extract bounds 76 lower = data.iloc[:, 0] 77 upper = data.iloc[:, 1] 78 79 # --- extract plot arguments 80 color = kwargs_d.get("color", DEFAULT_COLOR) 81 alpha = kwargs_d.get("alpha", DEFAULT_ALPHA) 82 label = kwargs_d.get("label", None) 83 linewidth = kwargs_d.get("linewidth", 0) 84 edgecolor = kwargs_d.get("edgecolor", None) 85 86 # --- plot 87 axes.fill_between( 88 data.index, 89 lower, 90 upper, 91 color=color, 92 alpha=alpha, 93 label=label, 94 linewidth=linewidth, 95 edgecolor=edgecolor, 96 ) 97 98 # --- set axis labels 99 if saved_pi is not None: 100 set_labels(axes, saved_pi[1], kwargs_d.get("max_ticks", get_setting("max_ticks"))) 101 102 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 plot_from: NotRequired[int | None] 31 max_ticks: NotRequired[int]
Keyword arguments for the fill_between_plot function.
def
fill_between_plot( data: pandas.core.frame.DataFrame, **kwargs: Unpack[FillBetweenKwargs]) -> matplotlib.axes._axes.Axes:
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 87 # --- plot 88 axes.fill_between( 89 data.index, 90 lower, 91 upper, 92 color=color, 93 alpha=alpha, 94 label=label, 95 linewidth=linewidth, 96 edgecolor=edgecolor, 97 ) 98 99 # --- set axis labels 100 if saved_pi is not None: 101 set_labels(axes, saved_pi[1], kwargs_d.get("max_ticks", get_setting("max_ticks"))) 102 103 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.