Polar Histogram

Hi! I wrote a little function to plot polar histograms using PolarAxis. I wonder if it’s a good idea to add something like this to makie?

using StatsBase
using Distributions
using CairoMakie

#set of angles in radian
angles = deg2rad.(rand(Normal(45,15), 100))
#bins limits in degrees
bins = [0, 15, 30, 45, 60, 75, 90]

function polarhist(angles, bins)

    bins = deg2rad.(bins)
    h = fit(Histogram, angles, bins)
    x = collect(h.edges[1])
    y = h.weights ./ sum(h.weights)
    f = Figure()
    ax = PolarAxis(f[1, 1], title="Polar Histogram")

    for i in eachindex(y)
        if y[i] > 0
            poly!(ax, [(0, 0), (y[i], x[i]), (y[i], x[i+1])], [1, 2, 3])
        end
    end
    return f
end

polarhist(angles, bins)
3 Likes

I was searching for something like this and it would be realy practical if something like this existed within Makie.jl

Barplot does work with PolarAxis:

    f = Figure()
    ax = PolarAxis(f[1, 1], title="Polar Histogram")
    r = 0:0.1:2pi
    barplot!(ax, r, rand(length(r)), color=r)
    f

So it should mainly be about getting the x values on the angle range.

4 Likes

Is that with Makie? Because i remember this issue existing: PolarAxis histogram fails in CairoMakie · Issue #3175 · MakieOrg/Makie.jl · GitHub

Yeah I didn’t realize that this seems to be broken in cairomakie

But still thank you. Lets just hope they fix it in CairoMakie so i have less to suffer in Matplotlib.

Hi! I had to use poly to make it works with CairoMakie. Here is how I succeded:

using CairoMakie
using StatsBase
CairoMakie.activate!(type = "png")
angles = 360 * rand(1000)
f = Figure()
function PolarHist(angles, figure, limits, title, colour, transparancy, graphposition)
    anglesRad = deg2rad.(angles)
    binsRad = deg2rad.(collect(0:15:limits))
    h = fit(Histogram, anglesRad, binsRad)
    x = collect(h.edges[1])
    y = convert.(Float64, h.weights)
    ax = PolarAxis(figure[1, graphposition],
        title="$title",
        thetaticks=((collect(0:15:limits)) .* 2*pi ./ limits, string.(string.(collect(0:15:limits)), "°")),
        #rticks=collect(0:10:ceil(maximum(y) / 10)*10)
    )
    thetalims!(ax, 0, 2*pi )
    #rlims!(ax, 0, ceil(maximum(y) / 10) * 10)
    for i in eachindex(y)
        if y[i] > 0
            CairoMakie.poly!(ax, [(0.0, 0.0), (x[i], y[i]), (x[i+1], y[i])], [1, 2, 3], color=Makie.wong_colors()[colour], alpha=transparancy, strokewidth=2, strokecolor=:black)
        end
    end
end
PolarHist(angles, f, 360, "polar histogram", 3, 0.5, 1)
f

4 Likes

Oh god thats amazing. I love it.