文章目录
科研绘图时,有时候数据范围较大,我们需要忽略一些稳定没有变化的区别,留出更多的空间来展示变化的部分;或者个别数据非常大/小,如果和其他数据等比例画在一起,会导致我们丢失其他数据的细节。这时候就需要对坐标轴进行断开,忽略一些区间内的数据。
Y轴
TODO: 官方文档教程: https://matplotlib.org/stable/gallery/subplots_axes_and_figures/broken_axis.html
X轴
下面这个例子,将x轴截成了三段,忽略了两段不重要的数据,细节参考代码里的注释.
import matplotlib.pyplot as plt
import numpy as np
import random
x1 = list(range(0, 50, 5))
y1 = [random.randint(0, 20) for x in range(len(x1))]
x2 = list(range(200, 400, 10))
y2 = [random.randint(10, 18) for x in range(len(x2))]
x3 = list(range(500, 580, 5))
y3 = [random.randint(5, 25) for x in range(len(x3))]
base = np.max(x1) - np.min(x1)
kw = [1, (np.max(x2) - np.min(x2))/base, (np.max(x3) - np.min(x3))/base] # 这里的比例非常重要,用于调整刻度,使得刻度均匀
fig, (ax0, ax1, ax2) = plt.subplots(1, 3, sharey=True, gridspec_kw={'width_ratios': kw})
fig.tight_layout(pad=4)
plt.subplots_adjust(wspace = 0.08)
fig.text(0.5, 0.04, 'XXX', ha='center', fontsize=25)
fig.text(0.025, 0.5, 'YYY', va='center', rotation='vertical', fontsize=25)
ax0.plot(x1, y1)
ax1.plot(x2, y2)
ax2.plot(x3, y3)
ax0.set_xlim(-0.5, np.max(x1)+2)
ax0.set_ylim(0, 30)
ax1.set_xlim(np.min(x2)-2, np.max(x2)+2)
ax1.set_ylim(0, 30)
ax2.set_xlim(np.min(x3)-2, np.max(x3)+2)
ax2.set_ylim(0, 30)
ax0.spines['right'].set_visible(False)
ax1.spines['left'].set_visible(False)
ax1.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
d = .015
kwargs = dict(transform=ax0.transAxes, color='k', clip_on=False)
ax0.plot((1-d,1+d), (-d,+d), **kwargs)
ax0.plot((1-d,1+d),(1-d,1+d), **kwargs)
kwargs.update(transform=ax1.transAxes)
ax1.plot((-d/kw[1],+d/kw[1]), (1-d,1+d), **kwargs) # 注意这里的斜率需要与ax0保持一致,以下也是如此
ax1.plot((-d/kw[1],+d/kw[1]), (-d,+d), **kwargs)
ax1.plot((1-d/kw[1],1+d/kw[1]), (-d,+d), **kwargs)
ax1.plot((1-d/kw[1],1+d/kw[1]), (1-d,1+d), **kwargs)
kwargs.update(transform=ax2.transAxes)
ax2.plot((-d/kw[2],+d/kw[2]), (1-d,1+d), **kwargs)
ax2.plot((-d/kw[2],+d/kw[2]), (-d,+d), **kwargs)
ax0.yaxis.tick_left()
ax1.tick_params(labelleft='off')
ax1.get_yaxis().set_visible(False)
ax2.tick_params(labelleft='off')
ax2.yaxis.tick_right()
plt.savefig("img.pdf")