python画图|两个Y轴共享X轴

【1】引言

在前述学习中,对使用matplotlib模块输出图形已经非常熟练,但常见的画图方式并未穷尽,如两个Y轴共享X轴就没有探索过。

对此,我进行了一些学习,获得一些心得,在此和大家共享。

【2】官网教程

官网对两个Y轴共享X轴提供了详细解释和代码示例,可以通过下述链接直达:

https://matplotlib.org/stable/gallery/subplots_axes_and_figures/two_scales.html#sphx-glr-gallery-subplots-axes-and-figures-two-scales-py

为便于大家理解和阅读,我增添了代码注释。

【3】代码解读 

首先是引入画图模块和计算模块:matplotlib和numpy

import matplotlib.pyplot as plt #引入画图模块
import numpy as np #引入计算模块

然后定义自变量和因变量:

t = np.arange(0.01, 10.0, 0.01) #定义自变量
data1 = np.exp(t) #定义因变量
data2 = np.sin(2 * np.pi * t) #定义因变量

之后定义了要画图:

fig, ax1 = plt.subplots() #定义要画图

首先进行第一个图的定义:

fig, ax1 = plt.subplots() #定义要画图

color = 'tab:red' #设置颜色变量
ax1.set_xlabel('time (s)') #设置X轴标签
ax1.set_ylabel('exp', color=color) #设置Y轴标签
ax1.plot(t, data1, color=color) #输出图形
ax1.tick_params(axis='y', labelcolor=color) #设置Y轴颜色

然后进行第二个图的定义:

ax2 = ax1.twinx()  # instantiate a second Axes that shares the same x-axis

color = 'tab:blue'
ax2.set_ylabel('sin', color=color)  # we already handled the x-label with ax1 #设置Y轴标签
ax2.plot(t, data2, color=color) #输出图形
ax2.tick_params(axis='y', labelcolor=color) #输出图形

最后输出图形:

fig.tight_layout()  # otherwise the right y-label is slightly clipped #可以保证Y轴标签位置合理,不会和坐标轴重合
plt.show() #输出图形

图形输出结果为:

图1

【4】代码修改

在【3】中可以发现,ax1是用subplots()函数进行的定义,ax2是用ax1.twinx()函数完成的定义。

为此,最核心的函数就是ax1.twinx()。

为了测试该功能,修改ax定义程序为:

import matplotlib.pyplot as plt #引入画图模块
import numpy as np #引入计算模块

# Create some mock data
t = np.arange(0.01, 10.0, 0.01) #定义自变量
data1 = np.exp(t) #定义因变量
data2 = np.sin(2 * np.pi * t) #定义因变量

fig, ax = plt.subplots(2,1) #定义要画图

color = 'tab:red' #设置颜色变量
ax[0].set_xlabel('time (s)') #设置X轴标签
ax[0].set_ylabel('exp', color=color) #设置Y轴标签
ax[0].plot(t, data1, color=color) #输出图形
ax[0].tick_params(axis='y', labelcolor=color) #设置Y轴颜色

#ax2 = plt.subplots()  # instantiate a second Axes that shares the same x-axis

color = 'tab:blue'
ax[1].set_ylabel('sin', color=color)  # we already handled the x-label with ax1 #设置Y轴标签
ax[1].plot(t, data2, color=color) #输出图形
ax[1].tick_params(axis='y', labelcolor=color) #输出图形

fig.tight_layout()  # otherwise the right y-label is slightly clipped #可以保证Y轴标签位置合理,不会和坐标轴重合
plt.show() #输出图形

上述代码的ax定义部分已经全部修改为subplots()输出:

fig, ax = plt.subplots(2,1) #定义要画图

color = 'tab:red' #设置颜色变量
ax[0].set_xlabel('time (s)') #设置X轴标签
ax[0].set_ylabel('exp', color=color) #设置Y轴标签
ax[0].plot(t, data1, color=color) #输出图形
ax[0].tick_params(axis='y', labelcolor=color) #设置Y轴颜色

#ax2 = plt.subplots()  # instantiate a second Axes that shares the same x-axis

color = 'tab:blue'
ax[1].set_ylabel('sin', color=color)  # we already handled the x-label with ax1 #设置Y轴标签
ax[1].plot(t, data2, color=color) #输出图形
ax[1].tick_params(axis='y', labelcolor=color) #输出图形

此时的输出结果为:

图2

至此,测试结果很清晰,使用twinx()函数可以实现2个Y轴共享X轴。

【5】代码改写

【5.1】 ax.twinx()函数测试

进一步测试,引入第三个变量:

data3 = 12*np.cos(2 * np.pi * t) #定义因变量

在此基础上,有两种共享Y轴的方式,一种是ax3 = ax1.twinx(),一种是ax3 = ax2.twinx(),第一种的完整代码为:

import matplotlib.pyplot as plt #引入画图模块
import numpy as np #引入计算模块

# Create some mock data
t = np.arange(0.01, 10.0, 0.01) #定义自变量
data1 = np.exp(t) #定义因变量
data2 = np.sin(2 * np.pi * t) #定义因变量
data3 = 12*np.cos(2 * np.pi * t) #定义因变量

fig, ax1 = plt.subplots() #定义要画图

color = 'tab:red' #设置颜色变量
ax1.set_xlabel('time (s)') #设置X轴标签
ax1.set_ylabel('exp', color=color) #设置Y轴标签
ax1.plot(t, data1, color=color) #输出图形
ax1.tick_params(axis='y', labelcolor=color) #设置Y轴颜色

ax2 = ax1.twinx()  # instantiate a second Axes that shares the same x-axis

color = 'tab:blue'
ax2.set_ylabel('sin', color=color)  # we already handled the x-label with ax1 #设置Y轴标签
ax2.plot(t, data2, color=color) #输出图形
ax2.tick_params(axis='y', labelcolor=color) #输出图形

ax3 = ax1.twinx()  # instantiate a second Axes that shares the same x-axis

color = 'tab:green'
ax3.set_ylabel('cos', color=color)  # we already handled the x-label with ax1 #设置Y轴标签
ax3.plot(t, data3, color=color) #输出图形
ax3.tick_params(axis='y', labelcolor=color) #输出图形

fig.tight_layout()  # otherwise the right y-label is slightly clipped #可以保证Y轴标签位置合理,不会和坐标轴重合
plt.show() #输出图形

对应输出结果为:

图3

可见共享X轴的两个Y轴按照各自的比例,将图像放大,铺满了坐标轴。

第二种方式的完整代码为:

import matplotlib.pyplot as plt #引入画图模块
import numpy as np #引入计算模块

# Create some mock data
t = np.arange(0.01, 10.0, 0.01) #定义自变量
data1 = np.exp(t) #定义因变量
data2 = np.sin(2 * np.pi * t) #定义因变量
data3 = 12*np.cos(2 * np.pi * t) #定义因变量

fig, ax1 = plt.subplots() #定义要画图

color = 'tab:red' #设置颜色变量
ax1.set_xlabel('time (s)') #设置X轴标签
ax1.set_ylabel('exp', color=color) #设置Y轴标签
ax1.plot(t, data1, color=color) #输出图形
ax1.tick_params(axis='y', labelcolor=color) #设置Y轴颜色

ax2 = ax1.twinx()  # instantiate a second Axes that shares the same x-axis

color = 'tab:blue'
ax2.set_ylabel('sin', color=color)  # we already handled the x-label with ax1 #设置Y轴标签
ax2.plot(t, data2, color=color) #输出图形
ax2.tick_params(axis='y', labelcolor=color) #输出图形

ax3 = ax2.twinx()  # instantiate a second Axes that shares the same x-axis

color = 'tab:green'
ax3.set_ylabel('cos', color=color)  # we already handled the x-label with ax1 #设置Y轴标签
ax3.plot(t, data3, color=color) #输出图形
ax3.tick_params(axis='y', labelcolor=color) #输出图形

fig.tight_layout()  # otherwise the right y-label is slightly clipped #可以保证Y轴标签位置合理,不会和坐标轴重合
plt.show() #输出图形

对应输出结果为:

图4

由图4可见,ax2对应的Y轴数据自动移动到了左侧。

也就是:

ax1.twinx()时,ax1的Y值会出现在左侧Y轴;ax2.twinx()时,ax2的Y值会出现在左侧Y轴。

【5.2】 自变量范围扩大测试

进一步测试,设置新自变量:

n = np.arange(10.0,20.0,0.01) #定义新自变量

对应设置新因变量:

data3 = np.sin(2 * np.pi * n) #定义新因变量

此处采用ax1.twinx()进行X轴共享,获得的输出图形为:

图5

由图5可见,共享X轴可以在自变量取值不重合的前提下实施。

但需注意的是,如果新自变量data3在输出的时候,Y轴设置名称是其他,比如“cos”,就会出现cos和sin的重影。

图6

由图6可见,出现了Y轴标签的重影。

此时的完整代码为:

import matplotlib.pyplot as plt #引入画图模块
import numpy as np #引入计算模块

# Create some mock data
t = np.arange(0.01, 10.0, 0.01) #定义自变量
n = np.arange(10.0,20.0,0.01) #定义新自变量
data1 = np.exp(t) #定义因变量
data2 = np.sin(2 * np.pi * t) #定义因变量
data3 = np.sin(2 * np.pi * n) #定义新因变量

fig, ax1 = plt.subplots() #定义要画图

color = 'tab:red' #设置颜色变量
ax1.set_xlabel('time (s)') #设置X轴标签
ax1.set_ylabel('exp', color=color) #设置Y轴标签
ax1.plot(t, data1, color=color) #输出图形
ax1.tick_params(axis='y', labelcolor=color) #设置Y轴颜色

ax2 = ax1.twinx()  # instantiate a second Axes that shares the same x-axis

color = 'tab:blue'
ax2.set_ylabel('sin', color=color)  # we already handled the x-label with ax1 #设置Y轴标签
ax2.plot(t, data2, color=color) #输出图形
ax2.tick_params(axis='y', labelcolor=color) #输出图形

ax3 = ax1.twinx()  # instantiate a second Axes that shares the same x-axis

color = 'tab:green'
ax3.set_ylabel('cos', color=color)  # we already handled the x-label with ax1 #设置Y轴标签
ax3.plot(n, data3, color=color) #输出图形
ax3.tick_params(axis='y', labelcolor=color) #输出图形
ax3.set_title('Y share X')
fig.tight_layout()  # otherwise the right y-label is slightly clipped #可以保证Y轴标签位置合理,不会和坐标轴重合
plt.show() #输出图形

【6】总结

学习了两个Y轴共享X轴的基础教程,尝试探索了3个Y轴共享X轴。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值