2

I'm using matplotlib's quivers to draw some vectors in 3d axes. The problem is when I want to add a slider widget and update the magnitude of vector according to slider, once I change the position everything works as my expectation, but I lose the arrow head of quiver.

Here is the example code:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.widgets import Slider
import numpy as np

fig = plt.figure(figsize=(10,6))
ax = fig.gca(projection='3d')
plt.subplots_adjust(bottom=0.15)

ax.set_xlim3d(-1, 1)
ax.set_ylim3d(-1, 1)
ax.set_zlim3d(-1, 1)

pos = [0.0, 0.0, 0.0]
V_ini = [0.5, 0.0, 0.0]

V = ax.quiver(*pos, *V_ini, length=1, normalize=False, color='green')

# SLIDER POSITIONS ON FIGURE
axcolor = 'lightgoldenrodyellow'
axVx = plt.axes([0.1, 0.11, 0.15, 0.02], facecolor=axcolor)
axVy = plt.axes([0.1, 0.08, 0.15, 0.02], facecolor=axcolor)
axVz = plt.axes([0.1, 0.05, 0.15, 0.02], facecolor=axcolor)

# SLIDER PROPERTIES
sliderVx = Slider(axVx, 'Vx', -1, 1, valinit=V_ini[0], valstep=0.01)
sliderVy = Slider(axVy, 'Vy', -1, 1, valinit=V_ini[1], valstep=0.01)
sliderVz = Slider(axVz, 'Vz', -1, 1, valinit=V_ini[2], valstep=0.01)

# QUIVER TO SEGMENT CONVERTER
def q2s(X, Y, Z, u, v, w, length=1):
    segments = (X, Y, Z, X+u*length, Y+v*length, Z+w*length)
    segments = np.array(segments).reshape(6,-1)
    return [[[x, y, z], [u, v, w]] for x, y, z, u, v, w in zip(*list(segments))]

def update(val):
    V_ = (sliderVx.val, sliderVy.val, sliderVz.val)
    V.set_segments(q2s(*pos, *V_))


sliderVx.on_changed(update)
sliderVy.on_changed(update)
sliderVz.on_changed(update)

plt.show()

Here what it looks like before:

before

And after I update:

after

I know that converting quivers to segment lines is causing the problem, but I don't know any other way to update quivers. Any help will be appreciated.

  • I believe that if you have N arrows, the first N segments are the arrow shafts. Then the next 2 segments are the first arrow head. Then the next 2 segments are the second arrowhead. Etc. So you have a total of 3N segments. – Job Stancil May 05 '20 at 09:56
  • Does this answer your question? [Animating a 3D vector with matplotlib](https://stackoverflow.com/questions/55169099/animating-a-3d-vector-with-matplotlib) – Mr. T Jan 13 '21 at 19:25

0 Answers0