Matplotlib:有没有 rcParams 方法来调整图例边框宽度?

Neu*_*tar 3 python matplotlib legend-properties

该站点显示了许多(全部?) rc 参数,可以通过matplotlibrc文件或在 Python 脚本中使用这些参数在 Matplotlib 图中进行调整matplotlib.rcParams[]。我看不出如何使用该站点中列出的参数来调整图例边框框的宽度。我知道可以“手动”更改框的线宽,即在脚本中(例如),但我希望找到一种使用matplotlib.rcParams[]或在matplotlibrc文件中设置它的方法。我怎么能这样做呢?

我之所以希望有一个自动化的、外部的(或者至少可以轻松复制粘贴的)是因为我有几个图形,用几个不同的 Python 脚本生成这几个图形,并且我希望有一种尽可能简单的方法来维护不同 Python 脚本中每个图形之间的标准外观。

在某些脚本中,我将图例称为 ,pyplot.legend()而在其他脚本中,我将其称为ax.legend()

Mad*_*ist 5

根据您想要执行的操作,实际上可以通过设置图例边框的宽度rcParams

长话短说

设置或patch.linewidth更好matplotlibrc的是,编写一个两行包装函数legend并在脚本中使用它。

长版

查看 的代码legend,您可以看到该框架存储为matplotlib.patched.FancyBBoxPatch对象,该对象是 的类型matplotlib.patches.PatchPatch对象从 获取其默认线宽matplotlib.rcParams['patch.linewidth']。这意味着如果您设置patch.linewidthmatplotlibrc图例边框的大小将会改变。

类似的修改将patch.edgecolor更改边框颜色,但patch.facecolor对于图例将被忽略。

以下是说明更改的代码示例,其中包含一些输出:

>>> import matplotlib as mpl
>>> from matplotlib import pyplot as plt
>>> mpl.rcParams['patch.linewidth']
1.0
>>> plt.plot((0, 1), label='a')[0].axes.legend()
<matplotlib.legend.Legend object at 0x7f6d7b0a0e48>
>>> mpl.rcParams['patch.linewidth'] = 15
>>> plt.plot((0, 1), label='a')[0].axes.legend()
<matplotlib.legend.Legend object at 0x7f6d7ae20908>
Run Code Online (Sandbox Code Playgroud)

法线图例

15px 线图例

这里明显的问题是,如果您在图表上绘制任何其他补丁,则默认线宽将被丢弃。当然,您可以通过“手动”将您创建的所有补丁的线宽更改回 1 来缓解这种情况。显然这不是一个最佳解决方案。

更好的方法

更好的解决方案是创建一个小脚本,您可以在所有图表生成脚本之间共享该脚本。以下是此类脚本的示例:

from matplotlib.axes import Axes

def add_legend(ax, *args, **kwargs):
    """
    Adds a legend to the specified axes, along with some common formatting. All additional arguments are the same as for `ax.legend`.
    """
    legend = _originalFn(ax, *args, **kwargs)
    legend.set_linewidth(15)
    return legend

if Axes.legend is not add_legend:
    _originalFn = Axes.legend
    Axes.legend = add_legend
Run Code Online (Sandbox Code Playgroud)

该脚本的结构使您无需add_legend手动调用。只需导入脚本子类,matplotlib.axes.Axes以便ax.legend(...)像以前一样调用会将默认图例边框宽度设置为 15 磅。

上面的脚本适用于调用ax.legendwhere axis an Axesinstance 和 on plt.legend,因为plt.legend实际上只是委托进行gca().legend一些额外的处理。

即使您的程序由导入共享脚本的多个脚本/模块组成,这种子类化机制也将起作用。这是因为 Python 在第一次之后实际上不会重新加载模块,而只会返回对它的引用,所有属性都完好无损。如果您开始使用,事情就会崩溃importlib.reload,但这只是一种非常遥远的可能性。