-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
I changed the offset code for draw_text for RendererAgg fixing issue #13044 #20057
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
Conversation
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.
Thank you for opening your first PR into Matplotlib!
If you have not heard from us in a while, please feel free to ping @matplotlib/developers
or anyone who has commented on the PR. Most of our reviewers are volunteers and sometimes things fall through the cracks.
You can also join us on gitter for real-time discussion.
For details on testing, writing docs, and our review process, please see the developer guide
We strive to be a welcoming and open project. Please follow our Code of Conduct.
I don't understand why these are leading to broken tests? I think its obviously OK to break the tests for non-zero rotation, but breaking them for zero rotation doesn't seem right. |
I think it is because when taking the components of the offset according to the non-rotation angle which is 0 degrees, we are setting y0 to be sin(0)*old y0 = 0. But I don’t think there should be a y offset due to y0, there is a y offset regardless due to yd. So that is why it might break tests with non-rotated text. |
I think you'll need to give us a little more detail. We can't break everyone who depends on our code without a really good reason. I think this would be easier with a diagram and some numbers. I appreciate that none of this is helped by the fact that |
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 am thinking that you are on the right track here. I haven't looked at how much the images would change, but I am inclined to say that it might be worth fixing if the results have been seriously wrong all this time. Maybe we can do some sort of special back-compat mode for unrotated text in order to limit the extent of the impact?
Can you comment on the difference between this fix and #19114?
@@ -208,10 +208,13 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): | |||
xo, yo = font.get_bitmap_offset() | |||
xo /= 64.0 | |||
yo /= 64.0 | |||
h = sqrt(xo**2 + yo**2) |
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.
Personally, I prefer using hypot()
instead, but I don't know if it really matters in the context of bounding box calculations.
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 don't know if it will matter, but we could still change it.
xd = d * sin(radians(angle)) | ||
yd = d * cos(radians(angle)) | ||
xo = h * cos(radians(angle)) | ||
yo = h * sin(radians(angle)) |
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.
If we are going to calculate radians(angle)
four times, might as well just do it once and store it in a variable.
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.
Also, these four lines here would greatly benefit from a comment explaining the trigonometry. Usually, cos() goes with x, and y goes with sin(). Seeing it two different ways here for the offset and the descent is confusing.
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 can explain the offset trigonometry, but I just left the code for the descent as it was before. The descent seems wrong - but I am unaware of the reason why it was like that before so I left it there. Basic trigonometry suggests that x components should be calculated by multiplying a number by the cosine of its angle and y components should be calculated by multiplying a number by the sine of its angle - so that is why I used that for the offset but I do think the descent should be in the same form too.
x = round(x + xo + xd) | ||
y = round(y + yo + yd) | ||
y = round(y + yo - yd) |
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.
much like the trig above, I think this will also need a quick proof in the comments.
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 don't think I have a proof for this at the moment except that in the draw_mathtext function the y is calculated in a similar manner and by subtracting the y offset we get a satisfactory result.
This fix and #19114 is different because #19114 tried to fix the bounding box and we are trying to change the offset for the text. But the problem is not with the bounding box but rather the text itself - here's an example to prove it:
Here's an example of text without the bounding box:
And you can see there is a problem with the offset of the text even when a bounding box isn't drawn. |
So I never could find the draw_text_image function in the source code actually. I was trying to look for it to check whether it solves rotation correctly or not. |
Yes, |
Closing and reopening to get fresh test results. |
👋🏻 Hello, @safdarzareef ! Are you interested in picking this back up? Can we help you with this? Please let us know 😄 |
Since this Pull Request has not been updated in 60 days, it has been marked "inactive." This does not mean that it will be closed, though it may be moved to a "Draft" state. This helps maintainers prioritize their reviewing efforts. You can pick the PR back up anytime - please ping us if you need a review or guidance to move the PR forward! If you do not plan on continuing the work, please let us know so that we can either find someone to take the PR over, or close it. |
PR Summary
I tried to fix issue #13044. This a script where the issue can be reproduced (from @dzh527's example in the PR)
This is the original output:

This is the output after our change:

So the difference is caused by the offset in the code, with xo and yo not accounting for the change in the rotation angle, so every time we rotate the x and y components of the offset are not adjusted accordingly with the angle. That is what we tried to implement.
I think this broke a lot of tests as we changed the location of any text added to a plot - because even if the angle is 0, the offset components would be different. We haven't modified anything except for the draw_text function in the backend_agg.py. I think the new behavior does change the plots for all types of text added to a plot, but even though it is offset differently, it is equivalent in theory. Also instead of adding yo to y, we subtracted it because that gave the best result and draw_mathtext was implemented like that.
PR Checklist
pytest
passes).flake8
on changed files to check).flake8-docstrings
and runflake8 --docstring-convention=all
).doc/users/next_whats_new/
(follow instructions in READM 8000 E.rst there).doc/api/next_api_changes/
(follow instructions in README.rst there).