Skip to content

Stripey LineCollection #24849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 11, 2023
Merged

Conversation

rcomer
Copy link
Member

@rcomer rcomer commented Dec 31, 2022

PR Summary

Closes #24796.

Following #23208, which implemented the gapcolor property for Line2D, this PR implements gapcolor for LineCollection. So we can set a colour (or list of colours) to fill the gaps in dashed lines and make a striped effect. For example

import matplotlib.pyplot as plt

_, ax = plt.subplots()
ax.vlines(range(1, 5), 0, 1, linestyle=':', linewidth=5,
          color='k', gapcolor=['r', 'b'])

plt.show()

stripey_vlines

I marked this functionality as "experimental" to be consistent with Line2D.

My current implementation works, but I'm pretty unsure about the way I've structured it: it doesn't seem great to have the LineCollection-specific handling within Collection. The only way I can see to avoid that is to define LineCollection.draw, but that would mean duplicating some code, which also wouldn't seem great.

For reference, the test images look like this:

gapcolor='orange'
test_striped_lines png-orange

gapcolor=['r', 'k']
test_striped_lines png-gapcolor1

I'm happy to squash the commits down once we're happy with the implementation, but I suspect there will be plenty of changes before that...

PR Checklist

Documentation and Tests

  • Has pytest style unit tests (and pytest passes)
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • New plotting related features are documented with examples.

Release Notes

  • New features are marked with a .. versionadded:: directive in the docstring and documented in doc/users/next_whats_new/
  • [N/A] API changes are marked with a .. versionchanged:: directive in the docstring and documented in doc/api/next_api_changes/
  • Release notes conform with instructions in next_whats_new/README.rst or next_api_changes/README.rst

@@ -406,6 +410,17 @@ def draw(self, renderer):
gc, paths[0], combined_transform.frozen(),
mpath.Path(offsets), offset_trf, tuple(facecolors[0]))
else:
if self._gapcolor is not None:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that do_single_path_optimization is only True if all the lines are solid

all(ls[1] is None for ls in self._linestyles) and

so gapcolor is only meaningful after this else.

@jklymak
Copy link
Member

jklymak commented Feb 2, 2023

@rcomer for a new feature like this, its nice to either include example code in the description, or in documentation of the feature. I'm not quite following the API from the test images and the tests (though I only tried for a minute or so).

@rcomer rcomer added the status: needs clarification Issues that need more information to resolve. label Feb 2, 2023
@rcomer
Copy link
Member Author

rcomer commented Feb 3, 2023

Thanks @jklymak, I have updated the OP.

@rcomer rcomer removed the status: needs clarification Issues that need more information to resolve. label Feb 3, 2023
@jklymak
Copy link
Member

jklymak commented Feb 8, 2023

@timhoffm @oscargus you reviewed the original feature for Line2d. Does this seem reasonable here?

Copy link
Member

@jklymak jklymak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fine to me, despite never using v/hlines ;-)

Copy link
Member

@story645 story645 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wording nits but I'm happy w/this. Thanks! (Also sorry for dragging this into the color validation arguments)

There can be overlaps between those two, which may result in
artifacts when using transparency.

This functionality is experimental and may change.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smallest little nit but I'd put only this very last sentence in the note and have everything else as just part of the docstring.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@story645 story645 Feb 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be changed there too but out of scope so I can put in that PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I remember of #23208, this went through a few iterations: started out with a warning about overlaps that don't look great with transparency. Then the warning was downgraded to a note, and the "experimental" bit added later. Given the amount of previous bikeshedding on this, I would be uncomfortable about changing it without a bit more discussion. That could happen in a follow-up PR, as you say.

Comment on lines 1533 to 1535
Used when gapcolor is set. Return the path and inverse pattern for
non solid lines, so we can use these to fill the gaps. For solid lines
we insert a path of nans so that no inverse line is drawn in that case.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Used when gapcolor is set. Return the path and inverse pattern for
non solid lines, so we can use these to fill the gaps. For solid lines
we insert a path of nans so that no inverse line is drawn in that case.
Returns the path and pattern for the gaps in the non-solid lines.
This path and pattern is the inverse of the path and pattern used to construct the non-solid lines. For solid lines, we set the inverse path to nans to prevent drawing an inverse line.

Wordsmithing, take or leave

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken!

non solid lines, so we can use these to fill the gaps. For solid lines
we insert a path of nans so that no inverse line is drawn in that case.
"""
pairs = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pairs is path_pattern?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean I should change the variable name? Happy to do so if so.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was confirming that I understood what the code was doing but if I'm right than yes please

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@rcomer rcomer force-pushed the stripey-line-collection branch from 4f872b9 to 3b4bd83 Compare February 9, 2023 19:22
@rcomer
Copy link
Member Author

rcomer commented Feb 10, 2023

Does anyone have an opinion on this Codecov failure? It seems unlikely to me that such a simple method could get broken.

@jklymak jklymak merged commit 81f5f24 into matplotlib:main Feb 11, 2023
@jklymak
Copy link
Member

jklymak commented Feb 11, 2023

Thanks @rcomer !

@rcomer
Copy link
Member Author

rcomer commented Feb 12, 2023

Thanks @jklymak, @story645 - this one was considerably more straightforward than I feared!

@rcomer rcomer deleted the stripey-line-collection branch February 12, 2023 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: gapcolor not supported for LineCollections
4 participants