如何从图表中获取所有图例?

13

我有一个带有两个或多个图例的图表。 如何“获取”所有图例并更改(例如)图例中的颜色和线条样式?

handles, labels = ax.get_legend_handles_labels() 只给出了我“第一个”图例,它是用plt.legend()添加到图表中的。但我也想要其他的图例,这些图例是使用plt.gca().add_artist(leg2)添加的。 我该怎么做呢?


1
你能给一个更完整的例子吗?我真的不知道你在这里说什么。 - tacaswell
2个回答

13

您可以从轴中获取所有子元素,并使用以下方法过滤图例类型:

legends = [c for c in ax.get_children() if isinstance(c, mpl.legend.Legend)]

但是这真的有效吗?如果我像你提到的那样添加更多图例,我会看到多个Legend子项,但所有子项都指向同一个对象。

编辑:

轴本身保留了最后添加的图例,因此如果您使用.add_artist()添加前面的图例,您将看到多个不同的图例:

例如:

fig, ax = plt.subplots()

l1, = ax.plot(x,y, 'k', label='l1')
leg1 = plt.legend([l1],['l1'])

l2, = ax.plot(x,y, 'k', label='l2')
leg2 = plt.legend([l2],['l2'])

ax.add_artist(leg1)

print(ax.get_children())

返回这些对象:

[<matplotlib.axis.XAxis at 0xd0e6eb8>,
 <matplotlib.axis.YAxis at 0xd0ff7b8>,
 <matplotlib.lines.Line2D at 0xd0f73c8>,
 <matplotlib.lines.Line2D at 0xd5c1a58>,
 <matplotlib.legend.Legend at 0xd5c1860>,
 <matplotlib.legend.Legend at 0xd5c4b70>,
 <matplotlib.text.Text at 0xd5b1dd8>,
 <matplotlib.text.Text at 0xd5b1e10>,
 <matplotlib.text.Text at 0xd5b1e48>,
 <matplotlib.patches.Rectangle at 0xd5b1e80>,
 <matplotlib.spines.Spine at 0xd0e6da0>,
 <matplotlib.spines.Spine at 0xd0e6ba8>,
 <matplotlib.spines.Spine at 0xd0e6208>,
 <matplotlib.spines.Spine at 0xd0f10f0>]

尚不清楚这是否是你想要做的事情!?你也可以将这些线条(或其他类型)与轴分开存储。


legends = [c for c in ax.get_children() if isinstance(c, mpl.legend.Legend)] 对我非常有用!它返回了绘图中的所有图例!这正是我在寻找的!非常感谢! - Hubschr

7

解决方案

另一种方法:ax.get_legend()

legends = ax.get_legends()

访问图例属性的方法如下:

legends = ax.get_legend()
dict_legends = {'Legends': dict()}
if not isinstance(legends, list):
    legends = [legends]
for i, legend in enumerate(legends):     
    dict_legend = dict()                                                           
    for j, obj in enumerate(lgnd.get_texts()):
        dict_obj = dict()
        dict_fp = dict()
        text = obj.get_text()
        position = obj.get_position()
        color = obj.get_color()    
        dict_obj.update({'Text': text, 
                         'Position': tuple(position), 
                         'Color': color})
        obj_fp = obj.get_font_properties()
        dict_fp.update({'Font_Name': obj_fp.get_name()})
        fontconfig_pattern = obj_fp.get_fontconfig_pattern()
        font_properties = str.split(fontconfig_pattern,":")
        for fp in font_properties:
            if not (fp.strip()==''):
                key, value = fp.split("=")
                dict_fp.update({str.title(key): value})        
        dict_fp.update({'fontconfig_pattern': fontconfig_pattern})
        dict_obj.update({'Font_Properties': dict_fp})    
        dict_legend.update({'Text_Object_{}'.format(j+1): dict_obj})    
    dict_legends['Legends'].update({'Legend_{}'.format(i): {'Legend_Object': legend, 
                                                            'Contents': dict_legend}})

print(dict_legends)

配置:

#  Windows: 10  
#  Python: 3.6  
#  Matplotlib: 2.2.2  

为什么这么复杂?另外,您能验证一下您的代码吗?因为在 key, value = fp.split("=") 这行代码处我无法运行。 - Marine Galantin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接