Skip to content

Prevent arrow lengths from being too long #2576

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
Jun 16, 2025

Conversation

jewettaijfc
Copy link
Contributor

@jewettaijfc jewettaijfc commented Jun 15, 2025

This PR is an attempt to address issue #2575.

After this PR, arrows will always fit within plot window, regardless of their direction and regardless of the aspect ratio of the plot (ax.set_aspect()).

Screenshots

Before this PR

Before this PR, the vertical arrows could easily grow too long to fit within the plot window:
Image

After this PR

After this PR, the green arrow is visible, regardless of it's orientation and regardless of the aspect ratio:
fix_arrow_autoscale_after

Test files
The plot above was made using this file:
test_arrow_autoscale.ipynb.zip

Download it, unzip it, and run the cells.

(NOTE: I disabled the plot on the right because it depends on #2544. That PR might not be merged by the time you are reading this. But it's not necessary to show this plot to see the problem. It just makes it more obvious.)

Notes:

  • Previously, autoscaling worked in the horizontal direction, but not the vertical direction.
  • Now it works in both horizontal and vertical directions.
  • This PR fixes the problem of long arrows. In this example, the other arrow (the grey arrow) is now too short to see clearly. But I'm less concerned about short arrows because all arrows are still visible, regardless of how short they are. (To see they grey arrow in this example, you just need to make the 2nd graph wider. You can do that by adding hlim=[-20,20] to the 2nd plot() argument list. The short grey arrow will resemble a small sideways triangle.) If you want to preserve the length of short arrows as well, a different approach is needed. (I did not try this because it is more complicated. See below.)
  • More notes are listed in the comments below.

Additional context

This problem is making it hard to implement PR2544.

Greptile Summary

Fixed visualization issue in tidy3d/components/geometry/base.py where arrows could extend beyond plot boundaries by modifying _arrow_shape_cb to consider both horizontal and vertical scales when computing arrow lengths.

  • Updated arrow length calculation in Box class to use both axes scales instead of just horizontal
  • Ensures arrows remain visible within plot window regardless of direction/aspect ratio
  • Trade-off: While long arrows are now properly constrained, some short arrows may appear smaller
  • Visual improvement verified through test notebook with different aspect ratios
  • Critical fix needed to unblock implementation of PR#2544

Copy link
Contributor

github-actions bot commented Jun 15, 2025

Diff Coverage

Diff: origin/develop...HEAD, staged and unstaged changes

  • tidy3d/components/geometry/base.py (0.0%): Missing lines 2295-2297

Summary

  • Total: 3 lines
  • Missing: 3 lines
  • Coverage: 0%

tidy3d/components/geometry/base.py

Lines 2291-2301

  2291             # We only want to set the shape once, so we disconnect ourselves
  2292             event.canvas.mpl_disconnect(arrow.set_shape_cb[0])
  2293 
  2294             transform = arrow.axes.transData.transform
! 2295             scale_x = transform((1, 0))[0] - transform((0, 0))[0]
! 2296             scale_y = transform((0, 1))[1] - transform((0, 0))[1]
! 2297             scale = max(scale_x, scale_y)  # <-- Hack: This is a somewhat arbitrary choice.
  2298             arrow_length = ARROW_LENGTH * event.canvas.figure.get_dpi() / scale
  2299 
  2300             if bend_radius:
  2301                 v_norm = (direction[0] ** 2 + direction[1] ** 2) ** 0.5

@jewettaijfc
Copy link
Contributor Author

jewettaijfc commented Jun 15, 2025

tidy3d/components/geometry/base.py

  2295             transform = arrow.axes.transData.transform
! 2296             scale_x = transform((1, 0))[0] - transform((0, 0))[0]
! 2297             scale_y = transform((0, 1))[1] - transform((0, 0))[1]
! 2298             scale = math.sqrt(scale_x**2 + scale_y**2)
  2299             arrow_length = ARROW_LENGTH * event.canvas.figure.get_dpi() / scale
  • I confess that the choice of equation used for scale (eg scale = math.sqrt(scale_x**2 + scale_y**2)) was not well motivated. I tried several equations. This hacky equation seems to work reasonably well at all orientations and all aspect ratios. (The arrow never grows by more than a factor of $\sqrt(2)$. If you want to make sure the arrow length never grows at all, then a simpler choice is to use scale=max(scale_x, scale_y) instead.) <--UPDATE: Later decided to use this equation instead.
  • Feel free to pick a different equation if you find something that works better. I am happy as long as the arrows always fit within the plot window (and point in the correct direction).

@jewettaijfc
Copy link
Contributor Author

jewettaijfc commented Jun 15, 2025

I updated the equation for scale:

scale = max(scale_x, scale_y)

This is probably not the optimal choice either. But at least it guarantees that arrows remain within the plot window.

  • Again, feel free to suggest a different equation or a different approach.
  • (Sorry if I was sloppy with this PR. I am in a hurry to get back to work on a different problem.)

@jewettaijfc
Copy link
Contributor Author

jewettaijfc commented Jun 16, 2025

IMPORTANT: This PR does not preserve arrow lengths on screen when the aspect ratio is changed.

Do we want that?

If you want that, you must use a different approach.

...That approach is explained here. I tested that google-gemini code and actually works. I did not implement it, because I could not figure out how to make it work with the custom bend_radius code we are using. But if I can get someone to explain what the bend_radius code does, I am happy to solve this problem the better way (so that arrow lengths on screen are not affected by the aspect ratio). This would prevent arrows from getting shorter as the aspect ratio changes. It would guarantee that all arrows remain easy to see.

Currently, this PR is a quick hack which makes the minimal code changes to make sure that the arrows are not too large to fit in the plot window.

@jewettaijfc jewettaijfc changed the title arrow lengths are scaled consistently Arrow lengths are never too long Jun 16, 2025
@jewettaijfc jewettaijfc changed the title Arrow lengths are never too long Prevent arrow lengths from being too long Jun 16, 2025
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

LGTM

1 file reviewed, no comments
Edit PR Review Bot Settings | Greptile

@tylerflex
Copy link
Collaborator

Thanks @jewettaijfc, this looks good to me overall, but I'll feel safer if we check to make sure the notebooks that use this in plotting still look ok (if you haven't already).

@tylerflex
Copy link
Collaborator

To be clear: no need to check every notebook but maybe just look at around 5 and re-run (even without transpose) just to make sure nothing looks weird. Thanks!

@tylerflex
Copy link
Collaborator

Please squash commits into one (using git rebase -i)

and also please add a line under "fixed" in the CHANGELOG.md

@jewettaijfc
Copy link
Contributor Author

jewettaijfc commented Jun 16, 2025

Thanks @jewettaijfc, this looks good to me overall, but I'll feel safer if we check to make sure the notebooks that use this in plotting still look ok (if you haven't already).

I've checked 25 notebooks that use it this code today. I tested them while I was testing PR2544. Not all of these notebooks have examples that display arrows. But the examples that do have arrows look okay (in my opinion).


Here's the only weird side effect of this PR that I've found so far in my tests:

Sometimes arrows that were originally finite length become very short (as a result of this PR) when the aspect ratio gets very large. This doesn't happen very often, but it does occasionally happen. The alternative solution I mentioned earlier tries to solve that that issue by preserving the (visual) length of each arrow. But I don't know if it's worth the effort. I personally don't mind seeing short arrows (especially when the aspect ratio is 100).

@jewettaijfc jewettaijfc force-pushed the jewettaijfc/pr2574_fix_arrows branch 2 times, most recently from 03a973f to c13a5a7 Compare June 16, 2025 20:14
@jewettaijfc
Copy link
Contributor Author

  • I think I squashed it.
  • I added my changes to the CHANGELOG under ### Fixed inside ## [2.9.0rc1] - 2025-06-10, and I updated the date to today's date 2025-06-16.) (Please let me know if I was not supposed to alter the date.)

Copy link
Collaborator

@tylerflex tylerflex left a comment

Choose a reason for hiding this comment

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

oops forgot to hit submit!

…ect ratio (`ax.set_aspect()`). This fixes issue #2575.
@jewettaijfc jewettaijfc force-pushed the jewettaijfc/pr2574_fix_arrows branch from c13a5a7 to 1f110b9 Compare June 16, 2025 21:24
@tylerflex tylerflex self-requested a review June 16, 2025 21:58
@jewettaijfc jewettaijfc merged commit f258832 into develop Jun 16, 2025
43 checks passed
@jewettaijfc jewettaijfc deleted the jewettaijfc/pr2574_fix_arrows branch June 16, 2025 23:44
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.

3 participants