如何获取图表中的所有图例?
我有一个图表,上面有两个或更多的图例。
我想知道怎么才能“获取”所有的图例,以便更改(比如说)图例中的颜色和线条样式。
handles, labels = ax.get_legend_handles_labels()
这个代码只给我返回了“第一个”图例,也就是我用 plt.legend()
添加的那个。但我还想要其他的图例,它们是我用 plt.gca().add_artist(leg2)
添加的。
我该怎么做呢?
2 个回答
8
解决方案
另外一种方法是: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
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>]
这是否是你想要做的事情还有待观察!?你也可以把线条(或其他类型的元素)单独存储,而不放在坐标轴里。