Matplotlib 双刻度共享原点
matplotlib是Python中最常用的数据可视化库之一,它可以帮助我们很方便地实现针对数据的各种图表展示。在绘制图表时,我们通常会需要使用两种不同的刻度,例如左侧使用y1轴,右侧使用y2轴,但两者共享同一个坐标原点的情况,本文将会详细介绍该如何实现。
阅读更多:Matplotlib 教程
问题分析
为了更好地理解问题,我们先来认识一下matplotlib中Figure、Axes和Axis的概念。
Figure:图形窗口,整个绘图区域。
Axes:实际图形的绘制区域,一个Figure可以包含多个Axes。
Axis:Axes中的x、y轴对象。
有了以上的认识,那么展示双刻度共享原点将会变得相对容易。
我们针对以下的数据进行展示:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 10, 0.5)
y1 = x**2
y2 = x*10
解决方案
方案一:Manually set shared y-axis bounds
我们可以采用plt.subplots()来新建一个画布,然后在其中创建两个Axes对象,left和right,设置共享的x轴,再通过参数调节两个轴的位置与大小。
代码如下:
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot(x, y1, 'g-')
ax2.plot(x, y2, 'b-')
# Set y-axis label
ax1.set_ylabel('y1-axis', color='g')
ax2.set_ylabel('y2-axis', color='b')
# Set y-axis range
# Both y-axes will be plotted with the same y-limits
ax1.set_ylim(0, 80)
ax2.set_ylim(0, 80)
# Set x-axis label
ax1.set_xlabel('x-axis')
plt.show()
需要注意的是:
ax1.twinx()可以使得实际图形绘制区域上方新建一个轴。- 入参中的
'g-'和'b-'分别是y1和y2的颜色和线条类型。 - 两个轴设置的高度需要一致。
方案二:Sharing by making the axes object
在方案一中可以注意到,我们手动设置的两个轴的美观度量,如刻度、大小、颜色等,需要自己调整一致,有些繁琐和影响美观。下面介绍更加简便的实现,直接通过matplotlib提供的参数实现双刻度共享原点。
示例代码如下:
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot(x, y1, 'g-')
ax2.plot(x, y2, 'b-')
ax1.set_xlabel('x-axis')
ax1.set_ylabel('y1-axis', color='g')
ax2.set_ylabel('y2-axis', color='b')
ax1.tick_params(axis='y', labelcolor='g')
ax2.tick_params(axis='y', labelcolor='b')
# Create offset transform by 5 points in x direction
# This will be used to adjust the second axis
offset = 5
new_fixed_axis = ax2.get_grid_helper().new_fixed_axis
ax2.axis['right'] = new_fixed_axis(loc='right', axes=ax2, offset=(offset, 0))
ax2.axis['right'].toggle(all=True)
plt.show()
主要解释如下:
ax1.tick_params(axis='y', labelcolor='g')和ax2.tick_params(axis='y', labelcolor='b')表示手动定义两个轴的刻度颜色。offset = 5定义了一个偏移量,将用于调整第二个轴。new_fixed_axis方法创建一个新的轴,axes=ax2表示该轴与ax2共享,offset=(offset, 0)表示该轴在x轴上移动offset个单位距离。
方案三:Sharing the same range
如果双刻度想要共享一个轴,即它们的取值范围相同,可以直接设置两个轴的范围相同。示例代码如下:
fig, ax = plt.subplots()
ax.plot(x, y1, 'g-')
ax2 = ax.twinx()
ax2.plot(x, y2, 'b-')
ax.set_xlabel('x-axis')
ax.set_ylabel('y1-axis', color='g')
ax2.set_ylabel('y2-axis', color='b')
ax2.set_yticks(np.linspace(ax2.get_yticks()[0], ax2.get_yticks()[-1], len(ax.get_yticks())))
plt.show()
ax2.set_yticks(np.linspace(ax2.get_yticks()[0], ax2.get_yticks()[-1], len(ax.get_yticks())))的含义是设置第二个轴的值域和第一个轴相同。
总结
通过以上的介绍,我们学会了如何在matplotlib中实现双刻度共享原点的问题。其中,方案一需要根据实际需求手动设置轴,相对比较繁琐;方案二则是通过matplotlib提供的方法,直接实现双刻度共享原点,适用范围广;方案三针对两个轴范围相同的情况,可以直接设置刻度值相同,相对最为简单。在实际使用时,可以根据具体的情况选择对应的方案,提高数据可视化的效率。
极客教程