Changing axis in polar seasonal plots with Cairomakie

I am trying to replicate the seasonal plot with the polar axis from this example, but I couldn’t figure out how to replace the degree axis with months. This is the code:

Creating the dataframe

link = "https://vincentarelbundock.github.io/Rdatasets/csv/fpp2/a10.csv"
f = download(link)
a10 = DataFrame(CSV.File(f))
a10.year = parse.( Int64, first.(string.(a10.time),4))
a10.month .= 1
for (i, r) in enumerate(eachrow(a10))
	r.month   += (i +5) % 12
end

should give this:

julia> first(a10, 5)
5×5 DataFrame
 Row │ rownames  time     value    year   month
     │ Int64     Float64  Float64  Int64  Int64
─────┼──────────────────────────────────────────
   1 │        1  1991.5   3.52659   1991      7
   2 │        2  1991.58  3.18089   1991      8
   3 │        3  1991.67  3.25222   1991      9
   4 │        4  1991.75  3.611     1991     10
   5 │        5  1991.83  3.56587   1991     11

And now, trying to create the Plot.

psize = length(unique(a10.year))	
f = Figure()
ax =PolarAxis(f[1,1], title = "seasonal plot: "  ,theta_0 = -pi/2, direction = -1, )
cbarPal = :thermal
cmap = cgrad(ColorSchemes.colorschemes[:viridis], psize, categorical = true)
x =  length(unique(a10.month))
t = a10.month
tnorm = (t.-minimum(t))./(maximum(t).-minimum(t))*2*pi #normalize the axis related to X
a10.month_norm = tnorm  #add to the dataframe
list_lin = [] #empty list to use in legend
for (i, value) in enumerate(unique(a10.year))
	a10_filtered = filter([:year] => (z) -> z == value , a10)
	y = a10_filtered.value
	x = a10_filtered.month_norm
	lin = lines!(ax ,x,  y , label = string(value), color = cmap[i])
	push!(list_lin, lin)
end
Legend(f[1, 2], list_lin, string.(minimum(a10.year):maximum(a10.year)))

f

giving me this:

How can I replace the degrees on the circumference axes with months?

I’d assume you can pass a tuple (radians, ticklabels) to thetaticks PolarAxis · Makie

I have my doubts if I am doing it right because if I included in the definition of the axes considering the default value, I got just an error

julia> ax =PolarAxis(f[1,1], title = "seasonal plot: "  ,theta_0 = -pi/2, direction = -1, thetathicks = (180 / pi, "°"))
ERROR: MethodError: no method matching initialize_block!(::PolarAxis; thetathicks::Tuple{Float64, String})

and with AngularTicks(180 / pi, "°") get an error because AngularTicks is not defined

thetaticks not thetathicks :slight_smile:

And I’d guess you should pass (range(0, 2pi, length = 13)[1:end-1], list_of_months)

1 Like

That works fine! To sum up:

psize = length(unique(a10.year))	
f = Figure()
list_of_months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"]
ax =PolarAxis(f[1,1], title = "seasonal plot Polar Axis"  ,theta_0 = -pi/2, direction = -1, thetaticks =(range(0, 2pi, length = 13)[1:end-1], list_of_months))
#ax.ygridvisible = false
cbarPal = :thermal
cmap = cgrad(ColorSchemes.colorschemes[:viridis], psize, categorical = true)
x =  length(unique(a10.month))
t = a10.month
tnorm = (t.-minimum(t))./(maximum(t).-minimum(t))*2*pi
a10.month_norm = tnorm
list_lin = []
for (i, value) in enumerate(unique(a10.year))
	a10_filtered = filter([:year] => (z) -> z == value , a10)
	y = a10_filtered.value
	x = a10_filtered.month_norm
	lin = lines!(ax ,x,  y , label = string(value), color = cmap[i])
	push!(list_lin, lin)
end
Legend(f[1, 2], list_lin, string.(minimum(a10.year):maximum(a10.year)),)

f

Thank you so much :smile:

1 Like

Nice, although something’s still wrong in your code because the data points don’t match the theta locations of the months. Probably an off-by-one error somewhere.

Ah yeah your final point is in January again, while it should be in December

1 Like

Yeah, it’s another problem that I have to face. In the example, the line is connected, so the transition becomes smooth. However, in my iteration, I am not connecting the points between December and January, which is making that part a bit more confusing for interpretation.