<p>@drevicko的答案在我绘制以下两个点序列时失败了:</p>
<pre><code>l1 = [0.03, -0.6, 1, 0.05]
l2 = [0.8, 0.9, 1, 1.1]
fig, ax1 = plt.subplots()
ax1.plot(l1)
ax2 = ax1.twinx()
ax2.plot(l2, color='r')
align_yaxis(ax1, 0, ax2, 0)
</code></pre>
<p><a href="https://i.stack.imgur.com/pPTEL.png" rel="noreferrer"><img src="https://i.stack.imgur.com/pPTEL.png" alt="enter image description here"/></a></p>
<p>。。。下面是我的版本:</p>
<pre><code>def align_yaxis(ax1, ax2):
"""Align zeros of the two axes, zooming them out by same ratio"""
axes = (ax1, ax2)
extrema = [ax.get_ylim() for ax in axes]
tops = [extr[1] / (extr[1] - extr[0]) for extr in extrema]
# Ensure that plots (intervals) are ordered bottom to top:
if tops[0] > tops[1]:
axes, extrema, tops = [list(reversed(l)) for l in (axes, extrema, tops)]
# How much would the plot overflow if we kept current zoom levels?
tot_span = tops[1] + 1 - tops[0]
b_new_t = extrema[0][0] + tot_span * (extrema[0][1] - extrema[0][0])
t_new_b = extrema[1][1] - tot_span * (extrema[1][1] - extrema[1][0])
axes[0].set_ylim(extrema[0][0], b_new_t)
axes[1].set_ylim(t_new_b, extrema[1][1])
</code></pre>
<p>原则上,有无限不同的可能性来对齐零(或其他值,另一个提供的解决方案接受这些值):只要将零放在y轴上,就可以缩放这两个序列中的每一个,使其适合。我们只是选择一个位置,这样在转换后,两个覆盖相同高度的垂直间隔。
或者换言之,与不对齐图相比,我们在相同因素下最小化它们。
(这并不意味着0位于图的一半:这将发生,例如,如果一个图全部为负,另一个图全部为正。)</p>
<p>Numpy版本:</p>
<pre><code>def align_yaxis_np(ax1, ax2):
"""Align zeros of the two axes, zooming them out by same ratio"""
axes = np.array([ax1, ax2])
extrema = np.array([ax.get_ylim() for ax in axes])
tops = extrema[:,1] / (extrema[:,1] - extrema[:,0])
# Ensure that plots (intervals) are ordered bottom to top:
if tops[0] > tops[1]:
axes, extrema, tops = [a[::-1] for a in (axes, extrema, tops)]
# How much would the plot overflow if we kept current zoom levels?
tot_span = tops[1] + 1 - tops[0]
extrema[0,1] = extrema[0,0] + tot_span * (extrema[0,1] - extrema[0,0])
extrema[1,0] = extrema[1,1] + tot_span * (extrema[1,0] - extrema[1,1])
[axes[i].set_ylim(*extrema[i]) for i in range(2)]
</code></pre>