在matplotlib图例中寻找垂直堆栈线的解决方案时,我遇到了此堆栈帖子Two line styles in legend,但是我无法使代码正常工作,我总是在“ 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()})
答案 0 :(得分:1)
看来handle
循环中的for
是一个内有句柄的Legnth-1列表,这使get_legend_handler
函数感到困惑,因为它期待的是句柄,而不是列表。
如果相反,您只是从该列表内部将处理程序发送到legend.get_legend_handler()
和handler.create_artists()
,那么它似乎可以正常工作。
也许最简单的方法是在调用handle = handle[0]
函数之前添加一行代码get_legend_handler
。
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)
答案 1 :(得分:0)
正如@tmdavison所指出的那样,问题在于get_legend_handler函数需要一个句柄,而不是一个列表。我可能发现的原始代码来自matplotlib版本,该行为有所不同。 我通过使线成为句柄(通过添加逗号)解决了这个问题:
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()})