Skip to content

feat(geom_rect): add a hatch aesthetic - #1122

Open
floringogianu wants to merge 1 commit into
has2k1:mainfrom
floringogianu:feat/hatch
Open

floringogianu wants to merge 1 commit into
has2k1:mainfrom
floringogianu:feat/hatch

Conversation

@floringogianu

Copy link
Copy Markdown

Fixes #238

image
from plotnine import *
from plotnine.data import mpg

(
    ggplot(mpg, aes("class", fill="drv", hatch="drv"))
    + geom_bar(position="dodge", color="black")
    + scale_hatch_manual(values=["//", "xx", ".."])
    + labs(x="vehicle class", y="count", fill="drive", hatch="drive")
)

Adds a hatch aesthetic to geom_rect and everything built on it (geom_bar, geom_col, geom_histogram, geom_tile, geom_bin_2d), settable as a literal (geom_col(hatch="//")) or mapped through a discrete scale (geom_col(aes(hatch="grp"))).

A matplotlib Collection takes one hatch pattern for all of its paths, so each distinct pattern gets an overlay PolyCollection with no fill and no border, drawn over the parent. The strokes take the color aesthetic, matplotlib's convention for a hatch, and fall back to rcParams["patch.edgecolor"] when color is unset. The overlay's linewidth is zero so the parent keeps sole ownership of the border and its linetype.

geom_polygon.draw_group carries the hatch through as well, since geom_rect delegates to it under a non-linear coord.

Legend keys repeat the pattern by round(HATCH_KEY_SIZE / key_size), so a small key stays legible while a large one converges on the density the panel draws.

Scale family modelled on scale_linetype:

  • scale_hatch (discrete) / scale_hatch_discrete
  • scale_hatch_identity
  • scale_hatch_manual (custom per-level patterns)
  • scale_hatch_continuous raises PlotnineError, mirroring scale_linetype_continuous

labs(hatch=...) names the legend.

Adds a `hatch` aesthetic to geom_rect and everything built on it
(geom_bar, geom_col, geom_histogram, geom_tile, geom_bin_2d),
settable as a literal (geom_col(hatch="//")) or mapped through a
discrete scale (geom_col(aes(hatch="grp"))).

A matplotlib Collection takes one hatch pattern for all of its
paths, so each distinct pattern gets an overlay PolyCollection with
no fill and no border, drawn over the parent. The strokes take the
`color` aesthetic, matplotlib's convention for a hatch, and fall
back to rcParams["patch.edgecolor"] when color is unset. The
overlay's linewidth is zero so the parent keeps sole ownership of
the border and its linetype.

geom_polygon.draw_group carries the hatch through as well, since
geom_rect delegates to it under a non-linear coord.

Legend keys repeat the pattern by round(HATCH_KEY_SIZE / key_size),
so a small key stays legible while a large one converges on the
density the panel draws.

Scale family modeled on scale_linetype:
- scale_hatch (discrete) / scale_hatch_discrete
- scale_hatch_identity
- scale_hatch_manual (custom per-level patterns)
- scale_hatch_continuous raises PlotnineError, mirroring
  scale_linetype_continuous

`labs(hatch=...)` names the legend.
@codecov

codecov Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.50000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.22%. Comparing base (1f5ee9f) to head (4d20623).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
plotnine/geoms/geom_polygon.py 88.23% 2 Missing and 2 partials ⚠️
plotnine/scales/scale_hatch.py 93.10% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1122      +/-   ##
==========================================
+ Coverage   88.20%   88.22%   +0.02%     
==========================================
  Files         222      223       +1     
  Lines       16252    16331      +79     
  Branches     2080     2087       +7     
==========================================
+ Hits        14335    14408      +73     
- Misses       1315     1319       +4     
- Partials      602      604       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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

@has2k1

has2k1 commented Sep 11, 2026

Copy link
Copy Markdown
Owner

@floringogianu thank you for taking this on. When I get to reviewing the PR, it will be faster for me to make the changes rather do a back and forth review.

I will get this in for the upcoming 0.16.0 release.

@floringogianu

Copy link
Copy Markdown
Author

Sure, sounds good! I can probably take a look at the falling checks early next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fill with patterns

2 participants