Source code for plotnine.stats.stat_count

import numpy as np
import pandas as pd

from ..doctools import document
from ..exceptions import PlotnineError
from ..mapping.evaluation import after_stat
from ..utils import resolution
from .stat import stat


[docs]@document class stat_count(stat): """ Counts the number of cases at each x position {usage} Parameters ---------- {common_parameters} width : float, optional (default: None) Bar width. By default, set to 90% of the resolution of the data See Also -------- plotnine.stats.stat_bin """ _aesthetics_doc = """ {aesthetics_table} .. rubric:: Options for computed aesthetics :: 'count' # Number of observations at a position 'prop' # Ratio of points in the panel at a position """ REQUIRED_AES = {"x"} DEFAULT_PARAMS = { "geom": "histogram", "position": "stack", "na_rm": False, "width": None, } DEFAULT_AES = {"y": after_stat("count")} CREATES = {"count", "prop"} def setup_params(self, data): params = self.params.copy() if params["width"] is None: params["width"] = resolution(data["x"], False) * 0.9 return params @classmethod def compute_group(cls, data, scales, **params): x = data["x"] if ("y" in data) or ("y" in params): msg = "stat_count() must not be used with a y aesthetic" raise PlotnineError(msg) weight = data.get("weight", [1] * len(x)) # pyright: ignore width = params["width"] xdata_long = pd.DataFrame({"x": x, "weight": weight}) # weighted frequency count count = xdata_long.pivot_table("weight", index=["x"], aggfunc=np.sum)[ "weight" ] x = count.index count = count.to_numpy() return pd.DataFrame( { "count": count, "prop": count / np.abs(count).sum(), "x": x, "width": width, } )