Quiver plot arrowhead sizing


I am working on an image analysis tool for particle image velocimetry and one of the outputs will be a vector field. I can produce the vector field easily enough, but the components of each vector are very small due to the intended application. This results in the arrow lines being very small while the arrow heads are very large in comparison to the overall field size. I tried scaling the vector values, however the vector field is fairly high density and so this just looks cluttered.

I was wondering if anyone could tell me if there is currently an easy way to scale the arrowheads on a vector plot within the Plots.jl package. I have seen some examples that don’t seem to work and I know the quiver aspect of Plots.jl was sort of unfinished a few years ago.
Alternatively will I need to venture into a more specialised package?

Any advice will be greatly appreciated.

You might want to try the Gaston back end. It uses gnuplot (which you need to have installed), and you can pass settings to gnuplot. Gnuplot has settings for not only the size, but the shape and type of arrowhead. And if your vector field is large, gnuplot will be faster than anything else.

Makie does this well - see here.

You can try the user function arrow0!(), broadcasted as in example further below and which depends only on Plots.jl, as an alternative to quiver!().
(data example based on this other post)

Plots.jl code
using ForwardDiff
const βˆ‚ = ForwardDiff.derivative

f(x, y) = y * exp(-(x^2 + y^2))
u_(x, y) = -βˆ‚(Base.Fix2(f, y), x)
v_(x, y) = -βˆ‚(Base.Fix1(f, x), y)

lims = (-2.2, 2.2)
xs = ys = range(lims...; length=200)
c = 0.3
x = y = range(-2.0, 2.0; length=15)
X, Y = reim(complex.(x', y))        # meshgrid
U, V = c*u_.(x', y), c*v_.(x', y)

using Plots; gr(legend=false, dpi=600)

# as: arrow head size 0-1 (fraction of arrow length;  la: arrow alpha transparency 0-1
function arrow0!(x, y, u, v; as=0.07, lw=1, lc=:black, la=1)
    nuv = sqrt(u^2 + v^2)
    v1, v2 = [u;v] / nuv,  [-v;u] / nuv
    v4 = (3*v1 + v2)/3.1623  # sqrt(10) to get unit vector
    v5 = v4 - 2*(v4'*v2)*v2
    v4, v5 = as*nuv*v4, as*nuv*v5
    plot!([x,x+u], [y,y+v], lw=lw, lc=lc, la=la)
    plot!([x+u,x+u-v5[1]], [y+v,y+v-v5[2]], lw=lw, lc=lc, la=la)
    plot!([x+u,x+u-v4[1]], [y+v,y+v-v4[2]], lw=lw, lc=lc, la=la)

# Alternative to: quiver!(vec(X-U/2), vec(Y-V/2); quiver=(vec(U), vec(V)), color=:red)
# Plot points and arrows with 30% head sizes
heatmap(xs, ys, f, title="arrow0!", lims=lims, ratio=1)
arrow0!.(X, Y, U, V; as=0.3, lw=0.5,lc=:red, la=1);
1 Like

Sorry for the long delay in response, other aspect of my programme came up meaning this got pushed to the side for a while. I am going to take a look at Makie as it has been suggested across multiple other peoples posts

Thanks for all the advice