Python matplotlib__legend
1. 准备数据
width=4
height=width*0.618
fig, ax = plt.subplots(figsize=(width, height))
title='ZZZ'
x1=[1, 2., 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
y1=[0., 0.5, 0.75, 0.86, 0.87, 0.88,0.86, 0.86, 0.87, 0.86,0.88, 0.87, 0.88]
label1='A'
style1=['8', 'g', (0, (5, 1))]
x2=[1, 2., 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
y2=[0., 0.3, 0.6, 0.65, 0.66, 0.64,0.65, 0.65, 0.64, 0.66,0.65, 0.66, 0.65]
label2='B'
style2=['s', 'orange', (0, (2, 1))]
x3=[1, 2., 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
y3=[0., 0.2, 0.43, 0.46, 0.47,0.47, 0.46, 0.46, 0.48, 0.47,0.46, 0.47, 0.47]
label3='C'
style3=['v', 'r', (0, (4, 1, 1, 1, 1, 1))]
ax.legend() 由 3 种调用方式
Call signatures:
legend()
legend(labels)
legend(handles, labels)
2. legend() 自动添加图例
ax.plot(x1,y1,marker=style1[0],color=style1[1],linestyle=style1[2],label=label1)
ax.plot(x2,y2,marker=style2[0],color=style2[1],linestyle=style2[2],label=label2)
ax.plot(x3,y3,marker=style3[0],color=style3[1],linestyle=style3[2],label=label3)
ax.legend() # 自动添加图例
2.1 get_legend_handles_labels() 指定图例
使用 get_legend_handles_labels() 手动添加图例,效果和 ax.legend() 一样
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels)
但是,如果我们只传入部分 handles, 即
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[:1], labels[:1])
得到
好像只要出现几个图例由 handles 决定,不管 labels, 即
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[:1], labels)
效果也只有 label1, 和图 2 一样
但是如果只是传入 handles 这样,程序会报错
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles)
# TypeError: A single argument passed to legend() must be a list of labels, but found an Artist in there.
根据 ax.legend() 3种调用方式可以得知
Call signatures:
legend()
legend(labels)
legend(handles, labels)
在只有一个参数的情况下,我们需要使用 labels
handles, labels = ax.get_legend_handles_labels()
ax.legend(labels[1:])
得到
此时我们发现一个问题,就是绿色的线应该标成 label1, 这里是因为按照默认自动的排序
假如现在只标记 黄色 和 红色 的线
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[1:], labels[1:])
有更简单的方法是
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:])
一样得到图 4 的效果
2.2 精准指定handle
h1,=ax.plot(x1,y1,marker=style1[0],color=style1[1],linestyle=style1[2],label=label1)
h2,=ax.plot(x2,y2,marker=style2[0],color=style2[1],linestyle=style2[2],label=label2)
h3,=ax.plot(x3,y3,marker=style3[0],color=style3[1],linestyle=style3[2],label=label3)
ax.legend(handles=[h2,h3])
得到
甚至我们可以在 legend() 函数中重新修改 label
ax.legend(handles=[h2,h3],labels=['new label2','new label3'])
3. 添加一个新的图例
现在我们添加一条 蓝色 的图例,但是没有数据
这个功能主要用于某些画图函数无法直接生成图例,比如 violin 函数 ax.violinplot()
h1,=ax.plot(x1,y1,marker=style1[0],color=style1[1],linestyle=style1[2],label=label1)
h2,=ax.plot(x2,y2,marker=style2[0],color=style2[1],linestyle=style2[2],label=label2)
h3,=ax.plot(x3,y3,marker=style3[0],color=style3[1],linestyle=style3[2],label=label3)
import matplotlib.lines as mlines
blue_line = mlines.Line2D([], [], color='#2F81BA',linestyle=(0,(4,1)), marker='*',label='Blue')
ax.legend(handles=[h1,h2,h3,blue_line])
注意,所有的图例都要写在一起,如果 h1, h2, h3 用一次 ax.legend(), blue_line 用一次 ax.legend(), 只会显示最后那个图例。
ax.legend(handles=[h1,h2,h3])
ax.legend(handles=[blue_line])
4. 完整源代码
import os
import matplotlib.pyplot as plt
import time
font1 = {
'weight': 'medium',
'size': 12,
}
font2 = {
'weight': 'medium',
'size': 12,
}
def pt():
width = 4
height = width * 0.618
fig, ax = plt.subplots(figsize=(width, height))
title = 'ZZZ'
x1 = [1, 2., 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
y1 = [
0., 0.5, 0.75, 0.86, 0.87, 0.88, 0.86, 0.86, 0.87, 0.86, 0.88, 0.87,
0.88
]
label1 = 'label1'
style1 = ['8', 'g', (0, (5, 1))]
x2 = [1, 2., 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
y2 = [
0., 0.3, 0.6, 0.65, 0.66, 0.64, 0.65, 0.65, 0.64, 0.66, 0.65, 0.66,
0.65
]
label2 = 'label2'
style2 = ['s', 'orange', (0, (2, 1))]
x3 = [1, 2., 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
y3 = [
0., 0.2, 0.43, 0.46, 0.47, 0.47, 0.46, 0.46, 0.48, 0.47, 0.46, 0.47,
0.47
]
label3 = 'label3'
style3 = ['v', 'r', (0, (4, 1, 1, 1, 1, 1))]
h1, = ax.plot(x1,
y1,
marker=style1[0],
color=style1[1],
linestyle=style1[2],
label=label1)
h2, = ax.plot(x2,
y2,
marker=style2[0],
color=style2[1],
linestyle=style2[2],
label=label2)
h3, = ax.plot(x3,
y3,
marker=style3[0],
color=style3[1],
linestyle=style3[2],
label=label3)
import matplotlib.lines as mlines
blue_line = mlines.Line2D([], [],
color='#2F81BA',
linestyle=(0, (4, 1)),
marker='*',
label='Blue')
ax.legend(handles=[h1, h2, h3, blue_line])
# ax.legend(handles=[blue_line])
ax.set_ylabel('YYY', font2)
ax.set_xlabel('XXX', font1)
ax.set_title('TITLE = ' + title, fontsize=11)
ax.grid()
plt.tight_layout()
SaveDir = 'result/'
if not os.path.exists(SaveDir):
os.makedirs(SaveDir)
now = time.strftime("%Y_%m%d_%H%M_%S", time.localtime(
time.time())) # 获得当前时间 2021_1108_2310_22
SaveFile = SaveDir + title + '_' + now + '.png'
fig.savefig(SaveFile)
print(SaveFile + ' ==================>>> has been complete')
plt.close()
def example():
pt()
if __name__ == '__main__':
example()