使用极坐标在 matplotlib 中绘制等高线密度图
Contour density plot in matplotlib using polar coordinates
根据一组角度 (theta) 和半径 (r),我使用 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
我现在想在上面绘制密度等值线图,所以我尝试了:
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.
我做错了什么?
我认为您的问题的解决方案是为您的直方图定义 bins 数组(例如 0 到 2pi 之间的 linspaced 数组用于 theta 和 0 到 1 之间用于 r)。这可以通过函数 numpy.histogram
的 bins 或 range 参数来完成
我这样做了,通过绘制 theta % (2 * pi) 而不是 theta 来确保 theta 值都在 0 和 2pi 之间。
最后,您可以选择绘制 bin 边缘的中间而不是像示例中那样绘制 bin 的左侧(使用 0.5 * (r_edges[1:] + r_edges[:-1]) 而不是 r_edges[:-1])
下面是代码的建议
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()
结果应该是
根据一组角度 (theta) 和半径 (r),我使用 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
我现在想在上面绘制密度等值线图,所以我尝试了:
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.
我做错了什么?
我认为您的问题的解决方案是为您的直方图定义 bins 数组(例如 0 到 2pi 之间的 linspaced 数组用于 theta 和 0 到 1 之间用于 r)。这可以通过函数 numpy.histogram
的 bins 或 range 参数来完成我这样做了,通过绘制 theta % (2 * pi) 而不是 theta 来确保 theta 值都在 0 和 2pi 之间。
最后,您可以选择绘制 bin 边缘的中间而不是像示例中那样绘制 bin 的左侧(使用 0.5 * (r_edges[1:] + r_edges[:-1]) 而不是 r_edges[:-1])
下面是代码的建议
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()
结果应该是