Python 创建matplotlib图例后如何修改它?

Python 创建matplotlib图例后如何修改它?,python,matplotlib,legend,Python,Matplotlib,Legend,我可以访问figure实例fig=pylab.gcf()。我知道在这个图中有一个图例,我可以通过myLegend=fig.gca().legend\uuu访问它。现在我想更改图例的属性。其中一些我可以通过设置器访问,比如myLegend.set\u frame\u on(True) 创建图例时,它接受多个关键字参数: 类matplotlib.legend.legend(父级、句柄、标签、loc=None、, numpoints=None,markerscale=None,scatterpoint

我可以访问figure实例
fig=pylab.gcf()
。我知道在这个图中有一个图例,我可以通过
myLegend=fig.gca().legend\uuu
访问它。现在我想更改图例的属性。其中一些我可以通过设置器访问,比如
myLegend.set\u frame\u on(True)

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

类matplotlib.legend.legend(父级、句柄、标签、loc=None、, numpoints=None,markerscale=None,scatterpoints=None, 散点偏移=无,属性=无,fontsize=无,borderpad=无, labelspacing=None,handlelength=None,HandleLight=None, handletextpad=None,borderaxespad=None,ColumnSpacting=None,ncol=1, mode=None,fancybox=None,shadow=None,title=None,framealpha=None, bbox\u to\u anchor=None,bbox\u transform=None,frameon=None, 处理程序(映射=无)

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

其中一个问题是
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变量已更改,但大写字母未更新到屏幕。我遗漏了什么?

您在图例中看到的实际上是一个
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()。上面的代码片段应该足以让您大致了解情况,但在实际应用程序中,获取句柄的更好方法是遵循并使用定制的
HandlerLine2D
,它以某种方式存储该行。

您可以再次使用命令
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()

希望能有所帮助。

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

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

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

modify_legend(numpoints = 1)

pylab.show()
以下是
修改图例的代码:

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()))
守则注释:

  • 一些参数可以很容易地从
    图例
    对象中读取,其他参数(如
    标题
    fancybox
    )需要一些“艺术性”。你可以检查一下,看看是怎么做的,为什么做的
  • 当最初使用
    prop
    创建图例时,
    fontsize
    参数上的附加条件用于覆盖字体大小,因为
    prop
    通常覆盖
    fontsize
  • 我没有测试所有的案例,因为我没有太多的时间(特别是
    bbox\u-to\u锚定
    bbox\u转换
    -参数),所以请尝试并改进代码:)

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

      要打开一个文件进行写入,我们将第二个参数设置为“w”而不是“r”。(of
      fobj=open(“ad_lesbiam.txt”,“r”)
      )要将数据实际写入该文件,我们使用file handle对象的方法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()
      

      仅供参考。输入文本文件的每一行都以行号作为前缀

      我想你可以进入并戳一下处理程序。mmmh这与问题有什么关系?这很好,谢谢。我不得不对
      \handler\u map=l.\u custom\u handler\u map,
      行进行注释,因为它在我的图例(python 2.7.8,mpl 1.3.1)中不存在。如果我没有弄错的话,属性
      \u custom\u handler\u map
      被称为
      \u handler\u map
      。因此,如果您在注释行中遇到问题,请尝试更改属性名称(而不是
      :)
      ,但如何更改文本?这是一种很好的方法。但也有一些改进。例如,您丢失了瓷砖。可以执行以下操作:leit=ax.get_legend().get_title().get_text()ax.legend(shadow=True,facecolor=(0.7,0.75,0.7,0.8))ax.get_legend().set_title(leit)