Search code examples
pythonmatplotlibtime-seriespolar-coordinates

Polar chart of yearly data with matplolib


I am trying to plot data for a whole year as a polar chart in matplotlib, and having trouble locating any examples of this. I managed to convert the dates from pandas according to this thread, but I can't wrap my head around (litterally) the y-axis, or theta.

This is how far I got:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd

times = pd.date_range("01/01/2016", "12/31/2016")
rand_nums = np.random.rand(len(times),1)
df = pd.DataFrame(index=times, data=rand_nums, columns=['A'])

ax = plt.subplot(projection='polar')
ax.set_theta_direction(-1)
ax.set_theta_zero_location("N")
ax.plot(mdates.date2num(df.index.to_pydatetime()), df['A'])
plt.show()

which gives me this plot:

this plot

reducing the date range to understand what is going on
times = pd.date_range("01/01/2016", "01/05/2016") I get this plot:

this plot

I gather that the start of the series is between 90 and 135, but how can I 'remap' this so that my year date range starts and finishes at the north origin?


Solution

  • The polar plot's angle range ranges over a full circle in radiants, i.e. [0, 2π]. One would therefore need to normalize the date range to the full circle.

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    import pandas as pd
    
    times = pd.date_range("01/01/2016", "12/31/2016")
    rand_nums = np.random.rand(len(times),1)
    df = pd.DataFrame(index=times, data=rand_nums, columns=['A'])
    
    ax = plt.subplot(projection='polar')
    ax.set_theta_direction(-1)
    ax.set_theta_zero_location("N")
    
    t = mdates.date2num(df.index.to_pydatetime())
    y = df['A']
    tnorm = (t-t.min())/(t.max()-t.min())*2.*np.pi
    ax.fill_between(tnorm,y ,0, alpha=0.4)
    ax.plot(tnorm,y , linewidth=0.8)
    plt.show()
    

    enter image description here