Hello,

I have to bin periodic data. I was wondering if there are packages that can deal with polar binning in Julia. I have not been able to find it online.

Any help is appreciated!

Thank you in advance!

Hello,

I have to bin periodic data. I was wondering if there are packages that can deal with polar binning in Julia. I have not been able to find it online.

Any help is appreciated!

Thank you in advance!

Can you give an example of your data?

Would rose plots qualify as “polar binning”?

The CircStats.jl package and this reference seem relevant.

A rose plot would be what I need but I only need the data separated into bins, not the plot itself.

I’m not certain your use case, but this is simple enough:

```
using Distributions
# assume a and b are in radians
# compute intrinsic distance on the circle. Works for any interval.
function circdist(a, b)
d = a - b
return (d ≈ π ? -one(d) * π : rem(d, oftype(d, 2) * π, RoundNearest))
end
# simulate data in [-3π/4, 5π/4]
pts = rand(VonMises(π / 4, 10), 1000)
edges = range(-π, π; length=20)
midpoints = (edges[1:end-1] .+ edges[2:end]) ./ 2
bins = map(pts) do p
argmax([circdist(m, p) for m in midpoints])
end
```

If you want to fit a histogram, it’s probably a good idea to center your data around 0 first. You can do this for example using Manifolds

```
using Manifolds, StatsBase
M = Circle()
μ = mean(M, pts) # intrinsic mean, approximately π / 4,
pts_centered = log.(Ref(M), μ, pts) # data with intrinsic mean of 0
hist_centered = fit(Histogram, pts_centered)
edges_centered = only(hist_centered.edges)
midpoints_centered = (edges_centered[1:end-1] .+ edges_centered[2:end]) ./ 2
bins = map(pts_centered) do p
argmax(distance.(Ref(M), midpoints_centered, p))
end
# get the uncentered midpoints of the bins
midpoints = exp.(Ref(M), μ, midpoints_centered)
```

1 Like

@sethaxen, could you please elaborate a bit on the use of manifolds here?

Also, in `circdist()`

what is the need for `one()`

and `oftype()`

, as the multiplication by `π`

seems to always produce floats?

Thanks.

**NB:**

*Fyi, the circular distance function was written more compactly in the links provided as:* `cdist(a, b) = mod(b - a + π, 2π) - π`

1 Like

Sure, here we create the real `Circle`

manifold, where points are represented as angles in radians over some interval. The call to `mean`

computes the intrinsic (i.e. Riemannian mean), which generalizes the usual mean to nonlinear spaces and respects the periodicity of the data. `log`

computes the Riemannian logarithm map from the mean to each point. You don’t need to know what this means, but the geometric idea is that it rotates the circle (and the data) so that the mean is at the 0 angle and then flattens it (by unwinding) into an interval of `[-π, π]`

, thus centering the data on 0. This can all be done with addition/subtraction and `mod`

, but I do it this way because I can never remember the appropriate `mod`

, and these functions work for any manifold.

The rest of the code just now ignores the circle and works with our interval. At the end, we use `exp`

(the opposite of `log`

), to undo the centering and get back bin midpoints that can be directly compared to our data.

These are just there for type stability. Otherwise depending on the values, a `Float`

or an `Irrational`

might be returned. The code you gave looks simpler and type-stable and probably does the same thing.

1 Like