Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Implement head resizing (and reversal) for larrow/rarrow/darrow#29998

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

Open
CharlieThornton33 wants to merge16 commits intomatplotlib:main
base:main
Choose a base branch
Loading
fromCharlieThornton33:road-sign-annotation

Conversation

CharlieThornton33
Copy link

@CharlieThornton33CharlieThornton33 commentedMay 1, 2025
edited
Loading

PR summary

When creating an annotation using boxed text in an arrow shape (patches.BoxStyle.LArrow/RArrow/DArrow),head_width andhead_angle arguments may now be passed to adjust the size of the arrow head(s), and (via the use of negative angles) generate 'reversed' arrow heads. Addresses#24618 and is a direct continuation of@Abitamim's work in#24744.

This solves both the issue initially mentioned in#24618 (creating a pentagonal 'road-sign' annotation box), as well as allowing for many other customisation options for arrows; for example, a reversed-headDArrow could act as a way to bring attention to a certain region on an axis.

import matplotlib.pyplot as pltfig, ax = plt.subplots(figsize=(4, 3))t1 = ax.text(0.5, 0.75, "Road-sign",            ha="center", va="center", size=15,            bbox=dict(boxstyle="rarrow,pad=0.3,head_width=1,head_angle=45",                      fc="lightblue", ec="steelblue", lw=2))t2 = ax.text(0.5, 0.25, "  Reversed heads   ",            ha="center", va="center", size=15,            bbox=dict(boxstyle="darrow,pad=0.3,head_width=1.5,head_angle=-45",                      fc="lightblue", ec="steelblue", lw=2))plt.show()

pr_example

A new test,test_boxarrow_adjustment, has been added to test these options.

PR checklist

Copy link

@github-actionsgithub-actionsbot left a comment

Choose a reason for hiding this comment

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

Thank you for opening your first PR into Matplotlib!

If you have not heard from us in a week or so, please leave a new comment below and that should bring it to our attention. Most of our reviewers are volunteers and sometimes things fall through the cracks.

You can also join uson gitter for real-time discussion.

For details on testing, writing docs, and our review process, please seethe developer guide

We strive to be a welcoming and open project. Please follow ourCode of Conduct.

@CharlieThornton33
Copy link
Author

Hi everyone,

I was just wondering whether someone would be willing to have a look at this PR? I feel like it's in a complete or nearly-complete state but need some guidance - the two failing CI jobs seem to be:

  • PR cleanliness:
    The added unit test was written first by@Abitamim, and then expanded by myself. When I expanded the test to check the newly-added reversed arrow heads, I changed both the test name (temp_test_boxarrowtest_boxarrow_adjustment) and the name of the output image (roadsign_test_image.pngboxarrow_adjustment_test_image.png) to reflect this. The 'file both added and deleted' error given seems to be a result of adding then deletingroadsign_test_image.png.
  • Python 3.11 on macos-13:
    The failing test here (test_blitting_events) is marked as flaky, with the comment# subprocesses can struggle to get the display, so rerun a few times. I feel it may be that this was just a random instance of the test failing multiple times in a row; unfortunately I don't have access tomacos-supported hardware for rerunning this locally, so I was wondering if someone would be able to take a look.

Any help would be greatly appreciated. Thanks!

@timhoffm
Copy link
Member

PR-cleanliness: This is a check so that we don't merge commits with unneeded images, which would increase repo size. You can either squash and force-push. Or ignore this and we'll squash-merge at the end.

Ignore the macos test failure. It's unrelated.

@CharlieThornton33
Copy link
Author

Thank you for getting back so quickly! Would it be okay if you handled the squashing - I'm relatively new to git, and I'm not sure of the best method to use for squashing to keep a relatively clean but traceable commit history?

Copy link
Member

@timhoffmtimhoffm left a comment

Choose a reason for hiding this comment

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

Looking at the arrows in the test image,https://github.com/matplotlib/matplotlib/pull/29998/files#diff-ff8adb592a399d60ee5c93fbff7552182f53b74be4573ca21db404ef3c3a6673, the outline sometimes cuts through the text, which must not happen.

From plotting

plt.text(0.5, 0.5, 'text', size=24, bbox=dict(boxstyle="rarrow", fc="w", ec="k"),)plt.text(0.5, 0.5, 'text', size=24, bbox=dict(boxstyle="square", pad=0, fc="C0", ec='none'))

we can see that the original calculation had a shaft with the length of the text, i.e. the arrow head starts at -pad from the end of the text.

image

This setting was ok for the hard-coded parameters, but when head_size and head_angle can vary, we have to invest more into a good positioning of arrow head.

Comment on lines +65 to +69
angle = -80
angle_step = 120 / repetitions
for i in range(repetitions):
for j, stylename in enumerate(sorted(styles)):
if stylename in ("larrow", "rarrow", "darrow"):
Copy link
Member

Choose a reason for hiding this comment

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

Please explain what you are trying to achieve with this rather wild parameter juggling. I cannot follow the logic and the associated reference image looks complicated. I would have expected that you have a set of characteristic cases such as

{'head_width'=1.5, 'head_angle'=90},{'head_width'=1, 'head_angle'=60},{'head_witdh'=0.5, 'head_angle'=30},{'head_witdh'=1.5, 'head_angle'=-90},

for each of 'larrow', 'darrow', 'rarrow'. You could coveniently arrange them on a regular grid.

I don't think you need to test the rotation. By design that's covered by the transform system and is thus orthogonal to the shaping of the arrow. But if you want, you could add an extra entry with rotation in the above matrix.

Choose a reason for hiding this comment

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

I wasn't aware that the transform system itself was tested elsewhere; I'll remove the rotations, as well as lay the arrows out more regularly. I was rushing quite a bit when writing the test, and I felt the positioning needed to somewhat resemble that intest_boxarrow - the insane double loop is a result of me trying to test multiple cases for each type of arrow while still using the positioning code from that test.

Before I get on to rewriting the test, though, I'll work on the arrow head positioning/padding issue.

@CharlieThornton33
Copy link
Author

Since I'm going to need to make some relatively major changes to the contents of this PR (a redo of the arrow drawing code and a rewrite of its unit test), would it be better for me to amend my last commit (d9b0b32) as suggested in thecontributing guide, or make a few new commits? I'm not quite sure how to add more commits to an open PR - do I just push the changes to my development branch?

@rcomer
Copy link
Member

@CharlieThornton33 yes you can just push more commits to your current branch and they will appear in this PR. Since you already have several commits they will ultimately need squashing one way or the other (and I see you already asked that we handle that), so I do not think you gain anything from the—amend option.

@CharlieThornton33
Copy link
Author

I've just redone the padding (only forLArrow andRArrow for the moment), and I think the issue with the text escaping the outline has been fixed. I set the arrow body to dynamically increase in length to make sure there's always a gap of at leastpad between the edge of the text closest to the arrow head and the position where that edge would first intercept the outline if moved towards the tip:

import numpy as npimport matplotlib.pyplot as pltfig, ax = plt.subplots(figsize=(3, 8))t0 = ax.text(0.5, 0.9, "Text",            ha="center", va="center", rotation=0, size=30,            bbox=dict(boxstyle="rarrow,pad=0.3,head_width=1.5,head_angle=-90",                      fc="lightblue", ec="steelblue", lw=2))t1 = ax.text(0.5, 0.7, "Text",            ha="center", va="center", rotation=0, size=30,            bbox=dict(boxstyle="rarrow,pad=0.3,head_width=1.5,head_angle=70",                      fc="lightblue", ec="steelblue", lw=2))t2 = ax.text(0.5, 0.5, "Text",            ha="center", va="center", rotation=0, size=30,            bbox=dict(boxstyle="rarrow,pad=0.3,head_width=1.5,head_angle=100",                      fc="lightblue", ec="steelblue", lw=2))t3 = ax.text(0.5, 0.3, "Text",            ha="center", va="center", rotation=0, size=30,            bbox=dict(boxstyle="rarrow,pad=0.3,head_width=1.5,head_angle=130",                      fc="lightblue", ec="steelblue", lw=2))t4 = ax.text(0.5, 0.1, "Text",            ha="center", va="center", rotation=0, size=30,            bbox=dict(boxstyle="rarrow,pad=0.3,head_width=1.5,head_angle=170",                      fc="lightblue", ec="steelblue", lw=2))plt.show()

new_padding

It's also a bit concerning that the CI workflow seems to run on every commit to this PR - am I okay to disable tests in my commit messages until the one where I write the new test to save on CI resources?

@CharlieThornton33
Copy link
Author

I've just noticed - all of thepytest test runs are about to fail because I forgot to remove the flawedtest_boxarrow_adjustment test. Is there any way to cancel a CI test run?

@rcomer
Copy link
Member

@CharlieThornton33 I wouldn't worry about the CI failing, but if they are still running when you push another commit they will be interrupted and re-started.

@CharlieThornton33
Copy link
Author

Hi,

I'm a bit stuck with how to handle cases where an arrow head extends behind the opposite end of the body; something like

arrow_overflow

I'm not sure whether the arrow head should 'stick out' through the other end of the body, or should cut off at that point.

I'd really appreciate any advice - I don't know if there's any sort of precedent in Matplotlib for this kind of thing.

@timhoffm
Copy link
Member

I don't think there's precedent. While such cases should be rare, my gut feeling is that the tip should not stick out.

@melissawmmelissawm moved this fromNeeds review toWaiting for author inFirst Time ContributorsMay 26, 2025
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@timhoffmtimhoffmtimhoffm left review comments

@github-actionsgithub-actions[bot]github-actions[bot] left review comments

At least 1 approving review is required to merge this pull request.

Assignees
No one assigned
Projects
Status: Waiting for author
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

[ENH]: "Road sign" boxstyle/annotation
5 participants
@CharlieThornton33@timhoffm@rcomer@melissawm@Abitamim

[8]ページ先頭

©2009-2025 Movatter.jp