Skip to content

Commit 7032e38

Browse files
committed
fix(geom_rect): draw each rectangle as its own polygon in non-linear coords
In a non-linear coord, rectangles are drawn as polygons grouped by the `group` aesthetic. A stacked bar shares one group across its segments, so they merged into a single open path and coord.munch bent the join between consecutive rectangles into a triangular spike. Regroup into one polygon per rectangle so each is closed independently.
1 parent 10aef3a commit 7032e38

4 files changed

Lines changed: 20 additions & 0 deletions

File tree

doc/changelog.qmd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ title: Changelog
112112

113113
### Bug Fixes
114114

115+
- Stacked bars in a non-linear coordinate system (e.g.
116+
[](:class:`~plotnine.coord_trans`)) no longer show triangular spikes; each
117+
rectangle is now drawn as its own polygon instead of merging a bar's
118+
segments into a single path.
119+
115120
- The space between facet panels now accounts for the margins of the axis
116121
text, so with free scales large margins no longer push the tick labels
117122
into the neighbouring panel.

plotnine/geoms/geom_rect.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ def draw_panel(
5454
"""
5555
if not coord.is_linear:
5656
data = _rectangles_to_polygons(data)
57+
# Each rectangle is its own closed polygon. Grouping by the
58+
# `group` aesthetic would merge a stacked bar's segments into one
59+
# open path, and coord.munch would then bend the join between
60+
# consecutive rectangles into a spurious spike.
61+
data["group"] = np.repeat(np.arange(len(data) // 4), 4)
5762
for _, gdata in data.groupby("group"):
5863
gdata.reset_index(inplace=True, drop=True)
5964
geom_polygon.draw_group(
2.83 KB
Loading

tests/test_coords.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
coord_flip,
1313
coord_trans,
1414
geom_bar,
15+
geom_col,
1516
geom_line,
1617
geom_point,
1718
ggplot,
1819
xlim,
1920
)
21+
from plotnine.data import mtcars
2022

2123
n = 10 # Some even number greater than 2
2224

@@ -74,6 +76,14 @@ def test_coord_trans_backtransforms():
7476
assert p == "coord_trans_backtransform"
7577

7678

79+
def test_coord_trans_stacked_bars_have_no_spikes():
80+
# Each stacked segment must be its own polygon. If they merge into one
81+
# path, the join between consecutive segments becomes a diagonal that
82+
# munch subdivides into a triangular spike across the bar.
83+
p = ggplot(mtcars, aes("factor(cyl)", "mpg")) + geom_col() + coord_trans()
84+
assert p == "coord_trans_stacked_bars_have_no_spikes"
85+
86+
7787
def test_datetime_coord_limits():
7888
n = 6
7989

0 commit comments

Comments
 (0)