Source code for easy_mpl._hist


__all__ = ["hist"]

from typing import Union, List

import numpy as np
import matplotlib.pyplot as plt

from .utils import kde, deprecated_argument
from .utils import process_axes, is_dataframe, create_subplots, is_series

[docs]@deprecated_argument(x="data") def hist( data: Union[list, np.ndarray], labels:Union[str, List[str]] = None, share_axes:bool = True, grid: bool = True, subplots_kws:dict = None, add_kde:bool = False, kde_kws:dict = None, line_kws:dict = None, ax: plt.Axes = None, ax_kws: dict = None, show: bool = True, return_axes:bool = False, **kwargs ): """ one stop shop for histogram Parameters ----------- data : list, array, optional array like, numpy ndarray or pandas DataFrame, or list of arrays labels : list/str optional names of the arrays, used for setting the legend share_axes : bool (default=True) whether to draw all the histograms on one axes or not? grid : bool, optional whether to show the grid or not subplots_kws : dict kws which go to plt.subplots() such as figure size (width, height) add_kde: bool, (default=False) whether to add a line representing kernel densitiy estimation or not kde_kws : dict keyword arguments to calculate kde. These will go to :func:`easy_mpl.utils.kde` function. line_kws : dict keyword arguments for drawing the kde line. These will go to :obj:`matplotlib.axes.Axes.plot` function ax : plt.Axes, optional axes on which to draw the plot ax_kws : dict keyword arguments for :py:func:`easy_mpl.utils.process_axes` show : bool, optional whether to show the plot or not return_axes : bool, (default=False) whether to return the axes objects on which histogram/histograms are drawn or not. If True, then the function returns two objects, the first is a tuple (output of axes.hist) and second is the axes/list of axes on which histogram is drawn **kwargs : optional any keyword arguments for :obj:`matplotlib.axes.Axes.hist` Returns ------- same what is returned by :obj:`matplotlib.axes.Axes.hist` Example -------- >>> from easy_mpl import hist >>> import numpy as np >>> hist(np.random.random((10, 1))) See :ref:`sphx_glr_auto_examples_hist.py` for more examples .. _axes.hist: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.hist.html """ if isinstance(data, np.ndarray): if len(data) == data.size: X = [data] names = [None] else: X = [data[:, i] for i in range(data.shape[1])] names = [f"{i}" for i in range(data.shape[1])] elif is_dataframe(data): X = [] for col in data.columns: X.append(data[col].values) names = data.columns.tolist() elif is_series(data): X = data.values names = [data.name] elif isinstance(data, (list, tuple)) and isinstance(data[0], (list, tuple, np.ndarray)): assert all([len(np.array(array_like))==np.array(array_like).size for array_like in data]), f""" All arrays must be one dimensional.""" X = [np.array(x_).reshape(-1,) for x_ in data] names = [None]*len(X) elif isinstance(data, (list, tuple)) and is_dataframe(data[0]): X = [*data] names = [None]*len(X) elif isinstance(data, (list, tuple)) and not is_dataframe(data[0]): X = [data] names = [None] else: raise ValueError(f"unrecognized type of x {type(data)}") if labels is not None: if isinstance(labels, str): labels = [labels] assert len(labels) == len(names), f"{len(names)} does not match data" names = labels if share_axes: nplots = 1 else: nplots = len(names) if nplots == 1: share_axes = True if subplots_kws is None: subplots_kws = dict() if not kde_kws: kde_kws = dict() _line_kws = {'color': 'k'} if line_kws: _line_kws.update(line_kws) f, axes = create_subplots(nplots, ax=ax, **subplots_kws) if isinstance(axes, np.ndarray): axes = axes.flatten() outs = [] for idx, x, name in zip(range(len(names)), X, names): if name: kwargs['label'] = name if add_kde: kwargs['density'] = True if share_axes: assert isinstance(axes, plt.Axes) ax = axes else: ax = axes[idx] out = ax.hist(x, **kwargs) outs.append(out) if add_kde: kde_kws['bins'] = len(out[0]) add_kde_line(ax, x, kde_kws, _line_kws) _ax_kws = dict(grid=grid) if ax_kws: _ax_kws.update(ax_kws) process_axes(ax, **_ax_kws) if name: ax.legend() if show: plt.show() if len(outs)==1: outs = outs[0] if return_axes: return outs, axes return outs
def add_kde_line(axes:plt.Axes, data, kde_kws:dict, line_kws:dict): ind, y = kde(data, **kde_kws) axes.plot(ind, y, **line_kws) return