如何在创建matplotlib图例后对其进行修改?

时间:2014-05-15 22:26:46

标签: python matplotlib legend

我可以访问图形实例fig = pylab.gcf()。我知道在这个图中有一个图例,我可以通过myLegend = fig.gca().legend_访问它。现在我想更改图例的属性。其中一些我可以通过像myLegend.set_frame_on(True)这样的设置者访问。

创建图例时,它接受许多关键字参数:

  

class matplotlib.legend.Legend(parent,handles,labels,loc = None,   numpoints = None,markerscale = None,scatterpoints = None,   scatteryoffsets = None,prop = None,fontsize = None,borderpad = None,   labelspacing = None,handlelength = None,handleheight = None,   handletextpad = None,borderaxespad = None,columnspacing = None,ncol = 1,   mode = None,fancybox = None,shadow = None,title = None,framealpha = None,   bbox_to_anchor =无,bbox_transform =无,frameon =无,   handler_map =无)

如何在创建图例后修改图例中的所有关键字参数?

其中一个问题是numpoints(图例中的标记数量,默认值为2)。以下是我想要更改它的示例:

这显示了我想要编程的方式

import pylab
pylab.plot(0,0,'ro', label = 'one point')
pylab.legend(loc = "lower left")
# no modifications above this line
setattr(pylab.gcf().gca().legend_, 'numpoints',1)
pylab.show()

这表明我希望它看起来像

import pylab
pylab.plot(0,0,'ro', label = 'one point')
pylab.legend(numpoints = 1, loc = "lower left")
pylab.show()

我已经解决了源代码,有一个numpoint变量被更改,但大写不会更新到屏幕。我错过了什么?

4 个答案:

答案 0 :(得分:3)

我编写了一个函数modify_legend,它在创建后修改了一个图例。它基本上从已创建的图例中读取所有参数,使用您提供的键值参数更新它,并再次使用所有可能的参数调用legend(...)

然后您的问题将通过以下方式解决:

import pylab
pylab.plot(0,0,'ro', label = 'one point')
pylab.legend(loc = "lower left")

modify_legend(numpoints = 1)

pylab.show()

以下是modify_legend的代码:

def modify_legend(**kwargs):
    import matplotlib as mpl

    l = mpl.pyplot.gca().legend_

    defaults = dict(
        loc = l._loc,
        numpoints = l.numpoints,
        markerscale = l.markerscale,
        scatterpoints = l.scatterpoints,
        scatteryoffsets = l._scatteryoffsets,
        prop = l.prop,
        # fontsize = None,
        borderpad = l.borderpad,
        labelspacing = l.labelspacing,
        handlelength = l.handlelength,
        handleheight = l.handleheight,
        handletextpad = l.handletextpad,
        borderaxespad = l.borderaxespad,
        columnspacing = l.columnspacing,
        ncol = l._ncol,
        mode = l._mode,
        fancybox = type(l.legendPatch.get_boxstyle())==mpl.patches.BoxStyle.Round,
        shadow = l.shadow,
        title = l.get_title().get_text() if l._legend_title_box.get_visible() else None,
        framealpha = l.get_frame().get_alpha(),
        bbox_to_anchor = l.get_bbox_to_anchor()._bbox,
        bbox_transform = l.get_bbox_to_anchor()._transform,
        frameon = l._drawFrame,
        handler_map = l._custom_handler_map,
    )

    if "fontsize" in kwargs and "prop" not in kwargs:
        defaults["prop"].set_size(kwargs["fontsize"])

    mpl.pyplot.legend(**dict(defaults.items() + kwargs.items()))

关于代码的说明:

  • 可以从Legend对象轻松读取某些参数,其他参数(如titlefancybox)需要一些“艺术”。您可以查看matplotlib.legend.Legend.__init__,了解其完成方式和原因。
  • fontsize参数的额外条件用于在最初使用prop创建图例时覆盖字体大小,因为prop通常会覆盖fontsize。< / LI>
  • 我没有测试所有的情况,因为我没有太多时间(特别是bbox_to_anchorbbox_transform - 参数),所以请随意尝试并改进代码:)

答案 1 :(得分:2)

您可以使用正确的关键字/参数再次使用命令pylab.legend。这将修改现有的图例,而不是创建新的图例。你找到你的例子,略有修改。

import pylab
pylab.plot(0,0,'ro', label = 'one point')
pylab.legend(loc = "lower left")
# Change the number of markers shown in the legend
pylab.legend(numpoints = 1, loc = "lower left")

pylab.show()

希望它有所帮助。

答案 2 :(得分:1)

您在图例中看到的实际上是Line2D。在创建该行之后更改numpoints将不会更新所述行,因此您必须获取Line2D对象的句柄并手动删除其中一个点:

import pylab
pylab.plot(0,0,'ro', label = 'one point')
legend = pylab.legend(loc = "lower left")
markers = legend.get_children()[0].get_children()[1].get_children()[0].get_children()[0].get_children()[0].get_children()[1]
markers.set_data(map(pylab.mean, markers.get_data()))
pylab.show()

get_children()链是必需的,因为matplotlib将线包裹在几层水平和垂直包中。上面的代码片段应该足以为您提供一般性的想法,但在实际应用程序中,获取句柄的一种更好的方法是遵循the legend guide's hint on legend handlers并使用存储该行的自定义HandlerLine2D一些时尚。

答案 3 :(得分:-1)

如果这是我,我会把它放到另一个文本文件中,以便这样做,因为它更容易更改和跟踪,特别是如果你之前和之后有很多代码。

要打开要写入的文件,我们将第二个参数设置为&#34; w&#34;而不是&#34; r&#34;。(fobj = open("ad_lesbiam.txt", "r"))为了将数据实际写入此文件,我们使用文件句柄对象的write()方法。

让我们从一个非常简单明了的例子开始:

fh = open("example.txt", "w")
fh.write("To write or not to write\nthat is the question!\n")
fh.close()

特别是如果您要写入文件,则永远不要忘记再次关闭文件句柄。否则,您将面临数据不一致状态的风险。

您经常会找到用于读取和写入文件的with语句。优点是在with完成执行后缩进块之后文件将自动关闭:

with open("example.txt", "w") as fh:
    fh.write("To write or not to write\nthat is the question!\n")

我们的第一个例子也可以用with语句重写:

with open("ad_lesbiam.txt") as fobj:
    for line in fobj:
        print(line.rstrip())

同时阅读和写作的例子:

fobj_in = open("ad_lesbiam.txt")
fobj_out = open("ad_lesbiam2.txt","w")
i = 1
for line in fobj_in:
    print(line.rstrip())
    fobj_out.write(str(i) + ": " + line)
    i = i + 1
fobj_in.close()
fobj_out.close()

FYI。输入文本文件的每一行都以其行号

为前缀