所以,据我理解,您想在同一个极坐标图上显示具有非常不同数量级的数据。基本上,您正在询问如何在极轴上执行类似于twinx
的操作。
为了说明这个问题,以下示例中的绿色系列与蓝色系列保持在同一个极轴上方便比较的同时,它们的比例尺应该不同。
import numpy as np
import matplotlib.pyplot as plt
numpoints = 30
theta = np.linspace(0, 2*np.pi, numpoints)
r1 = np.random.random(numpoints)
r2 = 5 * np.random.random(numpoints)
params = dict(projection='polar', theta_direction=-1, theta_offset=np.pi/2)
fig, ax = plt.subplots(subplot_kw=params)
ax.fill_between(theta, r2, color='blue', alpha=0.5)
ax.fill_between(theta, r1, color='green', alpha=0.5)
plt.show()
![输入图像描述](https://istack.dev59.com/18GTQ.webp)
然而,对于极坐标图,ax.twinx()
无法工作。
虽然有办法绕过这个问题,但不是很直观。以下是一个例子:
import numpy as np
import matplotlib.pyplot as plt
def main():
numpoints = 30
theta = np.linspace(0, 2*np.pi, numpoints)
r1 = np.random.random(numpoints)
r2 = 5 * np.random.random(numpoints)
params = dict(projection='polar', theta_direction=-1, theta_offset=np.pi/2)
fig, ax = plt.subplots(subplot_kw=params)
ax2 = polar_twin(ax)
ax.fill_between(theta, r2, color='blue', alpha=0.5)
ax2.fill_between(theta, r1, color='green', alpha=0.5)
plt.show()
def polar_twin(ax):
ax2 = ax.figure.add_axes(ax.get_position(), projection='polar',
label='twin', frameon=False,
theta_direction=ax.get_theta_direction(),
theta_offset=ax.get_theta_offset())
ax2.xaxis.set_visible(False)
ax2._r_label_position._t = (22.5 + 180, 0.0)
ax2._r_label_position.invalidate()
for label in ax.get_yticklabels():
ax.figure.texts.append(label)
return ax2
main()
![输入图像描述](https://istack.dev59.com/MhcCs.webp)
这确实达到了我们想要的效果,但一开始看起来相当糟糕。一个改进的方法是将刻度标签对应到我们所绘制的内容:
plt.setp(ax2.get_yticklabels(), color='darkgreen')
plt.setp(ax.get_yticklabels(), color='darkblue')
![在此输入图像描述](https://istack.dev59.com/kdkj9.webp)
然而,我们仍然有双重网格线,这可能会导致困惑。一个简单的方法是手动设置r-limits(和/或r-ticks),以使网格线彼此重叠。或者,您可以编写自定义定位器以自动执行此操作。在这里,让我们坚持简单的方法:
ax.set_rlim([0, 5])
ax2.set_rlim([0, 1])
![enter image description here](https://istack.dev59.com/fUoxj.webp)
警告:由于共享轴不适用于极坐标图,上面的实现将在任何改变原始轴位置的情况下出现问题。例如,向图中添加彩条会导致各种问题。尽管有可能解决这个问题,但我并没有包含在内。如果您需要它,请告诉我,我可以添加一个示例。
无论如何,以下是完整的、独立的代码来生成最终的图形:
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1977)
def main():
numpoints = 30
theta = np.linspace(0, 2*np.pi, numpoints)
r1 = np.random.random(numpoints)
r2 = 5 * np.random.random(numpoints)
params = dict(projection='polar', theta_direction=-1, theta_offset=np.pi/2)
fig, ax = plt.subplots(subplot_kw=params)
ax2 = polar_twin(ax)
ax.fill_between(theta, r2, color='blue', alpha=0.5)
ax2.fill_between(theta, r1, color='green', alpha=0.5)
plt.setp(ax2.get_yticklabels(), color='darkgreen')
plt.setp(ax.get_yticklabels(), color='darkblue')
ax.set_ylim([0, 5])
ax2.set_ylim([0, 1])
plt.show()
def polar_twin(ax):
ax2 = ax.figure.add_axes(ax.get_position(), projection='polar',
label='twin', frameon=False,
theta_direction=ax.get_theta_direction(),
theta_offset=ax.get_theta_offset())
ax2.xaxis.set_visible(False)
ax2._r_label_position._t = (22.5 + 180, 0.0)
ax2._r_label_position.invalidate()
for label in ax.get_yticklabels():
ax.figure.texts.append(label)
return ax2
if __name__ == '__main__':
main()
np.arange
来设置刻度。arange
在终点之前停止(例如,np.arange(0, 0.5, 0.1)
会产生array([0.0, 0.1, 0.2, 0.3, 0.4])
)。如果你想包括终点,请使用end + dx
(其中dx
是你的间隔)代替。 - Joe Kington