from matplotlib import pyplot as plt
import numpy as np
#Create some Fake Data
x =np.arange(-10,10)
y = x+np.random.rand(20)
y2 = 0.5*x-3.*np.random.rand(20)
#Figure
fig = plt.figure(figsize=(12,6))
#First subplot with zero line not even
ax1 = plt.subplot(121)
ax2 = ax1.twinx()
ax1.plot(x,y,c='r')
ax2.plot(x,y2,c='b')
ax1.axhline(0)
#Second Subplot with zero line the same on both axes
ax3 = plt.subplot(122)
ax4 = ax3.twinx()
ax3.plot(x,y,c='r')
ax4.plot(x,y2,c='b')
ax3.axhline(0)
#If you set your limits on both sides to have the same interval you will get the same zero line
ax3.set_ylim(-10,10)
ax4.set_ylim(-6,6)
plt.show()
fig, ax1 = plt.subplots()
ax1.plot(...) # Plot first data set
ax2 = ax1.twinx()
ax2.plot(...) # Plot second data set
ax1_ylims = ax1.axes.get_ylim() # Find y-axis limits set by the plotter
ax1_yratio = ax1_ylims[0] / ax1_ylims[1] # Calculate ratio of lowest limit to highest limit
ax2_ylims = ax2.axes.get_ylim() # Find y-axis limits set by the plotter
ax2_yratio = ax2_ylims[0] / ax2_ylims[1] # Calculate ratio of lowest limit to highest limit
# If the plot limits ratio of plot 1 is smaller than plot 2, the first data set has
# a wider range range than the second data set. Calculate a new low limit for the
# second data set to obtain a similar ratio to the first data set.
# Else, do it the other way around
if ax1_yratio < ax2_yratio:
ax2.set_ylim(bottom = ax2_ylims[1]*ax1_yratio)
else:
ax1.set_ylim(bottom = ax1_ylims[1]*ax2_yratio)
plt.tight_layout()
plt.show()
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
def align_zeros(axes):
ylims_current = {} # Current ylims
ylims_mod = {} # Modified ylims
deltas = {} # ymax - ymin for ylims_current
ratios = {} # ratio of the zero point within deltas
for ax in axes:
ylims_current[ax] = list(ax.get_ylim())
# Need to convert a tuple to a list to manipulate elements.
deltas[ax] = ylims_current[ax][1] - ylims_current[ax][0]
ratios[ax] = -ylims_current[ax][0]/deltas[ax]
for ax in axes: # Loop through all axes to ensure each ax fits in others.
ylims_mod[ax] = [np.nan,np.nan] # Construct a blank list
ylims_mod[ax][1] = max(deltas[ax] * (1-np.array(list(ratios.values()))))
# Choose the max value among (delta for ax)*(1-ratios),
# and apply it to ymax for ax
ylims_mod[ax][0] = min(-deltas[ax] * np.array(list(ratios.values())))
# Do the same for ymin
ax.set_ylim(tuple(ylims_mod[ax]))
x = np.array(range(1,11))
y1 = 5*x-10
y2 = -10*x+5
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot(x,y1,'r',label='y1')
ax1.set_ylabel('y1')
ax2 = ax1.twinx()
ax2.plot(x,y2,'g',label='y2')
ax2.set_ylabel('y2')
align_zeros([ax1,ax2])
ax1.legend(loc='upper left')
ax2.legend(loc='upper right')
plt.show()
4条答案
按热度按时间vzgqcmou1#
假设你创建了一个共享轴的图,你只需要修改y的范围,使其以零为中心,或者在两个图中有一个类似的偏移乘数(即为两个图设置
ax.set_ylim(-6,6)
)。下面的代码是一个例子。dgiusagp2#
我也遇到了同样的问题,我所做的就是根据最小值和最大值的比值来改变y轴的范围。如果将y轴的比率设置为相同,则零点应相同。
这是我的第一个答案,所以我希望它足够好。
oknwwptz3#
我找到了this excellent library,它可以对齐轴并保持自动缩放。
安装
pip install mpl-axes-aligner
用法
输出
积分
这个包是由ryotuk开发的,上面的使用示例来自他的包的文档。
6psbrbz94#
这里有另一种方法,我认为它更通用。
enter image description here