matplotlib: 如何画不连续的坐标轴

文章目录

科研绘图时,有时候数据范围较大,我们需要忽略一些稳定没有变化的区别,留出更多的空间来展示变化的部分;或者个别数据非常大/小,如果和其他数据等比例画在一起,会导致我们丢失其他数据的细节。这时候就需要对坐标轴进行断开,忽略一些区间内的数据。

Y轴

TODO: 官方文档教程: https://matplotlib.org/stable/gallery/subplots_axes_and_figures/broken_axis.html

X轴

下面这个例子,将x轴截成了三段,忽略了两段不重要的数据,细节参考代码里的注释.

matplotlib: 如何画不连续的坐标轴

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")

上一篇:python 面向对象专题(十四):MetaClass使用


下一篇:matplotlib.pyplot.bar() plt.bar()