# How to plot the orientation of particles?

Dear all,
I am trying to plot the orientation of 2D Brownian particles. I have the x and y positions and the orientation of each particle. Given this, I have successfully plotted the x and y positions of the particles, and now I want to superimpose their respective orientation on top it.
Any help will be highly appreciated.
Many thanks for considering my request.

The Plots.jl package has a function `quiver` that should do what you want (plot little arrows).

help?> quiver
``````search: quiver quiver!

quiver(x,y,quiver=(u,v))
quiver!(x,y,quiver=(u,v))

Make a quiver (vector field) plot. The ith vector extends from (x[i],y[i]) to (x[i] + u[i], y[i] + v[i]).

Keyword arguments
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

•  arrow::Union{Bool, Plots.Arrow}: Defines arrowheads that should be displayed at the end of path line segments (just before a NaN
and the last non-NaN point). Used in quiverplot, streamplot, or similar. Aliases: (:arrows,).

Example
≡≡≡≡≡≡≡≡≡

julia> quiver([1,2,3],[3,2,1],quiver=([1,1,1],[1,2,3]))
``````

It is also common to plot the orientation not with arrows (that can get messy quickly), but instead color the particles in different colors, according to their orientation, e.g. in this paper
https://www.researchgate.net/figure/Simulation-snapshot-of-active-Brownian-particles-in-an-elongated-box-employing-periodic_fig1_337966798

Here is another thread discussing how to achieve that: How to color points in scatter plot by value?

It boils down to something like

``````julia> using Plots
julia> N = 100
julia> xs = rand(N); ys = rand(N); φs = 2π .* rand(N);
julia> scatter(xs, ys, marker_z=φs, color=:rainbow)
``````

This method works in my code. However, I am not getting color gradient map along with the plot.
What could be the reason?
scatter(graph_wall[1][i][:,1], graph_wall[1][i][:,2], marker_z=graph_wall[2][i,1], color=:rainbow, aspect_ratio=:equal, lims=(-L/2, L/2),markersize=350R/L, marker =:circle,legend=false, title = “\$Np particles, steps \$Nt, ellipse a=L/2, b=L/3”)
where i is for the time loop.

In my case, it will probably not work.
Quiver makes an arrow from one point to another point while orientation is not a point.

Arrows may also be given with location, orientation, magnitude

Just a small comment: enclosing the code in three backticks ( ` ) makes it a lot easier to read and copy/paste.

`````````julia

```
``````

You’re using `legend=false` which turns off the colorbar on the side. In my snippet, the output looks like this

It works, but it might be a bit tricky to get used to. Mathematically, an orientation is usually represented as a (unit) vector. But a point in the x-y-plane is also represented by a vector.

What `quiver` does is attaching small arrows to the x-y-positions you specify. The length and direction of the arrows is given by the u-v-coordinates. Here is the same example as with the colors, but using `quiver` instead:

``````quiver(xs, ys, quiver=(0.05 .* cos.(φs), 0.05 .* sin.(φs)))
scatter!(xs, ys)
``````

We first draw the arrows at the particles’ positions. The vector for the orientation is computed from the angle (which is very convenient in 2D) and they are shortened to a length of `0.05` so they don’t span the whole plot.
On top of the arrows, we can also plot the particle markers.

1 Like

For good-looking arrows, finer control and fast display, you can use Plots’ shapes:

Plots gr() code
``````using Plots; gr(legend=false)

function R(θ)               # Rotation matrix
sθ, cθ = sincosd(θ)
return [cθ -sθ; sθ cθ]
end

function Sarrow(θ)
M = [Ref(R(u)) .* [[0, 0],[0,0.8],[0.15,0.6],[0,1], [-0.15,0.6], [0,0.8]] for u in θ]
return [Shape(first.(m), last.(m)) for m in M]
end

N = 100
x, y, θ = rand(N), rand(N), rand(0:359, N)
scatter(x, y, ms=2, c=:white, msc=:black, msw=0.2, ratio=1, lims=(0,1))
scatter!(x, y, marker=Sarrow(θ), ms=10, c=:black, msc=:black, msw=0.2)
``````
2 Likes

It’s not exactly what you are after, but if you end up wanting to plot trajectories of atomic simulations there is some functionality in Molly.jl.

1 Like