-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
str_angles and scale_units logic for quiver #8670
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
@@ -626,19 +626,19 @@ def _angles_lengths(self, U, V, eps=1): | |||
|
|||
def _make_verts(self, U, V, angles): | |||
uv = (U + V * 1j) | |||
str_angles = isinstance(angles, six.string_types) | |||
if str_angles and (angles == 'xy' and self.scale_units == 'xy'): | |||
str_angles = angles if isinstance(angles, six.string_types) else '' |
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 seeing why this change is necessary.
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.
Build mpl on latest commit 1144e8c on branch master
_, ax = plt.subplots(subplot_kw=dict(aspect='equal'))
ax.quiver(0, 0, 1, 1, angles='xy', scale_units='xy', scale=1)
ax.set_xlim(0, 1.1); ax.set_ylim(0, 1.1); ax.grid()
this block l. 668 is now wrong:
if str_angles and (angles == 'xy'):
theta = angles
elif str_angles and (angles == 'uv'):
theta = np.angle(uv)
since variable angles is overridden by angles, lengths = self._angles_lengths(U, V, eps=1)
the cited commit d705dbd screws up the whole quiver logic
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.
Ah, okay. In that case, if str_angles and str_angles == 'some string':
is redundant now; it can just be if str_angles == 'some string':
.
Please add a test as well; something similar to your example will probably work.
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 not, str_angles is here to avoid the FutureWarning: elementwise comparison failed
cited above and was introduced in #6971
I tried to stick with the existant ...
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.
But this line has changed it so that str_angles
is always a string.
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.
yes, but the empty string evaluates to False (as in print('foo' if '' else 'bar')
), thus short-circuiting the angles == 'xy' test, which can eventually throw a warning.
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.
But you've replaced all the angles ==
with str_angles ==
.
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.
ha yes I see it now, stupid me it's getting late here ...
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 looks good, thanks for fixing what I broke in my original commit! It looks like this has changed one of the test images: https://travis-ci.org/matplotlib/matplotlib/jobs/236581341#L1788 - could you generate a new image and see what the difference is?
# Calculate eps based on the extents of the plot | ||
# so that we don't end up with roundoff error from | ||
# adding a small number to a large. | ||
eps = np.abs(self.ax.dataLim.extents).max() * 0.001 | ||
angles, lengths = self._angles_lengths(U, V, eps=eps) | ||
if self.scale_units == 'xy': | ||
if str_angles and self.scale_units == 'xy': |
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.
Why does this extra bit need to go in - if str_angles is a string does this even make sense?
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 should avoid throwing issue 2 is str_angles == '', doesn't it ?
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.
Maybe it should be if str_angles == 'xy'
as well, to match the others? I'm not sure what the behaviour should be if you pass angles = 'some garbage'
instead though.
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 the real question is whether this should apply to str_angles == 'uv'
as well?
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.
well, all the scalings except 'xy' are based on U and V, so I guess I it sufficient to leave it like that. throwing an exception on str_angles not in ('xy', 'uv')
seems to be an overkill since a
and theta
will fallback to using U
and V
values ...
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.
Appears that angles='uv'
is the default, so the existing tests not being changed shows that it's probably fine.
lib/matplotlib/tests/test_quiver.py
Outdated
# simple arrow pointing from SW to NE | ||
fig, ax = plt.subplots(subplot_kw=dict(aspect='equal')) | ||
ax.quiver(0, 0, 1, 1, angles='xy', scale_units='xy', scale=1) | ||
ax.set_xlim(0, 1.1); ax.set_ylim(0, 1.1); ax.grid() |
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.
Could these all go on a separate line without semicolons
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.
done. the issue with the test_image is mostly due to different version of freetype on my dev version, I will try to generate it using mpl from the repos or anaconda ... thanks
Once you've answered the last question, can you rebase and remove the multiple copies of the test image? |
added 2 simple tests
# Calculate eps based on the extents of the plot | ||
# so that we don't end up with roundoff error from | ||
# adding a small number to a large. | ||
eps = np.abs(self.ax.dataLim.extents).max() * 0.001 | ||
angles, lengths = self._angles_lengths(U, V, eps=eps) | ||
if self.scale_units == 'xy': | ||
if str_angles and self.scale_units == 'xy': |
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.
Appears that angles='uv'
is the default, so the existing tests not being changed shows that it's probably fine.
🎉 Congratulations on your first merged PR into Matplotlib @neok-m4700 ! Hopefully we will hear from you again! |
Thanks @tacaswell , I guess there is a start to everything :) |
issue 1
d705dbd is introducing issues when using
angles='xy'
, especially at l.660:, comparing angles (now an array) to a string is throwing a warning
issue 2
using
scale_units='xy'
together with an angles array throws anwhere it shouldn't
reproduce the problem
this patch fixes both issues