Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Do not set clip path if it exists#23199
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Illustration importmatplotlibasmplfrommatplotlibimportpyplotaspltfig,ax=plt.subplots()poly=mpl.patches.Polygon([[1,0], [0,1], [-1,0], [0,-1]],facecolor="#ddffdd",edgecolor="#00ff00",linewidth=2,alpha=0.5)ax.add_patch(poly)line=mpl.lines.Line2D((-1,1), (0.5,0.5),clip_on=True,clip_path=poly)ax.add_artist(line)ax.set_xlim(-1,1)ax.set_ylim(-1,1) (no, there is no need to do |
@@ -686,7 +687,7 @@ def annotate(self, text, xy, xytext=None, xycoords='data', textcoords=None, | |||
textcoords=textcoords, arrowprops=arrowprops, | |||
annotation_clip=annotation_clip, **kwargs) | |||
a.set_transform(mtransforms.IdentityTransform()) | |||
if 'clip_on' in kwargs: | |||
ifkwargs.get('clip_on', False) and a.get_clip_path() is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I guess thatclip_on
not only should be inkwargs
, but also be set to True?
@@ -369,7 +369,7 @@ def draw_path(self, renderer, gc, tpath, affine, rgbFace): | |||
self.patch.set_transform(affine + self._offset_transform(renderer)) | |||
self.patch.set_clip_box(gc.get_clip_rectangle()) | |||
clip_path = gc.get_clip_path() | |||
if clip_path: | |||
if clip_path and self.patch.get_clip_path() is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This one is bit doubtful...
@oscargus is there a reason you have this in draft? I think it looks good! The only thing that could be added would be a quick test. Might be able to do a |
Also if you are interested in looking at the text portion, this PR seemed like a good start that could be reworked:#10811 |
I think it was probably the test issue. Which ideally should be testing all of the modifications and I may not really know how PathEffects work. Not sure that what you suggest will work, at least not with a rotated rectangle, as the "shorter" line must be quite exact to pass the test. Will rebase and see what happens for a start. |
24c3802
to1d2b56d
Compareoscargus commentedMar 4, 2023 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@@ -8455,6 +8455,43 @@ def test_zorder_and_explicit_rasterization(): | |||
fig.savefig(b, format='pdf') | |||
@image_comparison(["preset_clip_paths.png"], remove_text=True, style="mpl20") | |||
def test_preset_clip_paths(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'm not sure we want to add an image here that we know is wrong just to have to change it again later?
Some possible alternatives:
- Adding all of the lines/patches completely outside of the rectangle so they are completely clipped? This should make it simpler to compare against a plain rectangle in a check_figures_equal comparison.
- Removing the annotation for now and adding one outside the axes later once that gets fixed.
- Use a Cairo backend if the text clipping works properly there...
- Perhaps simplest though, can you check the expected clip_path after you set it with
artists.get_clip_path() is axes.patch
,artist.get_clip_path() is polygon
for the various cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Comparingget_clip_path
doesn't seem to work:
assert <matplotlib.transforms.TransformedPatchPath object at 0x000002BE4A717F70> is <matplotlib.patches.Polygon object at 0x000002BE4A5465E0>
Removing annotation and then adding it doesn't really seem better? Now, the test will fail once it is fixed so one will notice this and automatically have to update it (big risk that this test will not be updated.
Forpatheffects
, this happens at draw time, so that will not be tested (not 100% sure that it is now as I do not fully understand that part).
I'd take it that one actually would like to take the intersection of e.g. the axes patch and the provided clip path (although I am not sure if that will ever become a problem). So even if theget_clip_path
approach did work, it would break if this was fixed.
I think this is an example that shows that it is better to use the intersection:
import matplotlib as mplfrom matplotlib import pyplot as pltfig, ax = plt.subplots()poly3 = mpl.patches.Polygon([[-0.5, 0], [-0.5, 0.5], [0.5, 0.5], [0.5, 0]], facecolor="g", edgecolor="y", linewidth=2, alpha=0.3)fig.add_artist(poly3, clip=True)line = mpl.lines.Line2D((-1, 1), (0.25, 0.25), color='r', clip_on=True, clip_path=poly3)ax.add_artist(line)# or# fig.add_artist(line, clip=True)
while current master gives
or
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'm not sure I totally follow these recent images... The first one looks like the Polygon isn't actually containing the entire line which I would have expected from the clip, so is there still an error present?
The images frommain
seem to show that the default clip paths are the axes and figure respectively which I expected.
Comparing get_clip_path doesn't seem to work:
Ahh, yes, if you look at thedef set_clip_path
implementation, I think you can just callTransformedPathPatch(artist)
?
Sorry for sending you down this rabbit hole :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
The first one looks like the Polygon isn't actually containing the entire line which I would have expected from the clip, so is there still an error present?
This is a new error. Although probably this case is artificial, it is the consequence of not setting the previous default clip. So as long as we cannot do an intersection of the clip paths, we have to select which error we get.
Then the question is if these compare the same? Will have to look, but pretty sure that one will have to overload the__eq__
method here. Or extract the path. (I guessis
will not work as they will not be the same object.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Lets not hold this up on the test image. It is a useful change.
Uh oh!
There was an error while loading.Please reload this page.
PR Summary
This fixes parts of#8270 and in general it does not update the clip path of an artist added with
add_artist
if it already have a clip path set. Although that is not enough for#8270 (depending on backend).See:#8270 (comment)
Edit: more cases are added where a new clip path is not added if one is already set. I guess that in general one would like to have a union of the clip paths? Is that easily obtainable in some way?
Tests will be added.
PR Checklist
Tests and Styling
pytest
passes).flake8-docstrings
and runflake8 --docstring-convention=all
).Documentation
doc/users/next_whats_new/
(follow instructions in README.rst there).doc/api/next_api_changes/
(follow instructions in README.rst there).