Plot with sticks or arrows

It seems that the 3D quiver arrows in Plots.jl might be work in progress.

By extending this user function to 3D, you can get:

Fixed 3d arrow head sizes:

Proportional 3d arrow head sizes:

Julia 1.7 Plots.jl code used
using LinearAlgebra, Plots; gr(dpi=600)

# as: arrow head size 0-1 (fraction of arrow length)
# la: arrow alpha transparency 0-1
function arrow3d!(x, y, z,  u, v, w; as=0.1, lc=:black, la=1, lw=0.4, scale=:identity)
    (as < 0) && (nv0 = -maximum(norm.(eachrow([u v w]))))
    for (x,y,z, u,v,w) in zip(x,y,z, u,v,w)
        nv = sqrt(u^2 + v^2 + w^2)
        v1, v2 = -[u,v,w]/nv, nullspace(adjoint([u,v,w]))[:,1]
        v4 = (3*v1 + v2)/3.1623  # sqrt(10) to get unit vector
        v5 = v4 - 2*(v4'*v2)*v2
        (as < 0) && (nv = nv0) 
        v4, v5 = -as*nv*v4, -as*nv*v5
        plot!([x,x+u], [y,y+v], [z,z+w], lc=lc, la=la, lw=lw, scale=scale, label=false)
        plot!([x+u,x+u-v5[1]], [y+v,y+v-v5[2]], [z+w,z+w-v5[3]], lc=lc, la=la, lw=lw, label=false)
        plot!([x+u,x+u-v4[1]], [y+v,y+v-v4[2]], [z+w,z+w-v4[3]], lc=lc, la=la, lw=lw, label=false)
    end
end

# input points and arrows
x = y = 0:0.1:3π; z = zero(x)
u = v = zero(x);  w = sin.(x)

# arrows with fixed head sizes
p = plot(camera=(20,30), legend=false)
arrow3d!(x, zero(y), zero(z), u, w, v; as=-0.05, lc=:red, la=0.5)
arrow3d!(x, zero(y), zero(z), u, v, w; as=-0.05, lc=:blue, la=0.5)
display(p)

# arrows with proportional 5% head sizes
p = plot(camera=(20,30))
arrow3d!(x, zero(y), zero(z), u, w, v; as=0.05, lc=:red, la=0.5)
arrow3d!(x, zero(y), zero(z), u, v, w; as=0.05, lc=:blue, la=0.5)
display(p)

4 Likes