plotnine icon indicating copy to clipboard operation
plotnine copied to clipboard

fix: correctly access axes ranges after coord flip in geom_path

Open AlFontal opened this issue 2 weeks ago • 3 comments

Description

This PR fixes a bug where arrowheads in geom_path (and derivatives like geom_segment) were distorted when using coord_flip().

The issue was caused by geom_path using coord.range(panel_params) to calculate the data range for aspect ratio corrections. coord_flip.range() returns the ranges of the original data variables (where x is the mapped variable, which becomes vertical). However, geom_path expects the ranges to correspond to the physical visual axes (horizontal and vertical width).

The fix is to use panel_params.x.range and panel_params.y.range directly, as plotnine ensures panel_params.x always corresponds to the horizontal visual axis.

Changes

  • Modified plotnine/geoms/geom_path.py: updated get_paths to access panel_params.x.range and panel_params.y.range directly.

Before:


import pandas as pd
import plotnine as p9
df = pd.DataFrame({
    "sample": ["A", "B", "C", "D", "E"],
    "value":  [0.1, 0.3, 0.6, 0.4, 0.8],
})

(p9.ggplot(df, p9.aes(x="sample", y="value"))
    + p9.geom_segment(
        p9.aes(xend="sample", y=0, yend="value"),
        arrow=p9.arrow(angle=30, length=0.2, ends="last", type="open"),
    )
    + p9.coord_flip()
)
image

Now:


(p9.ggplot(df, p9.aes(x="sample", y="value"))
    + p9.geom_segment(
        p9.aes(xend="sample", y=0, yend="value"),
        arrow=p9.arrow(angle=30, length=0.2, ends="last"),
    )
    + p9.coord_flip()
)
image

Related issue

Closes #1014.

AlFontal avatar Dec 05 '25 16:12 AlFontal

I ran the test suite locally and it seems to pass. Wondering whether it might make sense to create an actual test_coord_flip test that compares the png's generated by manually flipping and coord flipping, but I worry that the implementation doesn't 100% work pixel-perfect as of right now...

AlFontal avatar Dec 05 '25 16:12 AlFontal

Codecov Report

:white_check_mark: All modified and coverable lines are covered by tests. :white_check_mark: Project coverage is 86.71%. Comparing base (0da5f04) to head (34b171a). :warning: Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1015      +/-   ##
==========================================
- Coverage   86.73%   86.71%   -0.03%     
==========================================
  Files         198      198              
  Lines       13246    13248       +2     
  Branches     1653     1653              
==========================================
- Hits        11489    11488       -1     
- Misses       1208     1211       +3     
  Partials      549      549              

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

codecov[bot] avatar Dec 10 '25 22:12 codecov[bot]

You can add a test_arrow_coord_flip which just coord_flips the same plot used in test_arrow.

The pixel perfect thing is a raster graphics artefact which "disappears" at higher resolutions. To check if something is really off, save to pdf.

has2k1 avatar Dec 11 '25 12:12 has2k1

I've just added the test case as requested.

  • Added test_arrow_coord_flip to tests/test_geom_segment.py
  • Added baseline image tests/baseline_images/test_geom_segment/arrow_coord_flip.png.

Verified locally that the test passes, so I think it should be ready to go 👍

AlFontal avatar Dec 12 '25 16:12 AlFontal

Great, Thank you.

has2k1 avatar Dec 12 '25 16:12 has2k1