You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Quiver plots currently have a set_UVC method which lets one animate the direction that the arrows point. Unfortunately, they do not have a set_XY, so one cannot animate the location of the arrows.
This limitation makes is hard to make things like: (An animation of elliptical polarization)
without resorting to simply clearing the axis, and redrawing everything on every frame. This annoyance get's compounded with even more complex animations.
Reacted by Malte Esders, Leo Hanisch, vikramchvc, Stathis Kagioulis, Abhishek Tiwari, Julien Guégan, Francesco Boccardo, Sarath Ravindran Nair and Ina Tang
Seems a reasonable addition. OTOH, I wouldn't necessarily have thought quiver was the right method for just drawing arrows. I think the reason that this hasn't been added before is that most quiver plots are thought of as mapping a field of vectors, and the field locations don't usually change. But there is no reason they couldn't.
I can think of lots of uses for something like this. For example, lets say I have a vector field and I want to apply a rotation to it. It would be nice to see the vector field actually rotate, and not just the arrows changing direction. I'll admit that changing the location of the arrows is more niche than setting the direction, so that's why I think a set_XY would be better than a set_XYUVC (that and backwards compatibility). When needing to animate a large number of arrows, ax.annotate isn't great to use.
For api consistency, we'd probably want a set_XY for barb plots too.
My gut says there's probably some implementation details that make this more than trivial, but I'd be willing to merge the work of someone else doing this. 😁
I don't know if this is a good method, but it can be done with qu.set_offsets(np.array([X.flatten(), Y.flatten()]).T) where qu is the matplotlib.quiver.Quiver object. It is described e.g. there.
This is kind of related too. If you increase the number of arrows with set_offsets and then try to update the (U,V) with set_UVC you will get a ValueError even if both are the same dimension.
The total number of arrows doesn't update as the Quiver class doesn't have a proper set_offsets function.
The following code procs the error in 3.3.2
import matplotlib.pyplot as plt
import numpy as np
X, Y = np.random.rand(10, 2).T
U, V = np.random.rand(10, 2).T
fig, ax = plt.subplots()
Q = ax.quiver(X, Y, U, V)
X, Y = np.random.rand(11, 2).T
Q.set_offsets(np.array([X, Y]).T)
U, V = np.random.rand(11, 2).T
Q.set_UVC(U, V)
plt.show()
@daniel-cr Changing the number of arrows is currently not supported consistently (we should proabably already fail on set_offsets(). The problem is that it is hard to maintain a valid state. X, Y, U, V, C need to have the same size, and also you have parameters like color, that can be one element per arrow.
Thank you this works. It seems this feature is available only on version 3.1.3, as I tried on 3.3.2 and it failed.
One more question if you don't mind. I have been trying to update the color array for each arrow using set_UVC(U, V,C) but it fails.
I had it like this:
Q = ax.quiver(X, Y, U, V, color=color)
color = np.array(['b','b','r','r','g','g','m','m','y','y'])
...
Q.set_UVC(U, V,color)
One more question if you don't mind. I have been trying to update the color array for each arrow using set_UVC(U, V,C) but it fails.
@yasser-h-khalil, it should work if you use :
players.set_facecolors(colors[idx_timestamp]) # with len(colors[idx_timestamp]) = len(positions[idx_timestamp])
Just to re-iterate - I'm sure we would accept a PR for setting set_xy. I'm not sure we would consider changing the number of quivers a robust feature, but if there were a separate PR that had a clean API, I imagine we could do so. As @timhoffm says, there is a lot of state to carry around and sync up.
I will also re-iterate that this is all likely better done with arrow calls if you are just dealing with a finite number of points that are moving around.
One more question if you don't mind. I have been trying to update the color array for each arrow using set_UVC(U, V,C) but it fails.
@yasser-h-khalil, it should work if you use :
players.set_facecolors(colors[idx_timestamp]) # with len(colors[idx_timestamp]) = len(positions[idx_timestamp])
True. It works. However, I noticed it is a slow command.
I figured out that the color array needs to be float to be accepted by set_UVC. But I still didn't figure out what are the type of those float numbers. Like what float number reflects what color.
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
Activity
jklymak commentedon Jul 28, 2018
Seems a reasonable addition. OTOH, I wouldn't necessarily have thought
quiverwas the right method for just drawing arrows. I think the reason that this hasn't been added before is that most quiver plots are thought of as mapping a field of vectors, and the field locations don't usually change. But there is no reason they couldn't.t-makaro commentedon Jul 28, 2018
I can think of lots of uses for something like this. For example, lets say I have a vector field and I want to apply a rotation to it. It would be nice to see the vector field actually rotate, and not just the arrows changing direction. I'll admit that changing the location of the arrows is more niche than setting the direction, so that's why I think a
set_XYwould be better than aset_XYUVC(that and backwards compatibility). When needing to animate a large number of arrows,ax.annotateisn't great to use.For api consistency, we'd probably want a
set_XYfor barb plots too.dopplershift commentedon Jul 31, 2018
My gut says there's probably some implementation details that make this more than trivial, but I'd be willing to merge the work of someone else doing this. 😁
fruchart commentedon Jun 28, 2019
I don't know if this is a good method, but it can be done with
qu.set_offsets(np.array([X.flatten(), Y.flatten()]).T)wherequis thematplotlib.quiver.Quiverobject. It is described e.g. there.daniel-cr commentedon Oct 18, 2020
This is kind of related too. If you increase the number of arrows with set_offsets and then try to update the (U,V) with set_UVC you will get a ValueError even if both are the same dimension.
The total number of arrows doesn't update as the Quiver class doesn't have a proper set_offsets function.
The following code procs the error in 3.3.2
timhoffm commentedon Nov 1, 2020
@daniel-cr Changing the number of arrows is currently not supported consistently (we should proabably already fail on
set_offsets(). The problem is that it is hard to maintain a valid state. X, Y, U, V, C need to have the same size, and also you have parameters like color, that can be one element per arrow.theovincent commentedon Nov 16, 2020
I know it is not the best way of doing it but if you really want to change the number of arrows, matplotlib version 3.1.3 allows you to do it :)
yasser-h-khalil commentedon Dec 2, 2020
@thevincent could you please show me how it is done?
theovincent commentedon Dec 3, 2020
@yasser-h-khalil here is a simple example with matplotlib 3.1.3 :
Which produces this following :
yasser-h-khalil commentedon Dec 3, 2020
Thank you this works. It seems this feature is available only on version 3.1.3, as I tried on 3.3.2 and it failed.
One more question if you don't mind. I have been trying to update the color array for each arrow using
set_UVC(U, V,C)but it fails.I had it like this:
Any suggestions. Thanks.
HaaLeo commentedon Dec 3, 2020
I would love to do this in matplotlib 3.3.3, too.
theovincent commentedon Dec 3, 2020
@yasser-h-khalil, it should work if you use :
players.set_facecolors(colors[idx_timestamp]) # with len(colors[idx_timestamp]) = len(positions[idx_timestamp])
jklymak commentedon Dec 3, 2020
Just to re-iterate - I'm sure we would accept a PR for setting
set_xy. I'm not sure we would consider changing the number of quivers a robust feature, but if there were a separate PR that had a clean API, I imagine we could do so. As @timhoffm says, there is a lot of state to carry around and sync up.I will also re-iterate that this is all likely better done with
arrowcalls if you are just dealing with a finite number of points that are moving around.yasser-h-khalil commentedon Dec 3, 2020
True. It works. However, I noticed it is a slow command.
I figured out that the color array needs to be float to be accepted by set_UVC. But I still didn't figure out what are the type of those float numbers. Like what float number reflects what color.
Thanks.
jklymak commentedon Dec 3, 2020
@yasser-h-khalil Please take user-help to discourse.matplotlib.org. Thanks!
ianhi commentedon Feb 5, 2022
See #22407 for a possible
set_datathat allows changing the number of arrows.github-actions commentedon Oct 11, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!