Source code for plotnine_extra.geoms.geom_half_boxplot

"""
Half-boxplot geom for raincloud plots.

Draws a boxplot shifted to one side, useful for combining
with half-violins and jittered points.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from plotnine.doctools import document
from plotnine.geoms.geom_boxplot import geom_boxplot

if TYPE_CHECKING:
    import pandas as pd
    from matplotlib.axes import Axes
    from plotnine.coords.coord import coord
    from plotnine.iapi import panel_view


[docs] @document class geom_half_boxplot(geom_boxplot): """ Half-width boxplot shifted to one side Draws a narrower boxplot offset to the left or right, designed for combining with half-violins and jittered points in raincloud plots. {usage} Parameters ---------- {common_parameters} side : str Which side to shift to: ``"r"`` (right) or ``"l"`` (left). Default ``"r"``. nudge : float Additional horizontal offset in data units. Default ``0``. half_width : float Width of the half-boxplot as a fraction of the full boxplot width. Default ``0.5``. """ _aesthetics_doc = """ {aesthetics_table} """ DEFAULT_PARAMS = { **geom_boxplot.DEFAULT_PARAMS, "side": "r", "nudge": 0, "half_width": 0.5, }
[docs] @staticmethod def draw_group( data: pd.DataFrame, panel_params: panel_view, coord: coord, ax: Axes, params: dict[str, Any], ): side = params.get("side", "r") nudge = params.get("nudge", 0) half_width = params.get("half_width", 0.5) # Modify the data to shift and narrow the box data = data.copy() if "xmin" in data.columns and "xmax" in data.columns: # Calculate the full width width = data["xmax"] - data["xmin"] center = (data["xmax"] + data["xmin"]) / 2 new_width = width * half_width if side == "r": data["xmin"] = center + nudge data["xmax"] = center + new_width / 2 + nudge else: data["xmin"] = center - new_width / 2 + nudge data["xmax"] = center + nudge # Delegate to parent draw_group return geom_boxplot.draw_group(data, panel_params, coord, ax, params)