-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
Implementation of 3D quiver #2961
Conversation
|
||
ax.quiver(x, y, z, u, v, w, length=0.1) | ||
|
||
plt.show() |
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 think our (possibly over-zealous) pep8 tests will complain about the lack of a new line.
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.
new lines are in place :)
Cool! I like this idea of assiging adding features to OSS porjects as homework 😄 I left some nit-picky/style comments. @WeatherGod Thoughts? |
This is absolutely fantastic! I will spend some time tonight reviewing the code. On Tue, Apr 8, 2014 at 4:50 PM, Thomas A Caswell
|
if len(args) != 6: | ||
ValueError('Wrong number of arguments') | ||
# X, Y, Z, U, V, W | ||
coords = list(map(lambda k: np.array(k) if not isinstance(k, np.ndarray) else k, args)) |
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.
use np.broadcast_arrays(). You get the additional benefit of making sure everything is broadcastable, so you can eliminate the shape check later
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.
At first I didn't use broadcast_arrays() because it strip off the mask of masked arrays. But I think it should be preferred to be consistent with rest of APIs. Used a alternative way to handle the masked array so that broadcast can be used too.
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.
Here is a quick-n-dirty masked array version of broadcast_arrays(). It is very efficient and very clean and easy to understand.
def ma_broadcast_arrays(*arrays):
arrays = [np.ma.masked_array(x) for x in arrays)]
broadcasted = np.broadcast_arrays(*arrays)
broadcasted_masks = np.broadcast_arrays(*[x.mask for x in arrays])
return [np.ma.masked_array(x, mask=mask) for x, mask in zip(broadcasted, broadcasted_masks)]
The beauty of the above function is that the inputs can be heterogenous (scalars, regular numpy arrays, masked arrays), and everything comes out at the end as broadcasted views of masked arrays so there is little if any copies.
Then, you can use cbook.delete_masked_points() to get rid of anything masked, so you don't have to worry about making the mask the same across all arrays.
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.
Wow...found lot of useful functions in cbook :) great thanks for the pointer.
As for this case, I think the masks must be broadcasted together with data, if broadcasted separately, the outcome mask and data will not match each other in some scenario, consider:
arrays = [
np.ma.array([1, 2, 3], mask=[1, 0, 0]),
np.array([[4, 5, 6], [7, 8, 9]])
]
Line 2522-2526 is to address this scenario.
When picking the elements, the approach I used here happened to be very similar to delete_masked_points()
, the main difference is delete_masked_points()
is doing and
to reduce the mask, here I am doing or
to reduce the mask. I think it make sense to do so, if I use and
here, the input parameter will need to make sure all u,v,w,x,y,z
masked in the same spot after broadcasting in order for a position to be masked; using or
, the user can simply mask any of the u,v,w,x,y,z
and knowing the position is masked no matter if the mask matches or not after broadcasting in rest of parameters. If one got multiple masks and feel confused, one can simply strip all the masks and only mask on one parameter.
Different than delete_masked_points()
, here since I know that the arrays and mask are in same shape, I can simply apply the mask and use compressed()
to get rid of the masked elements without additional checking like delete_masked_points()
needed. Also I get the added benefit of being able to handle masked array of more than 1-D.
Thanks for the insightful comments! |
👍 - this is an excellent piece of work with a test to boot - great stuff! Once @WeatherGod has had a good read, I'm in favour of this change. @xbtsw and collaborators: Please feel free to add your names and the feature to `doc/users/whats_new.rst`` and get your name in lights. I wouldn't find it inappropriate to also list your institution in the what's new if your instructor so wishes. Thanks for the contribution, and I hope you've enjoyed it sufficiently to consider getting your teeth stuck into other matplotlib features/bugs. |
Sorry I haven't responded on this. I have not forgotten about this. I want to look into the cbook.delete_masked_points() function, as I don't think it should be behaving as you describe. I would like to get delete_masked_points() to be used here like it is used elsewhere and would greatly simplify the code here. |
Hi @WeatherGod thanks for your reply :) Also while doing this, I found a bug in the code, so I pushed a new commit to fix it, also added to
|
|
||
ax.quiver(x, y, z, u, v, w, length=0.1) | ||
|
||
plt.show() |
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.
Make sure you have a newline at the end of the file
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.
Pinging on adding a newline at the end of the file.
|
||
points = input_args[:3] | ||
vectors = input_args[3:] | ||
|
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.
At about this point, I would do a check for empty arrays and do an early return if that is the case. I can easily imagine a case of inputs being all masked out.
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z) | ||
w = np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) * np.sin(np.pi * z) | ||
|
||
ax.quiver(x, y, z, u, v, w, length=0.1) |
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.
Need two blank lines after this
Once the remaining comments are addressed, I am ok with merging this to get it into 1.4.0. I might make it a future PR to add a cbook.broadcast_any_arrays() and to improve cbook.delete_masked_points() such that it could be used here and elsewhere. |
Hi WeatherGod, We will gladly make these changes. Our team is just finishing up final exams this week and hope to commit these changes early next week. |
Ping? I hope the finals went well for you all. |
Includes better way to handle rotation. However some updates are required to be put again. xbtsw will fix soon.
@TheInvoker What is the state of this? @WeatherGod Can you be responsible for getting this ready to merge (looks like it needs a re-base at a minimum)? |
I guess I could. I guess I would just have to fork their branch and send a new PR with the additional changes? |
@WeatherGod I mostly meant taking care of prodding the OP to make sure it happens, but your approach would also work. |
Closing in favor of #3149 |
Hi,
We are a small team of students from University of Toronto. Our instructor asked as to implement a MPL feature as one of our project :) so we choose the 3D quiver plot, as mentioned in #1026 and mailing list
We only had a week to work on the implementation and term report, so it's not a full featured quiver as 2D quiver. But we got the basics working and it should be usable.
Below is a graph for z = sin(x) + cos(y)