如何为Matplotlib 2×2子图的每一列添加通用legend?
为Matplotlib 2×2子图的每一列添加通用标注
先贴出原绘图代码:
import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 2 * np.pi, 400) y = np.sin(x ** 2) fig, axs = plt.subplots(2, 2) axs[0, 0].plot(x, y) axs[0, 0].set_title('Axis [0, 0]') axs[0, 1].plot(x, y, 'tab:orange') axs[0, 1].set_title('Axis [0, 1]') axs[1, 0].plot(x, -y, 'tab:green') axs[1, 0].set_title('Axis [1, 0]') axs[1, 1].plot(x, -y, 'tab:red') axs[1, 1].set_title('Axis [1, 1]') for ax in axs.flat: ax.set(xlabel='x-label', ylabel='y-label') # Hide xlabels & and tick labels for top plots. for ax in axs.flat: ax.label_outer()
需求是给左列加time-domain、右列加frequency-domain的通用标注,这里提供两种实用方法:
方法一:直接在画布上添加文本标注
用fig.text()在画布的归一化坐标位置添加文本,调整坐标让它刚好对齐整列的中心:
修改后的完整代码:
import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 2 * np.pi, 400) y = np.sin(x ** 2) fig, axs = plt.subplots(2, 2) axs[0, 0].plot(x, y) axs[0, 0].set_title('Axis [0, 0]') axs[0, 1].plot(x, y, 'tab:orange') axs[0, 1].set_title('Axis [0, 1]') axs[1, 0].plot(x, -y, 'tab:green') axs[1, 0].set_title('Axis [1, 0]') axs[1, 1].plot(x, -y, 'tab:red') axs[1, 1].set_title('Axis [1, 1]') for ax in axs.flat: ax.set(xlabel='x-label', ylabel='y-label') # Hide xlabels & and tick labels for top plots. for ax in axs.flat: ax.label_outer() # 添加列的通用标注,坐标是画布归一化范围(0-1),可根据布局微调 fig.text(0.22, 0.95, 'time-domain', ha='center', fontsize=12, fontweight='bold') fig.text(0.78, 0.95, 'frequency-domain', ha='center', fontsize=12, fontweight='bold') plt.show()
这里的0.22和0.78是x轴归一化坐标,你可以根据自己子图的间距微调,确保文本对齐对应列的中心。
方法二:用虚拟元素创建图例式标注
如果需要带颜色块的图例样式标注,可以创建虚拟的绘图元素,再在画布对应位置添加图例:
完整代码如下:
import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Patch x = np.linspace(0, 2 * np.pi, 400) y = np.sin(x ** 2) fig, axs = plt.subplots(2, 2) axs[0, 0].plot(x, y) axs[0, 0].set_title('Axis [0, 0]') axs[0, 1].plot(x, y, 'tab:orange') axs[0, 1].set_title('Axis [0, 1]') axs[1, 0].plot(x, -y, 'tab:green') axs[1, 0].set_title('Axis [1, 0]') axs[1, 1].plot(x, -y, 'tab:red') axs[1, 1].set_title('Axis [1, 1]') for ax in axs.flat: ax.set(xlabel='x-label', ylabel='y-label') # Hide xlabels & and tick labels for top plots. for ax in axs.flat: ax.label_outer() # 创建虚拟的图例元素,颜色可以和对应列的线条匹配 left_legend = [Patch(facecolor='blue', label='time-domain')] right_legend = [Patch(facecolor='tab:orange', label='frequency-domain')] # 在画布对应位置添加图例,bbox_to_anchor微调位置 fig.legend(handles=left_legend, loc='upper left', bbox_to_anchor=(0.1, 0.95)) fig.legend(handles=right_legend, loc='upper right', bbox_to_anchor=(0.9, 0.95)) plt.show()
这种方法适合需要用颜色对应列内容的场景,bbox_to_anchor参数可以调整图例的位置,让它精准对齐列的上方。
内容的提问来源于stack exchange,提问作者Amina Umar
相关产品推荐
相关产品推荐

