Exemplo n.º 1
0
def annot_bars(
    ax: plt.Axes,
    dist: float = 0.15,
    color: str = "k",
    compact: bool = False,
    orient: str = "h",
    format_spec: str = "{x:.2f}",
    fontsize: int = 12,
    alpha: float = 0.5,
    drop_last: int = 0,
    **kwargs,
) -> None:
    """Annotate a bar graph with the bar values.

    Parameters
    ----------
    ax : Axes
        Axes object to annotate.
    dist : float, optional
        Distance from ends as fraction of max bar. Defaults to 0.15.
    color : str, optional
        Text color. Defaults to "k".
    compact : bool, optional
        Annotate inside the bars. Defaults to False.
    orient : str, optional
        Bar orientation. Defaults to "h".
    format_spec : str, optional
        Format string for annotations. Defaults to ".2f".
    fontsize : int, optional
        Font size. Defaults to 12.
    alpha : float, optional
        Opacity of text. Defaults to 0.5.
    drop_last : int, optional
        Number of bars to ignore on tail end. Defaults to 0.
    """
    if not compact:
        dist = -dist

    xb = np.array(ax.get_xbound()) * (1 + abs(2 * dist))
    ax.set_xbound(*xb)

    max_bar = np.abs([b.get_width() for b in ax.patches]).max()
    dist = dist * max_bar
    for bar in ax.patches[:-drop_last or len(ax.patches)]:
        if orient.lower() == "h":
            x = bar.get_width()
            x = x + dist if x < 0 else x - dist
            y = bar.get_y() + bar.get_height() / 2
        elif orient.lower() == "v":
            x = bar.get_x() + bar.get_width() / 2
            y = bar.get_height()
            y = y + dist if y < 0 else y - dist
        else:
            raise ValueError("`orient` must be 'h' or 'v'")

        text = format_spec.format(x=bar.get_width())
        ax.annotate(
            text,
            (x, y),
            ha="center",
            va="center",
            c=color,
            fontsize=fontsize,
            alpha=alpha,
            **kwargs,
        )