Matplotlib 在图例中垂直堆叠线

Matplotlib 在图例中垂直堆叠线,matplotlib,Matplotlib,在寻找matplotlib图例中垂直堆叠线的解决方案时,我遇到了这篇堆栈文章,但我无法使代码正常工作,我总是在“legline=handler.createartists(…)”行中遇到错误: “发生异常:AttributeError'NoneType'对象没有 属性“创建艺术家” 在这里,我重现了stackoverflow问题的代码(@gyger): import matplotlib.pyplot as plt from matplotlib.legend_handler import Ha

在寻找matplotlib图例中垂直堆叠线的解决方案时,我遇到了这篇堆栈文章,但我无法使代码正常工作,我总是在“legline=handler.createartists(…)”行中遇到错误:

“发生异常:AttributeError'NoneType'对象没有 属性“创建艺术家”

在这里,我重现了stackoverflow问题的代码(@gyger):

import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerTuple

class HandlerTupleVertical(HandlerTuple):
    def __init__(self, **kwargs):
        HandlerTuple.__init__(self, **kwargs)

    def create_artists(self, legend, orig_handle,
                       xdescent, ydescent, width, height, fontsize, trans):
        # How many lines are there.
        numlines = len(orig_handle)
        handler_map = legend.get_legend_handler_map()

        # divide the vertical space where the lines will go
        # into equal parts based on the number of lines
        height_y = (height / numlines)

        leglines = []
        for i, handle in enumerate(orig_handle):
            handler = legend.get_legend_handler(handler_map, handle)

            legline = handler.create_artists(legend, handle,
                                             xdescent,
                                             (2*i + 1)*height_y,
                                             width,
                                             2*height,
                                             fontsize, trans)
            leglines.extend(legline)

        return leglines
要使用此代码,请执行以下操作:

line1 = plt.plot(xy,xy, c='k', label='solid')
line2 = plt.plot(xy,xy+1, c='k', ls='dashed', label='dashed')
line3 = plt.plot(xy,xy-1, c='k', ls='dashed', label='dashed')

plt.legend([(line1, line2), line3], ['text', 'more text', 'even more'],
           handler_map = {tuple : HandlerTupleVertical()})

似乎
for
循环中的
handle
是一个带有句柄的legnth-1列表,这会混淆
get\u legend\u handler
函数,因为它需要的是句柄,而不是列表

相反,如果您只将该列表中的处理程序发送到
图例.get\u legend\u handler()
handler.create\u artists()
,它似乎可以工作

也许最简单的方法是在调用
get\u legend\u handler
函数之前添加一行代码
handle=handle[0]

for i, handle in enumerate(orig_handle):

    handle = handle[0]
    handler = legend.get_legend_handler(handler_map, handle)

    legline = handler.create_artists(legend, handle,
                                     xdescent,
                                     (2*i + 1)*height_y,
                                     width,
                                     2*height,
                                     fontsize, trans)
    leglines.extend(legline)

正如@tmdavison所指出的,问题在于get\u legend\u handler函数需要的是句柄,而不是列表。我找到的原始代码可能来自matplotlib版本,而在matplotlib版本中,这种行为有所不同。 我通过将行设置为句柄(添加逗号)解决了这个问题:


这解决了问题的一部分,谢谢。但它并没有产生预期的图例:一个条目2行表示“文本”,另一个条目2行表示“更多文本”,三行表示“额外行”。由于@tmdavison,已经解决了。我在下面留下了答案。
line1, = plt.plot(xy,xy, c='k', label='solid')
line2, = plt.plot(xy,xy+1, c='k', ls='dashed', label='dashed')
line3, = plt.plot(xy,xy-1, c='k', ls='dashed', label='dashed')

plt.legend([(line1, line2), line3], ['text', 'more text', 'even more'],
           handler_map = {tuple : HandlerTupleVertical()})