3

From a set of angle (theta) and radius (r) I drew a scatter plot using matplotlib:

fig = plt.figure()
ax = plt.subplot(111, polar=True)

ax.scatter(theta, r, color='None', edgecolor='red')

ax.set_rmax(1)   
plt.savefig("polar.eps",bbox_inches='tight')

Which gave me this figure

I now want to draw the density contour map on top of that, so I tried:

fig = plt.figure()
ax = plt.subplot(111, polar=True)

H, theta_edges, r_edges = np.histogram2d(theta, r)
cax = ax.contourf(theta_edges[:-1], r_edges[:-1], H, 10, cmap=plt.cm.Spectral)

ax.set_rmax(1)
plt.savefig("polar.eps",bbox_inches='tight')

Which gave me the following results that is obviously not what I wanted to do.

What am I doing wrong ?

4
  • Could you give a example of what a density contour map looks like sorry I'm not a graph expert. Commented Oct 30, 2016 at 10:24
  • 1
    It is a graph that represents the average density of point in a given area, the contours delimit the areas of different density: i.sstatic.net/XJYnz.png Commented Oct 30, 2016 at 10:30
  • in order to get something like that you have to use pcolor not contourf though? Commented Oct 30, 2016 at 10:40
  • 1
    I tried both, It doesn't change my issue with polar coordinates. Commented Oct 30, 2016 at 11:06

1 Answer 1

3

I think that the solution to your problem is to define the bins arrays for your histogram (for instance a linspaced array between 0 and 2pi for theta and between 0 and 1 for r). This can be done with the bins or range arguments of function numpy.histogram

I you do so, make sure that the theta values are all between 0 and 2pi by plotting theta % (2 * pi) instead of theta.

Finally, you may choose to plot the middle of the bin edges instead of the left side of the bins as done in your example (use 0.5 * (r_edges[1:] + r_edges[:-1]) instead of r_edges[:-1])

below is a suggestion of code

import matplotlib.pyplot as plt
import numpy as np

#create the data 
r1     = .2 + .2 * np.random.randn(200)
theta1 = 0. + np.pi / 7. * np.random.randn(len(r1)) 
r2     = .8 + .2 * np.random.randn(300)
theta2 = .75 * np.pi + np.pi / 7. * np.random.randn(len(r2)) 
r = np.concatenate((r1, r2))
theta = np.concatenate((theta1, theta2))



fig = plt.figure()
ax = plt.subplot(111, polar=True)

#define the bin spaces
r_bins     = np.linspace(0., 1., 12)
N_theta    = 36
d_theta    = 2. * np.pi / (N_theta + 1.)
theta_bins = np.linspace(-d_theta / 2., 2. * np.pi + d_theta / 2., N_theta)


H, theta_edges, r_edges = np.histogram2d(theta % (2. * np.pi), r, bins = (theta_bins, r_bins))

#plot data in the middle of the bins
r_mid     = .5 * (r_edges[:-1] + r_edges[1:])
theta_mid = .5 * (theta_edges[:-1] + theta_edges[1:])


cax = ax.contourf(theta_mid, r_mid, H.T, 10, cmap=plt.cm.Spectral)
ax.scatter(theta, r, color='k', marker='+')
ax.set_rmax(1)
plt.show()

which should result as

polar histogram

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

2 Comments

Do you now if there is a way to have the same density of bin everywhere on the plot ? As of now, the bins in the center have a small surface, will the bins at the boundary have a large surface.
You may use non linear bin spaces so that the surface of each bin is the same. Alternatively you can use the density=True argument of the histogram function (or divide the content of H by the surface of each bin, which should be equivalent)

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.