Alarik
Alarik

Reputation: 553

Python polar clock-like plot with matplotlib

I am trying to plot data in a clock-wise fashion using matplotlib in Python in the style of this answer. I noticed weird behaviour when plotting my data; the data points had the correct y value, but would not appear at the correct x values, i.e. times. I first thought that my data was erroneous, but upon recreating my problem with the following working example I came to the conclusion that the mistake must be somewhere else.

import numpy as np
import matplotlib.pyplot as plt     

ax = plt.subplot(111, polar=True)
equals = np.linspace(0, 360, 24, endpoint=False) #np.arange(24)
ones = np.ones(24)
ax.scatter(equals, ones)       

# Set the circumference labels
ax.set_xticks(np.linspace(0, 2*np.pi, 24, endpoint=False))
ax.set_xticklabels(range(24))      

# Make the labels go clockwise
ax.set_theta_direction(-1)       

# Place 0 at the top
ax.set_theta_offset(np.pi/2.0)       

plt.show()

This results in the following plot: enter image description here

I would have expected that the x values of the points line up with the hours, considering the definition of equals. It is currently defined as an angle, but I also tried defining it as an hour. Why is this not the case and how can I get my data to line up with the corresponding time?

Upvotes: 3

Views: 3643

Answers (2)

David Zwicker
David Zwicker

Reputation: 24318

Matplotlib expects angles to be in units of radians and not degrees (see the open bug report). You can use the numpy function np.deg2rad to convert to radians:

import numpy as np
import matplotlib.pyplot as plt     

ax = plt.subplot(111, polar=True)
equals = np.linspace(0, 360, 24, endpoint=False) #np.arange(24)
ones = np.ones(24)
ax.scatter(np.deg2rad(equals), ones)       

# Set the circumference labels
ax.set_xticks(np.linspace(0, 2*np.pi, 24, endpoint=False))
ax.set_xticklabels(range(24))      

# Make the labels go clockwise
ax.set_theta_direction(-1)       

# Place 0 at the top
ax.set_theta_offset(np.pi/2.0)       

plt.show()

This produces the following picture:

enter image description here

Alternatively, you could have changed your definition of equals to produce angles in terms of radians: equals = np.linspace(0, 2*np.pi, 24, endpoint=False)

Upvotes: 5

David Z
David Z

Reputation: 131610

Your equals array is in degrees, but matplotlib expects radians. So all you need to do is make your angle measurements in radians.

Upvotes: 1

Related Questions