Skip to content

[ENH]: mutation_aspect for Round BoxStyle type #31175

Description

@tricarbonate

Problem

I was trying to make a bar chart with rounded corners, which necessitates using FancyBBoxPatch. However, I would have expected rounded corners to be isotropic by default.

Example showing default behavior and expected behavior (bar on the right):

import matplotlib.pyplot as plt
from matplotlib.patches import FancyBboxPatch, BoxStyle

def add_bar(ax, x, y, w, h, mutation_aspect=1):
    patch = FancyBboxPatch(
        (x, y),
        w,
        h,
        boxstyle=BoxStyle("Round", pad=0, rounding_size=w / 2),
        linewidth=0,
        facecolor="C0",
        mutation_aspect=mutation_aspect,
    )
    ax.add_patch(patch)


fig, ax = plt.subplots(figsize=(10, 5))


x, y, w, h = 0.3, 0, 0.18, 1

# Left: default mutation_aspect=1 (shows issue)
add_bar(ax, x, y, w, h)

# Right: using 1/ax._get_aspect_ratio()
add_bar(ax, x + 0.3, y, w, h, 1 / ax._get_aspect_ratio())

plt.tight_layout()
plt.savefig("reproduce.png", dpi=220)
plt.show()

which gave:

Image

The solution uses private API (ax._get_aspect_ratio()) because ax.get_aspect() returns "auto".

I'm guessing changing the default behavior is not possible for backward compatibility, so my question is: Would an opt-in auto mode for mutation_aspect be acceptable to ensure isotropic rounding?

The same question applies to other BoxStyle types.

Proposed solution

An opt-in auto mode for mutation_aspect (for example passing mutation_aspect="auto") which changes default behavior and sets the mutation_aspect value to 1 / ax._get_aspect_ratio() internally in the FancyBboxPatch class

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions