# 共享子图的坐标轴

# 在同一画布中,若子图与其他子图的同方向的坐标轴相同,则可以共享子图之间同方向的坐标轴。下面将对相邻和非相邻子图之间共享坐标轴的方式进行详细介绍。

# 共享相邻子图的坐标轴

# 当 pyplot 使用subplots() 函数绘制子图时,可以通过 sharex 或 sharey 参数控制是否共享 X 轴或 y 轴。sharex 或 sharey 参数支持 False 或'none'、True 或 'all'、'row'、'col' 中任一取值,关于这些取值的含义如下。

# · True 或 'all' :表示所有子图之间共享 x 轴或 y 轴。<br.>· False 或 'none' :表示所有子图之间不共享 x 轴或 y 轴。
· 'row' :表示每一行的子图之间共享 x 轴或 y 轴。
· 'col' :表示每一列的子图之间共享 x 轴或 y 轴。

# 下面以同一画布中 2 行 2 列的子图为例,分别展示 shaipx 参数不同取值的效果,如图5-11 所示。

# 例如,将画布规划成 2x2 的矩阵区域,依次在每个区域中绘制子图,每一列子图之间共享 x 轴,示例代码如下 :

In [7]:
%matplotlib auto
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['axes.unicodejriinus'] = False
x1 = np.linspace(0, 2*np.pi, 400)
x2 = np.linspace(0.01, 10, 100)
x3 = np.random.rand(10)
x4 = np.arange(0, 6, 0.5)
y1 = np.cos(x1**2)
y2 = np.sin(x2)
y3 = np.linspace(0, 3, 10)
y4 = np.power(x4, 3)
# 共享每一列子图之间的 x 轴
fig, ax_arr = plt.subplots(2, 2, sharex='col')
ax1 = ax_arr[0, 0]
ax1.plot(x1, y1)
ax2 = ax_arr[0, 1]
ax2.plot(x2, y2)
ax3 = ax_arr[1, 0]
ax3.scatter(x3, y3)
ax4 = ax_arr[1, 1]
ax4.scatter(x4, y4)
plt.show()

# 运行程序,效果如图 5-12 所示。

# 共享非相邻子图的坐标轴

# 当 pyplot 使用 subplot() 函数绘制子图时,也可以将代表其他子图的变量赋值给 sharex 或 sharey 参数,此时可以共享非相邻子图之间的坐标轴。
例如,将画布规划成 2x2 的矩阵区域,之后在索引为 1 的区域中先绘制一个子图,再次将画布规划成 2x2 的矩阵区域,之后在索引为 4 的区域中绘制另一个子图,后绘制的子图与先绘制的子图之间共享 x 轴,代码如下。

In [8]:
%matplotlib auto
x1 = np.linspace(0, 2*np.pi, 400)
y1 = np.cos(x1**2)
x2 = np.linspace(0.01, 10, 100)
y2 = np.sin(x2)
ax_one = plt.subplot(221)
ax_one.plot(x1, y1)
# 共享子图 ax_one 和 ax_two 的 x 轴
ax_two = plt.subplot(224, sharex=ax_one)
ax_two.plot(x2, y2)

# 运行程序,效果如图 5-13 所示。

# 多学一招:共享同一子图的坐标轴

# 单个子图也可以共享坐标轴,它通常会将 y 轴作为一组图形参考的坐标轴,将右侧的垂直坐标轴作为另一组图形参考的坐标轴。matplotlib 中提供了 twinx() 函数共享同一子图的坐标轴。twinx() 函数的语法格式如下 :
twinx(ax=None)
# 该函数的 ax 参数表示要共享坐标轴的子图。
twinx() 函数会返回共享 x 轴的新绘图区域(Axes 类的对象), 新创建的绘图区域具有不可见的 x 轴和独立的、位于右侧的 y 轴。例如,共享某个子图中的坐标轴,代码如下:
fig, ax = plt.subplots()
ax__right = ax.twinx()

# 实例4:某地区全年平均气温与降水量、蒸发量的关系

# 气候是地球上某一地区大气的多年平均状况,主要有光照、气温、降水等气候要素,其中气温、降水是反映一个地区气候特性的重要指标。已知某地区全年的平均气温、降水量、蒸发量如表 5-4 所示。

# 根据表 5-4 的数据,将“月份”一列的数据作为 x 轴的刻度标签,将“平均气温”“降水量”“蒸发量”三列的数据作为 y 轴的数据,在同一绘图区域中分别绘制反映平均气温、降水量、蒸发量关系的图表,具体代码如下。

In [9]:
# 04_temperature_precipitation_evaporation
import as numpy np
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
month_x = np.arange(1, 13, 1)
# 平均气温
data_tem = np.array([2.0, 2.2, 3.3, 4.5, 6.3, 10.2,
                     20.3, 33.4, 23.0, 16.5, 12.0, 6.2])
# 降水量
data_precipitation = np.array([2.6, 5.9, 9.0, 26.4, 28.7, 70.7,
                               175.6, 182.2, 48.7, 18.8, 6.0, 2.3])
# 蒸发量
data_evaporation = np.array([2.0, 4.9, 7.0, 23.2, 25.6, 76.7,
                             135.6, 162.2, 32.6, 20.0, 6.4, 3.3])
fig, ax = plt.subplots()
bar_ev = ax.bar(month_x, data_evaporation, color='orange',
                tick_label=['1月', '2月', '3月', '4月', '5月', '6月',
                            '7月', '8月', '9月', '10月', '11月', '12月'])
bar_pre = ax.bar(month_x, data_precipitation,
                 bottom=data__evaporation, color='green')
ax.set_ylabel('水量(ml)')
ax.set_title('平均气温与降水量、蒸发量的关系')
ax_right = ax.twinx()
line = ax_right.plot(month_x, data_tem, 'o-m')
ax_ right.set_ylabel('气温 (S^\circSC)')
# 添加图例
plt.legend([bar_ev, bar_pre, line[0]], ['蒸发量', '降水量', '平均气温'],
            shadow=True, fancybox=True)
plt.show()

# 运行程序,效果如图 5-14 所示。

# 图 5-14 中,折线代表全年气温的趋势,参照右方的垂直坐标轴;绿色、橙色的柱形分别代表全年降水量、全年蒸发量,参照左方的垂直坐标轴,它们之间共享 x 轴。由图5-14可知,随着气温的升高,蒸发量也有所增加,降水量与蒸发量大致相等。