Matplotlib:是否有rcParams方式来调整图例边框宽度?

时间:2016-07-13 18:15:02

标签: python matplotlib legend-properties

This site显示了许多(所有?)rc参数,可以通过matplotlibrc文件或在Python脚本中使用matplotlib.rcParams[]在Matplotlib图中进行调整。我无法使用该站点中列出的参数调整图例边框的宽度。我知道可以“手动”更改框的线宽,即在脚本(for example)中,但我希望有一种方法可以使用matplotlib.rcParams[]或在matplotlibrc个文件。我怎么能这样做?

我之所以想要拥有一个自动的,外部的(或者至少是易于复制和可管理的)的原因是因为我有几个数字,有几个不同的Python脚本产生这几个数字,我想像一个简单的方式可以在不同的Python脚本之间保持每个图之间的标准外观。

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

1 个答案:

答案 0 :(得分:4)

根据您的目的,实际上可以通过rcParams设置图例边框的宽度。

<强> TL; DR

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

长版

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

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>

normal line legend

15px line legend

这里显而易见的问题是,如果您在图表上绘制任何其他补丁,则会抛弃默认线宽。您当然可以通过“手动”将所创建的所有修补程序的线宽更改回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

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

上面的脚本适用于ax.legend ax Axes实例和plt.legend实体的调用,因为plt.legend实际上只委托给gca().legend 1}}进行一些额外的处理。

即使您的程序包含多个导入共享脚本的脚本/模块,此子类化机制也将起作用。这是因为Python在第一次之后实际上不会重新加载模块,而是只返回对它的引用,所有属性都保持不变。如果你开始使用importlib.reload,情况就会破裂,但这只是一种非常遥远的可能性。