したがって、私が理解しているように、同じ極座標プロットに非常に異なる大きさのデータを表示したいと考えています。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()
ただし、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)
# There should be a method for this, but there isn't... Pull request?
ax2._r_label_position._t = (22.5 + 180, 0.0)
ax2._r_label_position.invalidate()
# Ensure that original axes tick labels are on top of plots in twinned axes
for label in ax.get_yticklabels():
ax.figure.texts.append(label)
return ax2
main()
これは私たちが望んでいることですが、最初はかなり悪いように見えます。改善点の 1 つは、目盛りラベルをプロット対象に対応させることです。
plt.setp(ax2.get_yticklabels(), color='darkgreen')
plt.setp(ax.get_yticklabels(), color='darkblue')
ただし、まだダブル グリッドがあり、かなり混乱しています。これを回避する簡単な方法の 1 つは、グリッドが互いに重なるように r-limits (および/または r-ticks) を手動で設定することです。または、これを自動的に行うカスタム ロケーターを作成することもできます。ここでは単純なアプローチに固執しましょう。
ax.set_rlim([0, 5])
ax2.set_rlim([0, 1])
警告:共有軸は極座標プロットでは機能しないため、上記の実装では、元の軸の位置を変更すると問題が発生します。たとえば、Figure にカラーバーを追加すると、さまざまな問題が発生します。これを回避することは可能ですが、私はその部分を省略しました。必要な場合はお知らせください。例を追加します。
いずれにせよ、最終的な図を生成するための完全なスタンドアロン コードは次のとおりです。
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)
# There should be a method for this, but there isn't... Pull request?
ax2._r_label_position._t = (22.5 + 180, 0.0)
ax2._r_label_position.invalidate()
# Bit of a hack to ensure that the original axes tick labels are on top of
# whatever is plotted in the twinned axes. Tick labels will be drawn twice.
for label in ax.get_yticklabels():
ax.figure.texts.append(label)
return ax2
if __name__ == '__main__':
main()