diff --git a/pyfixest/estimation/FixestMulti_.py b/pyfixest/estimation/FixestMulti_.py index 93d32a77..fe137e99 100644 --- a/pyfixest/estimation/FixestMulti_.py +++ b/pyfixest/estimation/FixestMulti_.py @@ -1,4 +1,6 @@ +import functools import warnings +from importlib import import_module from typing import Optional, Union import numpy as np @@ -11,7 +13,6 @@ from pyfixest.estimation.fepois_ import Fepois, _check_for_separation from pyfixest.estimation.FormulaParser import FixestFormulaParser from pyfixest.estimation.model_matrix_fixest_ import model_matrix_fixest -from pyfixest.report.visualize import coefplot, iplot from pyfixest.utils.dev_utils import _polars_to_pandas @@ -42,6 +43,21 @@ def __init__(self, data: pd.DataFrame) -> None: self._data.reset_index(drop=True, inplace=True) self.all_fitted_models = {} + # set functions inherited from other modules + _module = import_module("pyfixest.report") + _tmp = getattr(_module, "coefplot") + self.coefplot = functools.partial(_tmp, models=self.all_fitted_models.values()) + self.coefplot.__doc__ = _tmp.__doc__ + _tmp = getattr(_module, "iplot") + self.iplot = functools.partial(_tmp, models=self.all_fitted_models.values()) + self.iplot.__doc__ = _tmp.__doc__ + _tmp = getattr(_module, "summary") + self.summary = functools.partial(_tmp, models=self.all_fitted_models.values()) + self.summary.__doc__ = _tmp.__doc__ + _tmp = getattr(_module, "etable") + self.etable = functools.partial(_tmp, models=self.all_fitted_models.values()) + self.etable.__doc__ = _tmp.__doc__ + def _prepare_estimation( self, estimation: str, @@ -479,14 +495,6 @@ def tidy(self) -> pd.DataFrame: return res - def summary(self, digits: int = 3) -> None: # noqa: D102 - for x in list(self.all_fitted_models.keys()): - fxst = self.all_fitted_models[x] - fxst.summary(digits=digits) - - def etable(self, digits: int = 3) -> pd.DataFrame: # noqa: D102 - return self.tidy().T.round(digits) - def coef(self) -> pd.Series: """ Obtain the coefficients of the fitted models. @@ -549,115 +557,6 @@ def confint(self) -> pd.Series: """ return self.tidy()[["2.5%", "97.5%"]] - def iplot( - self, - alpha: float = 0.05, - figsize: tuple = (500, 300), - yintercept: Union[int, str, None] = None, - xintercept: Union[int, str, None] = None, - rotate_xticks: int = 0, - title: Optional[str] = None, - coord_flip: Optional[bool] = True, - ): - """ - Plot model coefficients. - - Plot model coefficients with confidence intervals for variable interactions - specified via the `i()` syntax. - - Parameters - ---------- - alpha : float, optional - The significance level for the confidence intervals. Default is 0.05. - figsize : tuple, optional - The size of the figure. Default is (10, 10). - yintercept : Union[int, str, None], optional - The value at which to draw a horizontal line. - xintercept : Union[int, str, None], optional - The value at which to draw a vertical line. - rotate_xticks : int, optional - The rotation angle for x-axis tick labels. Default is 0. - title : str, optional - The title of the plot. Default is None. - coord_flip : bool, optional - Whether to flip the coordinates of the plot. Default is True. - - Returns - ------- - lets-plot figure - A lets-plot figure of coefficients (and respective CIs) interacted - via the `i()` syntax. - """ - models = self.all_fitted_models - # get a list, not a dict, as iplot only works with lists - models = [models[x] for x in list(self.all_fitted_models.keys())] - - plot = iplot( - models=models, - alpha=alpha, - figsize=figsize, - yintercept=yintercept, - xintercept=xintercept, - rotate_xticks=rotate_xticks, - title=title, - coord_flip=coord_flip, - ) - - return plot - - def coefplot( - self, - alpha: float = 0.05, - figsize: tuple = (500, 300), - yintercept: int = 0, - rotate_xticks: int = 0, - title: Optional[str] = None, - coord_flip: Optional[bool] = True, - ): - """ - Plot estimation results. - - The plot() method is only defined for single regressions. - - Parameters - ---------- - alpha : float - The significance level for the confidence intervals. Default is 0.05. - figsize : tuple - The size of the figure. Default is (5, 2). - yintercept : float - The value of the y-intercept. Default is 0. - figtitle:str, optional - The title of the figure. Default is None. - figtext : str, optional - The text at the bottom of the figure. Default is None. - title : str, optional - The title of the plot. Default is None. - coord_flip : bool, optional - Whether to flip the coordinates of the plot. Default is True. - - Returns - ------- - lets-plot figure - A lets-plot figure of regression coefficients. - """ - # get a list, not a dict, as iplot only works with lists - models = self.all_fitted_models - models = [models[x] for x in list(self.all_fitted_models.keys())] - - plot = coefplot( - models=models, - figsize=figsize, - alpha=alpha, - yintercept=yintercept, - xintercept=None, - rotate_xticks=rotate_xticks, - title=title, - coord_flip=coord_flip, - ) - - return plot - def wildboottest( self, B: int, diff --git a/pyfixest/estimation/feols_.py b/pyfixest/estimation/feols_.py index c74fc0b7..b1d68a97 100644 --- a/pyfixest/estimation/feols_.py +++ b/pyfixest/estimation/feols_.py @@ -1,3 +1,4 @@ +import functools import re import warnings from importlib import import_module @@ -262,6 +263,18 @@ def __init__( self._adj_r2 = None self._adj_r2_within = None + # set functions inherited from other modules + _module = import_module("pyfixest.report") + _tmp = getattr(_module, "coefplot") + self.coefplot = functools.partial(_tmp, models=[self]) + self.coefplot.__doc__ = _tmp.__doc__ + _tmp = getattr(_module, "iplot") + self.iplot = functools.partial(_tmp, models=[self]) + self.iplot.__doc__ = _tmp.__doc__ + _tmp = getattr(_module, "summary") + self.summary = functools.partial(_tmp, models=[self]) + self.summary.__doc__ = _tmp.__doc__ + def get_fit(self) -> None: """ Fit an OLS model. @@ -728,115 +741,6 @@ def wald_test(self, R=None, q=None, distribution="F") -> None: return res - def coefplot( - self, - alpha: float = 0.05, - figsize: tuple[int, int] = (500, 300), - yintercept: Optional[float] = 0, - xintercept: Optional[float] = None, - rotate_xticks: int = 0, - coefficients: Optional[list[str]] = None, - title: Optional[str] = None, - coord_flip: Optional[bool] = True, - ): - """ - Create a coefficient plot to visualize model coefficients. - - Parameters - ---------- - alpha : float, optional - Significance level for highlighting significant coefficients. - Defaults to None. - figsize : tuple[int, int], optional - Size of the plot (width, height) in inches. Defaults to None. - yintercept : float, optional - Value to set as the y-axis intercept (vertical line). Defaults to None. - xintercept : float, optional - Value to set as the x-axis intercept (horizontal line). Defaults to None. - rotate_xticks : int, optional - Rotation angle for x-axis tick labels. Defaults to None. - coefficients : list[str], optional - List of coefficients to include in the plot. - If None, all coefficients are included. - title : str, optional - Title of the plot. Defaults to None. - coord_flip : bool, optional - Whether to flip the coordinates of the plot. Defaults to None. - - Returns - ------- - lets-plot figure - A lets-plot figure with coefficient estimates and confidence intervals. - """ - # lazy loading to avoid circular import - visualize_module = import_module("pyfixest.report") - _coefplot = getattr(visualize_module, "coefplot") - - plot = _coefplot( - models=[self], - alpha=alpha, - figsize=figsize, - yintercept=yintercept, - xintercept=xintercept, - rotate_xticks=rotate_xticks, - coefficients=coefficients, - title=title, - coord_flip=coord_flip, - ) - - return plot - - def iplot( - self, - alpha: float = 0.05, - figsize: tuple[int, int] = (500, 300), - yintercept: Optional[float] = None, - xintercept: Optional[float] = None, - rotate_xticks: int = 0, - title: Optional[str] = None, - coord_flip: Optional[bool] = True, - ): - """ - Create coefficient plots for variables interacted via `i()` syntax. - - Parameters - ---------- - alpha : float, optional - Significance level for visualization options. Defaults to 0.05. - figsize : tuple[int, int], optional - Size of the plot (width, height) in inches. Defaults to (500, 300). - yintercept : float, optional - Value to set as the y-axis intercept (vertical line). Defaults to None. - xintercept : float, optional - Value to set as the x-axis intercept (horizontal line). Defaults to None. - rotate_xticks : int, optional - Rotation angle for x-axis tick labels. Defaults to 0. - title : str, optional - Title of the plot. Defaults to None. - coord_flip : bool, optional - Whether to flip the coordinates of the plot. Defaults to True. - - Returns - ------- - lets-plot figure - A lets-plot figure with coefficient estimates and confidence intervals. - """ - visualize_module = import_module("pyfixest.report") - _iplot = getattr(visualize_module, "iplot") - - plot = _iplot( - models=[self], - alpha=alpha, - figsize=figsize, - yintercept=yintercept, - xintercept=xintercept, - rotate_xticks=rotate_xticks, - title=title, - coord_flip=coord_flip, - ) - - return plot - def wildboottest( self, B: int, @@ -1662,25 +1566,6 @@ def resid(self) -> np.ndarray: """ return self._u_hat - def summary(self, digits=3) -> None: - """ - Summary of estimated model. - - Parameters - ---------- - digits : int, optional - The number of digits to be displayed. Defaults to 3. - - Returns - ------- - None - """ - # lazy loading to avoid circular import - summarize_module = import_module("pyfixest.report") - _summary = getattr(summarize_module, "summary") - - return _summary(models=self, digits=digits) - def _check_vcov_input(vcov, data): """ diff --git a/pyfixest/multcomp.py b/pyfixest/multcomp.py index c3f7d229..c7395904 100644 --- a/pyfixest/multcomp.py +++ b/pyfixest/multcomp.py @@ -6,47 +6,11 @@ import pyfixest from pyfixest.estimation import Feols, Fepois from pyfixest.utils._exceptions import find_stack_level +from pyfixest.utils.dev_utils import docstring_from +@docstring_from(pyfixest.bonferroni) def bonferroni(models: Union[list[Feols, Fepois], Fepois], param: str) -> pd.DataFrame: - """ - Compute Bonferroni adjusted p-values for multiple hypothesis testing. - - For each model, it is assumed that tests to adjust are of the form - "param = 0". - - 'pyfixest.multcomp.bonferroni' is deprecated and will be removed in a future - version. Please use 'pyfixest.bonferroni' instead. You may refer the updated - documentation at: https://s3alfisc.github.io/pyfixest/quickstart.html - - Parameters - ---------- - models : list[Feols, Fepois], Feols or Fepois - A list of models for which the p-values should be adjusted, or a Feols or - Fepois object. - param : str - The parameter for which the p-values should be adjusted. - - Returns - ------- - pd.DataFrame - A DataFrame containing estimation statistics, including the Bonferroni - adjusted p-values. - - Examples - -------- - ```python - from pyfixest.estimation import feols - from pyfixest.utils import get_data - from pyfixest.multcomp import bonferroni - - data = get_data().dropna() - fit1 = feols("Y ~ X1", data=data) - fit2 = feols("Y ~ X1 + X2", data=data) - bonf_df = bonferroni([fit1, fit2], param="X1") - bonf_df - ``` - """ warnings.warn( "'pyfixest.multcomp.bonferroni' is deprecated and " "will be removed in a future version.\n" @@ -62,56 +26,10 @@ def bonferroni(models: Union[list[Feols, Fepois], Fepois], param: str) -> pd.Dat ) +@docstring_from(pyfixest.rwolf) def rwolf( models: Union[list[Feols], Feols], param: str, B: int, seed: int ) -> pd.DataFrame: - """ - Compute Romano-Wolf adjusted p-values for multiple hypothesis testing. - - For each model, it is assumed that tests to adjust are of the form - "param = 0". This function uses the `wildboottest()` method for running the - bootstrap, hence models of type `Feiv` or `Fepois` are not supported. - - 'pyfixest.multcomp.rwolf' is deprecated and will be removed in a future - version. Please use 'pyfixest.rwolf' instead. You may refer the updated - documentation at: https://s3alfisc.github.io/pyfixest/quickstart.html - - Parameters - ---------- - models : list[Feols] or FixestMulti - A list of models for which the p-values should be computed, or a - FixestMulti object. - Models of type `Feiv` or `Fepois` are not supported. - param : str - The parameter for which the p-values should be computed. - B : int - The number of bootstrap replications. - seed : int - The seed for the random number generator. - - Returns - ------- - pd.DataFrame - A DataFrame containing estimation statistics, including the Romano-Wolf - adjusted p-values. - - Examples - -------- - ```python - from pyfixest.estimation import feols - from pyfixest.utils import get_data - from pyfixest.multcomp import rwolf - - data = get_data().dropna() - fit = feols("Y ~ Y2 + X1 + X2", data=data) - rwolf(fit.to_list(), "X1", B=9999, seed=123) - - fit1 = feols("Y ~ X1", data=data) - fit2 = feols("Y ~ X1 + X2", data=data) - rwolf_df = rwolf([fit1, fit2], "X1", B=9999, seed=123) - rwolf_df - ``` - """ warnings.warn( "'pyfixest.multcomp.rwolf' is deprecated and " "will be removed in a future version.\n" diff --git a/pyfixest/report/summarize.py b/pyfixest/report/summarize.py index a44360e8..9de5e555 100644 --- a/pyfixest/report/summarize.py +++ b/pyfixest/report/summarize.py @@ -350,7 +350,7 @@ def _post_processing_input_checks(models): models = [models] else: - if isinstance(models, list): + if isinstance(models, (list, type({}.values()))): for model in models: if not isinstance(model, (Feols, Fepois)): raise TypeError( diff --git a/pyfixest/report/visualize.py b/pyfixest/report/visualize.py index 09790807..6726df24 100644 --- a/pyfixest/report/visualize.py +++ b/pyfixest/report/visualize.py @@ -21,6 +21,7 @@ ) from pyfixest.report.summarize import _post_processing_input_checks +from pyfixest.utils.dev_utils import _select_order_coefs LetsPlot.setup_html() @@ -34,10 +35,11 @@ def iplot( rotate_xticks: int = 0, title: Optional[str] = None, coord_flip: Optional[bool] = True, + keep: Optional[Union[list, str]] = [], + drop: Optional[Union[list, str]] = [], + exact_match: Optional[bool] = False, ): - """ - Plot model coefficients. - + r""" Plot model coefficients for variables interacted via "i()" syntax, with confidence intervals. @@ -60,6 +62,23 @@ def iplot( The title of the plot. coord_flip : bool, optional Whether to flip the coordinates of the plot. Default is True. + keep: str or list of str, optional + The pattern for retaining coefficient names. You can pass a string (one + pattern) or a list (multiple patterns). Default is keeping all coefficients. + You should use regular expressions to select coefficients. + "age", # would keep all coefficients containing age + r"^tr", # would keep all coefficients starting with tr + r"\\d$", # would keep all coefficients ending with number + Output will be in the order of the patterns. + drop: str or list of str, optional + The pattern for excluding coefficient names. You can pass a string (one + pattern) or a list (multiple patterns). Syntax is the same as for `keep`. + Default is keeping all coefficients. Parameter `keep` and `drop` can be + used simultaneously. + exact_match: bool, optional + Whether to use exact match for `keep` and `drop`. Default is False. + If True, the pattern will be matched exactly to the coefficient name + instead of using regular expressions. Returns ------- @@ -84,8 +103,7 @@ def iplot( df_all = [] all_icovars = [] - for x, _ in enumerate(models): - fxst = models[x] + for x, fxst in enumerate(list(models)): if fxst._icovars is None: raise ValueError( f"The {x} th estimated model did not have ivars / 'i()' model syntax." @@ -101,9 +119,14 @@ def iplot( all_icovars = list(set(all_icovars)) df = pd.concat(df_all, axis=0) + if keep or drop: + idxs = _select_order_coefs(df["Coefficient"], keep, drop, exact_match) + else: + idxs = df["Coefficient"] + df = df.loc[df["Coefficient"].isin(idxs), :] fml_list = df.index.unique() # noqa: F841 # keep only coefficients interacted via the i() syntax - df = df[df.Coefficient.isin(all_icovars)].reset_index() + df = df[df["Coefficient"].isin(all_icovars)].reset_index() return _coefplot( df=df, @@ -124,11 +147,13 @@ def coefplot( yintercept: float = 0, xintercept: float = None, rotate_xticks: int = 0, - coefficients: Optional[list[str]] = None, title: Optional[str] = None, coord_flip: Optional[bool] = True, + keep: Optional[Union[list, str]] = [], + drop: Optional[Union[list, str]] = [], + exact_match: Optional[bool] = False, ): - """ + r""" Plot model coefficients with confidence intervals. Parameters @@ -145,12 +170,27 @@ def coefplot( The value at which to draw a vertical line on the plot. Default is None. rotate_xticks : float, optional The angle in degrees to rotate the xticks labels. Default is 0 (no rotation). - coefficients : list, optional - A list of coefficients to plot. If None, all coefficients are plotted. title : str, optional The title of the plot. coord_flip : bool, optional Whether to flip the coordinates of the plot. Default is True. + keep: str or list of str, optional + The pattern for retaining coefficient names. You can pass a string (one + pattern) or a list (multiple patterns). Default is keeping all coefficients. + You should use regular expressions to select coefficients. + "age", # would keep all coefficients containing age + r"^tr", # would keep all coefficients starting with tr + r"\\d$", # would keep all coefficients ending with number + Output will be in the order of the patterns. + drop: str or list of str, optional + The pattern for excluding coefficient names. You can pass a string (one + pattern) or a list (multiple patterns). Syntax is the same as for `keep`. + Default is keeping all coefficients. Parameter `keep` and `drop` can be + used simultaneously. + exact_match: bool, optional + Whether to use exact match for `keep` and `drop`. Default is False. + If True, the pattern will be matched exactly to the coefficient name + instead of using regular expressions. Returns ------- @@ -172,17 +212,18 @@ def coefplot( """ models = _post_processing_input_checks(models) df_all = [] - for x, _ in enumerate(models): - fxst = models[x] + for fxst in models: df_model = fxst.tidy().reset_index() df_model["fml"] = fxst._fml df_model.set_index("fml", inplace=True) df_all.append(df_model) df = pd.concat(df_all, axis=0) - - if coefficients is not None: - df = df[df.Coefficient.isin(coefficients)].reset_index() + if keep or drop: + idxs = _select_order_coefs(df.index, keep, drop, exact_match) + else: + idxs = df.index + df = df.loc[idxs, :].reset_index() return _coefplot( df=df, diff --git a/pyfixest/summarize.py b/pyfixest/summarize.py index c5e4243d..1833fa80 100644 --- a/pyfixest/summarize.py +++ b/pyfixest/summarize.py @@ -6,8 +6,10 @@ import pyfixest from pyfixest.estimation import Feiv, Feols, Fepois from pyfixest.utils._exceptions import find_stack_level +from pyfixest.utils.dev_utils import docstring_from +@docstring_from(pyfixest.report.etable) def etable( models: Union[Feols, Fepois, Feiv, list], type: Optional[str] = "md", @@ -19,61 +21,6 @@ def etable( exact_match: Optional[bool] = False, **kwargs, ) -> Union[pd.DataFrame, str]: - r""" - Create an esttab-like table from a list of models. - - 'pyfixest.summarize.etable' is deprecated and will be removed in a future - version. Please use 'pyfixest.etable' instead. You may refer the updated - documentation at: https://s3alfisc.github.io/pyfixest/quickstart.html - - Parameters - ---------- - models : list - A list of models of type Feols, Feiv, Fepois. - type : str, optional - Type of output. Either "df" for pandas DataFrame, "md" for markdown, - or "tex" for LaTeX table. Default is "md". - signif_code : list, optional - Significance levels for the stars. Default is [0.001, 0.01, 0.05]. - If None, no stars are printed. - coef_fmt : str, optional - The format of the coefficient (b), standard error (se), t-stats (t), and - p-value (p). Default is `"b (se)"`. - Spaces ` `, parentheses `()`, brackets `[]`, newlines `\n` are supported. - Newline is not support for LaTeX output. - custom_stats: dict, optional - A dictionary of custom statistics. "b", "se", "t", or "p" are reserved. - keep: str or list of str, optional - The pattern for retaining coefficient names. You can pass a string (one - pattern) or a list (multiple patterns). Default is keeping all coefficients. - You should use regular expressions to select coefficients. - "age", # would keep all coefficients containing age - r"^tr", # would keep all coefficients starting with tr - r"\\d$", # would keep all coefficients ending with number - Output will be in the order of the patterns. - drop: str or list of str, optional - The pattern for excluding coefficient names. You can pass a string (one - pattern) or a list (multiple patterns). Syntax is the same as for `keep`. - Default is keeping all coefficients. Parameter `keep` and `drop` can be - used simultaneously. - exact_match: bool, optional - Whether to use exact match for `keep` and `drop`. Default is False. - If True, the pattern will be matched exactly to the coefficient name - instead of using regular expressions. - digits: int - The number of digits to round to. - thousands_sep: bool, optional - The thousands separator. Default is False. - scientific_notation: bool, optional - Whether to use scientific notation. Default is True. - scientific_notation_threshold: int, optional - The threshold for using scientific notation. Default is 10_000. - - Returns - ------- - pandas.DataFrame - A DataFrame with the coefficients and standard errors of the models. - """ # noqa: D301 warnings.warn( "'pyfixest.summarize.etable' is deprecated and " "will be removed in a future version.\n" @@ -96,45 +43,10 @@ def etable( ) +@docstring_from(pyfixest.report.summary) def summary( models: Union[Feols, Fepois, Feiv, list], digits: Optional[int] = 3 ) -> None: - """ - Print a summary of estimation results for each estimated model. - - For each model, this method prints a header indicating the fixed-effects and the - dependent variable, followed by a table of coefficient estimates with standard - errors, t-values, and p-values. - - 'pyfixest.summarize.summary' is deprecated and will be removed in a future - version. Please use 'pyfixest.summary' instead. You may refer the updated - documentation at: https://s3alfisc.github.io/pyfixest/quickstart.html - - Parameters - ---------- - digits : int, optional - The number of decimal places to round the summary statistics to. Default is 3. - - Returns - ------- - None - - Examples - -------- - ```{python} - from pyfixest.utils import get_data - from pyfixest.estimation import feols - from pyfixest.summarize import summary - - # load data - df = get_data() - fit1 = feols("Y~X1 + X2 | f1", df) - fit2 = feols("Y~X1 + X2 | f1 + f2", df) - fit3 = feols("Y~X1 + X2 | f1 + f2 + f3", df) - - summary([fit1, fit2, fit3]) - ``` - """ warnings.warn( "'pyfixest.summarize.summary' is deprecated and " "will be removed in a future version.\n" diff --git a/pyfixest/utils/dev_utils.py b/pyfixest/utils/dev_utils.py index 7e8c329d..21d244f2 100644 --- a/pyfixest/utils/dev_utils.py +++ b/pyfixest/utils/dev_utils.py @@ -118,3 +118,13 @@ def _select_order_coefs( res = _coefs return res + + +def docstring_from(func, custom_doc=""): + """Copy the docstring of another function.""" + + def decorator(target_func): + target_func.__doc__ = custom_doc + "\n\n" + func.__doc__ + return target_func + + return decorator diff --git a/pyfixest/visualize.py b/pyfixest/visualize.py index ac7de9b1..be4a1be4 100644 --- a/pyfixest/visualize.py +++ b/pyfixest/visualize.py @@ -3,8 +3,10 @@ import pyfixest from pyfixest.utils._exceptions import find_stack_level +from pyfixest.utils.dev_utils import docstring_from +@docstring_from(pyfixest.iplot) def iplot( models, alpha: float = 0.05, @@ -15,56 +17,6 @@ def iplot( title: Optional[str] = None, coord_flip: Optional[bool] = True, ): - """ - Plot model coefficients. - - Plot model coefficients for variables interacted via "i()" syntax, with - confidence intervals. - - 'pyfixest.visualize.iplot' is deprecated and will be removed in a future - version. Please use 'pyfixest.iplot' instead. You may refer the updated - documentation at: https://s3alfisc.github.io/pyfixest/quickstart.html - - Parameters - ---------- - models : list or object - A list of fitted models of type `Feols` or - `Fepois`, or just a single model. - figsize : tuple - The size of the figure. - alpha : float - The significance level for the confidence intervals. - yintercept : int or None, optional - The value at which to draw a horizontal line on the plot. - xintercept : int or None, optional - The value at which to draw a vertical line on the plot. - rotate_xticks : float, optional - The angle in degrees to rotate the xticks labels. Default is 0 (no rotation). - title : str, optional - The title of the plot. - coord_flip : bool, optional - Whether to flip the coordinates of the plot. Default is True. - - Returns - ------- - object - A lets-plot figure. - - Examples - -------- - ```{python} - from pyfixest.utils import get_data - from pyfixest.estimation import feols - from pyfixest.visualize import iplot - - df = get_data() - fit1 = feols("Y ~ i(f1)", data = df) - fit2 = feols("Y ~ i(f1) + X2", data = df) - fit3 = feols("Y ~ i(f1) + X2 | f2", data = df) - - iplot([fit1, fit2, fit3]) - ``` - """ warnings.warn( "'pyfixest.visualize.iplot' is deprecated and " "will be removed in a future version.\n" @@ -86,6 +38,7 @@ def iplot( ) +@docstring_from(pyfixest.coefplot) def coefplot( models: list, alpha: int = 0.05, @@ -97,54 +50,6 @@ def coefplot( title: Optional[str] = None, coord_flip: Optional[bool] = True, ): - """ - Plot model coefficients with confidence intervals. - - 'pyfixest.visualize.coefplot' is deprecated and will be removed in a future - version. Please use 'pyfixest.coefplot' instead. You may refer the updated - documentation at: https://s3alfisc.github.io/pyfixest/quickstart.html - - Parameters - ---------- - models : list or object - A list of fitted models of type `Feols` or `Fepois`, or just a single model. - figsize : tuple - The size of the figure. - alpha : float - The significance level for the confidence intervals. - yintercept : float or None, optional - The value at which to draw a horizontal line on the plot. Default is 0. - xintercept : float or None, optional - The value at which to draw a vertical line on the plot. Default is None. - rotate_xticks : float, optional - The angle in degrees to rotate the xticks labels. Default is 0 (no rotation). - coefficients : list, optional - A list of coefficients to plot. If None, all coefficients are plotted. - title : str, optional - The title of the plot. - coord_flip : bool, optional - Whether to flip the coordinates of the plot. Default is True. - - Returns - ------- - object - A lets-plot figure. - - Examples - -------- - ```{python} - from pyfixest.utils import get_data - from pyfixest.estimation import feols - from pyfixest.visualize import coefplot - - df = get_data() - fit1 = feols("Y ~ X1", data = df) - fit2 = feols("Y ~ X1 + X2", data = df) - fit3 = feols("Y ~ X1 + X2 | f1", data = df) - - coefplot([fit1, fit2, fit3]) - ``` - """ warnings.warn( "'pyfixest.visualize.coefplot' is deprecated and " "will be removed in a future version.\n" diff --git a/pyproject.toml b/pyproject.toml index 680bf103..5ff189d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,10 +78,14 @@ ignore = [ "D104", # missing docstring in public package "SIM110", # Use all instead of `for` loop "TRY003", # Avoid specifying long messages outside the exception class + "D205", # 1 blank line required between summary line and description ] [tool.ruff.lint.per-file-ignores] "tests/**/*.py" = ["D100", "D103"] +"pyfixest/multcomp.py" = ["D103"] +"pyfixest/summarize.py" = ["D103"] +"pyfixest/visualize.py" = ["D103"] [tool.ruff.lint.pycodestyle] max-doc-length = 88 diff --git a/tests/test_plots.py b/tests/test_plots.py index fc1af5df..2dc400aa 100644 --- a/tests/test_plots.py +++ b/tests/test_plots.py @@ -26,6 +26,8 @@ def test_iplot(data): iplot([fit1, fit2]) iplot([fit1, fit2], yintercept=0) + iplot([fit1, fit2], drop="T.12") + with pytest.raises(ValueError): fit3 = feols(fml="Y ~ X1", data=data, vcov="iid") fit3.iplot() @@ -46,6 +48,8 @@ def test_coefplot(data): coefplot(fit1) coefplot([fit1, fit2]) coefplot([fit1, fit2], yintercept=0) + coefplot([fit1, fit2], keep="X") + coefplot([fit1, fit2], drop="X") fit_multi = feols(fml="Y + Y2 ~ i(f2, X1)", data=data) fit_multi.coefplot()