diff --git a/doc/changelog.qmd b/doc/changelog.qmd index 46f687e24..0afaea656 100644 --- a/doc/changelog.qmd +++ b/doc/changelog.qmd @@ -116,6 +116,11 @@ title: Changelog the closing edge of a polygon is now curved along with the rest of its boundary instead of being drawn as a straight chord. +- Stacked bars in a non-linear coordinate system (e.g. + [](:class:`~plotnine.coord_trans`)) no longer show triangular spikes; each + rectangle is now drawn as its own polygon instead of merging a bar's + segments into a single path. + - The space between facet panels now accounts for the margins of the axis text, so with free scales large margins no longer push the tick labels into the neighbouring panel. diff --git a/plotnine/geoms/geom_rect.py b/plotnine/geoms/geom_rect.py index eecae786c..9b52ecf8e 100644 --- a/plotnine/geoms/geom_rect.py +++ b/plotnine/geoms/geom_rect.py @@ -54,6 +54,11 @@ def draw_panel( """ if not coord.is_linear: data = _rectangles_to_polygons(data) + # Each rectangle is its own closed polygon. Grouping by the + # `group` aesthetic would merge a stacked bar's segments into one + # open path, and coord.munch would then bend the join between + # consecutive rectangles into a spurious spike. + data["group"] = np.repeat(np.arange(len(data) // 4), 4) for _, gdata in data.groupby("group"): gdata.reset_index(inplace=True, drop=True) geom_polygon.draw_group( diff --git a/tests/baseline_images/test_coords/coord_trans_stacked_bars_have_no_spikes.png b/tests/baseline_images/test_coords/coord_trans_stacked_bars_have_no_spikes.png new file mode 100644 index 000000000..d3894ff21 Binary files /dev/null and b/tests/baseline_images/test_coords/coord_trans_stacked_bars_have_no_spikes.png differ diff --git a/tests/test_coords.py b/tests/test_coords.py index 0525e9d88..4d2e1fde6 100644 --- a/tests/test_coords.py +++ b/tests/test_coords.py @@ -12,12 +12,14 @@ coord_flip, coord_trans, geom_bar, + geom_col, geom_line, geom_point, geom_polygon, ggplot, xlim, ) +from plotnine.data import mtcars n = 10 # Some even number greater than 2 @@ -90,6 +92,14 @@ def test_coord_trans_munches_polygon_closing_edge(): assert p == "coord_trans_munches_polygon_closing_edge" +def test_coord_trans_stacked_bars_have_no_spikes(): + # Each stacked segment must be its own polygon. If they merge into one + # path, the join between consecutive segments becomes a diagonal that + # munch subdivides into a triangular spike across the bar. + p = ggplot(mtcars, aes("factor(cyl)", "mpg")) + geom_col() + coord_trans() + assert p == "coord_trans_stacked_bars_have_no_spikes" + + def test_datetime_coord_limits(): n = 6