Quiver plot (Plots.pyplot) with different colors depending on the length of the arrow

Hello,
I am new to Julia and tried to plot the gradient field of a loss function. I can get the lengths of the arrows by norm(dx, dy). But I don’t know how to convert a vector of values (lengths) into a vector of colors or how to specify a color based on a value.
My plot order looks like this:
""pl=quiver(Kp_plot, Ki_plot, quiver=(grad_Kp, grad_Ki), xlims=(Kp_plot[1],Kp_plot[end]) ,ylims=(Ki_plot[1],Ki_plot[end]) “”

I searched for hours and hope desperately that someone can help me

Please check this post out.

1 Like

Thank you for this really quick response!
I already saw this post, but didn’t quite understand the argument line_z and how I could use it for my example. I found another code example with

Blockquote
color = np.sqrt(((v-n)/2) 2 + ((u-n)/2) 2)
quiver(X,Y,u,v,color, alpha=0.8)
Blockquote

but this doesn’t work as well. Some information is missing for me. :frowning:

But at least I found Blockquotes

Your last quote seems from Python.
You may define an array of arrow lengths and feed it to line_z argument as done here.
Best is to post a MWE.

I am not sure why I need 40 elements in line_z but this seems to do the trick.
quiver(rand(10),rand(10),quiver=(rand(10),rand(10)),line_z=rand(40))

using Plots
x = rand(10)
y = rand(10)
dx = rand(10)
dy = rand(10)
c = kron(sqrt.(dx .^2 .+dy .^2),[1,1,1,1])
quiver(x,y,quiver=(dx,dy),line_z=c)

Another way, that might be a bit simpler but, in pyplot() the arrow-head colors do not look good while they are fine in gr() …

using Plots
x , y = rand(10), rand(10)
dx, dy = rand(10), rand(10)
c = sqrt.(dx .^2 .+dy .^2)
c = [c c]'
quiver(x,y,quiver=(dx,dy),line_z=repeat([c...], inner=2), c=:thermal)
1 Like

Thanks to both of you for your help!

I have come a step further, but not quite where I want to be. Both of your code snippets produce the same output:

It looks nice but the color doesn’t seem to be strictly related to the length of the arrows. I have no idea why. The ones in the middle are the shortest and therefor should be less bright than the upper ones.

Help is very welcome

PS: Is there an argument for the arrow hat size? I found one for Makie but not for Plots.gr()

In gr() back-end all looks good to me:

But not in pyplot() back-end where the arrow-heads are an issue:

1 Like

GR seems to not support the arrow series type so they draw the arrows using the shape series type.
If you want to customize it you could also plot other shapes using that method.
This would explain the multiple color values.

1 Like

Oh fine, thank you!

I didn’t completely understand what’s going on with the inner= -part. But I tried to understand the code example from the link above. I did the following:

Blockquote

Arrow position.

x = collect(0:10) # we have 11 points, not 10 !
y = fill(0., 10)

Arrow direction.

u = fill(1., 10)
v = fill(10., 10) # I think the (1,10) here was a typo

Arrow color.

c = collect(1:11) # or 0:10, but not 1:10
plt = quiver(x, y, quiver=(u, v), line_z=c, c=:viridis)
display(plt)

Blockquote

and I get:


I gave my example another try with as many lengths as arrows. And it worked out after all ! Now I only have to change the sombreros. But I’m already delighted. I couldn’t have done that without your help!

1 Like