3

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?

2 Answers 2

5

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)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, this solved my problem! For those interested, to convert a time from a 24h clock to a radiant, simply multiply the time by 15 to obtain the degree and then convert it to radians (though there is certainly a more straight-forward solution). lambda t: np.deg2rad(t*15)
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.