如何将 Matplotlib 图例的行与 2 列对齐?

如何将 Matplotlib 图例的行与 2 列对齐?

在使用 Matplotlib 绘图时,我们通常需要添加图例来说明各种线条或点的含义。然而,在一些情况下,图例的显示效果可能并不是很美观,由于文本长度差异较大、图例过多、位置不当等因素,导致图例显示效果不尽如人意,影响了图像的美观性和表现力。本篇文章将介绍如何将 Matplotlib 图例的行与 2 列对齐,以美化图像。

Matplotlib 图例的手动布局

Matplotlib 中的图例可以通过 legend 方法来添加。在默认情况下,图例的布局取决于图例中的元素数量、元素名称长度、位置等属性。在一些情况下,建议手动对图例进行布局,以达到更美观的效果。

具体实现方法是使用 legend 方法中的 ncolmode 参数,它们分别用于设置图例的列数和对齐方式。其中,mode 参数有三种可选值:expandextendraise,分别表示自适应、伸展和默认对齐方式。

下面是一个设置列数为 2、对齐方式为默认的实例程序:

import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
y = [1, 4, 2, 3]

plt.plot(x, y, 'r', label='line 1')

x1 = [1, 2, 3, 4]
y1 = [2, 5, 3, 4]

plt.plot(x1, y1, 'b', label='line 2')

x2 = [1, 2, 3, 4]
y2 = [3, 6, 4, 5]

plt.plot(x2, y2, 'g', label='line 3')

plt.legend(loc='lower right', ncol=2, mode=None, borderaxespad=0.)
plt.show()

从结果图中可以看到,图例中的元素被自动横向排列,但是不是很美观。下面我们将手动调整对齐方式。

其中 mode 参数修改为 extend,此时,会在每个条目的前面添加一个小符号,并将整个图例水平延伸到整个图像。修改 ncol 的值为 1。

plt.legend(loc='lower right', ncol=1, mode='expand', borderaxespad=0.)
plt.show()

可以看到,此时图例被水平拉伸了,但是变得更加美观了。如果想要将图例行与 2 列对齐,则需要进行一些

将 Matplotlib 图例的行与 2 列对齐

首先,我们可以先将图例属性获取出来,计算出图例文本中最长字符长度,对每一个图例文本前面补齐相应数量的空格,这样就能保证每行文本对齐。

程序的核心代码如下所示:

import matplotlib.pyplot as plt

def make_legend(ncol=1, loc='best', bbox_to_anchor=None, mode=None, borderaxespad=0.1, fontsize=13, pad=0.2):
    handles, labels = plt.gca().get_legend_handles_labels()
    if any(handles):
        fig = handles[0].figure
        if bbox_to_anchor is None:
            bbox_to_anchor = (0., 1.02, 1., .102)
    else:
        return None   
    lgd =fig.legend(handles, labels, loc=loc, borderaxespad=borderaxespad, bbox_to_anchor=bbox_to_anchor, ncol=ncol, mode=mode, fontsize=fontsize, title=None, borderpad=None, labelspacing=None, handlelength=None, handletextpad=None, markerscale=None, frameon=True)

    # 计算每个标签中的最大字符数
    max_label_len = max([len(label) for label in labels])

    # 计算每个标签前面应该添加的空格数
    space_count = (max_label_len // 8 + 1) * 8 - max_label_len

    # 添加前导空格来对齐每个标签
    for i, label in enumerate(labels):
        labels[i] = ' ' * space_count + label

    # 更新图例
    fig.legend(handles, labels, loc=loc, borderaxespad=borderaxespad, bbox_to_anchor=bbox_to_anchor, ncol=ncol, mode=mode, fontsize=fontsize, title=None, borderpad=None, labelspacing=None, handlelength=None, handletextpad=None, markerscale=None, frameon=True)

    # 调整图像布局
    fig.tight_layout(pad=pad)

    return lgd

在程序中,我们新定义了一个函数 make_legend,其中 handleslabelsplt.gca().get_legend_handles_labels() 方法返回的矩阵,表示图例的所有元素及其标签。ncol 是设置图例列数的参数,默认为 1,loc 是设置图例位置的参数,默认为最佳位置,bbox_to_anchor 是控制图例位置及占比的参数,默认为 (0., 1.02, 1., .102)mode 是设置图例元素对齐方式的参数,此处需要设置为 extendborderaxespad 是控制图例框与坐标轴之间距离的参数,默认为 0.1, fontsize 是图例字体大小,pad 用于设置子图之间的间距大小。

其中最关键的步骤是通过计算每个标签前应添加的空格数和更新标签,来实现对齐。计算每个标签前应添加的空格数时,我们将最大字符数进行四舍五入后除以 8,再加 1,得到的结果再乘以 8,最后减去字符串长度即可。更新标签后,我们再次调用 fig.legend 方法来更新图例。

下面是使用 make_legend 函数实现的示例程序:

import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
y = [1, 4, 2, 3]

plt.plot(x, y, 'r', label='line 1')

x1 = [1, 2, 3, 4]
y1 = [2, 5, 3, 4]

plt.plot(x1, y1, 'b', label='line 2')

x2 = [1, 2, 3, 4]
y2 = [3, 6, 4, 5]

plt.plot(x2, y2, 'g', label='line 3')

make_legend(ncol=2, mode='expand', borderaxespad=0.1)
plt.show()

可以看到,此时图例中的元素水平排列,而且每行都以相同的长度对齐了。如果您想要调整图例的位置和对齐方式,只需要调用 make_legend 函数,并传入合适的参数即可。

结论

本文主要介绍了如何将 Matplotlib 图例的行与 2 列对齐。通过手动调整对齐方式和编写对齐函数,可以大大提高图像美观度和表现力。当然,如果您需要更复杂的图例布局,还可以调用 Matplotlib 中其它相关功能来实现,比如使用 gridspec 模块等。总之,无论采用何种方法,只要最终效果符合需求,就是一种好的图像展示方式。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程