pyplot图例中的左对齐和右对齐

时间:2020-10-13 09:26:24

标签: python matplotlib legend

在我的绘图图例中,我还要在“正常”图例旁边显示函数的(最佳)值。

我当前的尝试:

enter image description here

我的编码如下:

for j, pol in enumerate(pols):
        val = vidics[1][pol]
        axis[1,i].axhline(val, label=f'{pol_label[j]}: {val:.1f}', color='r', linestyle = st[j])
    
sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_FI_3).melt(), label = f'FI: {score_FI_3:.1f}', ax=axis[1,i])
sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_PO_3).melt(), label = f'PO: {score_PO_3:.1f}', ax=axis[1,i])

for循环创建水平线。 sns线会创建蓝色和橙色线。

我想拥有的是分数(图例中的值)正确对齐。 通过在fstring中添加空格来手动执行此操作是不可行的,因为我将许多小图填充到了循环中。我试图在字符串中添加空格/填充,例如第二行sns行的以下标签:

label = f'{"PO": < 10}: {score_PO_3:.1f}'

哪个添加空格,直到字符串的长度为10(我认为?)。我以为如果对所有字符串都这样做,那么右边的字符将对齐,但是由于并非字符串中的所有字符都具有相同的宽度,因此这也不起作用并且看起来很丑。

有什么想法吗?

此外,较大的代码可供参考:

pols = ['optimal', 'preventive', 'corrective']
pol_label = ['VIoptm', 'VIprev', 'VIcorr']
vidics = [vi2, vi3, vi4]

labels = ['4', '5', '6', '7']

dics2_PO = [s4_PO_2, s5_PO_2, s6_PO_2, s7_PO_2]
dics2_FI = [s4_FI_2, s5_FI_2, s6_FI_2, s7_FI_2]

dics3_PO = [s4_PO_3, s5_PO_3, s6_PO_3, s7_PO_3]
dics3_FI = [s4_FI_3, s5_FI_3, s6_FI_3, s7_FI_3]

dics4_PO = [s4_PO_4, s5_PO_4, s6_PO_4, s7_PO_4]
dics4_FI = [s4_FI_4, s5_FI_4, s6_FI_4, s7_FI_4]

figlabel = [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k','l']]

fig, axis = plt.subplots(3,4, figsize=(17,10))

st = ['-', '-.' , ':']

for i in range(4):
    # 2 comp
    dic2FI = dics2_FI[i]
    dic2PO = dics2_PO[i]
    
    r_FI_2 = dic2FI['ar']
    r_PO_2 = dic2PO['ar']
    
    t_PO_2 = np.array(dic2PO['t']).sum()
    
    best_r_FI = np.array(dic2FI['best_r'])
    best_r_PO = np.array(dic2PO['best_r'])
    
    score_FI_2 = best_r_FI.mean()
    score_PO_2 = best_r_PO.mean()
    
    sd_FI_2 = best_r_FI.std()
    sd_PO_2 = best_r_PO.std()
    
    print(f'2comp, agent {labels[i]} FI : {score_FI_2:.1f} +- {sd_FI_2:.1f} ')
    print(f'2comp, agent {labels[i]} PO : {score_PO_2:.1f} +- {sd_PO_2:.1f} ')
    print(f'2comp, agent {labels[i]} PO , time: {t_PO_2:.0f}')
    
    for j, pol in enumerate(pols):
        val = vidics[0][pol]
        axis[0,i].axhline(val, label=f'{pol_label[j]}: {val:.1f}', color='r', linestyle = st[j])
    
    sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_FI_2).melt(), label = f'FI: {score_FI_2:.1f}', ax=axis[0,i])
    sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_PO_2).melt(), label = f'PO: {score_PO_2:.1f}', ax=axis[0,i])
    
    axis[0,i].set_ylim((-30,-8))
    axis[0,i].legend(loc='lower right')
    axis[0,i].set_xlabel('Training Iterations')
    axis[0,i].set_xticks([4,9])
    axis[0,i].set_xticklabels(['50k', '100k'])
    axis[0,i].set_title(f'{figlabel[0][i]}) 2 comp, agent {labels[i]}')
    if i==0:
        axis[0,i].set_ylabel('Average Reward')
    else:
        axis[0,i].set_ylabel('')
            

    
    # 3 comp
    dic3FI = dics3_FI[i]
    dic3PO = dics3_PO[i]
    
    r_FI_3 = dic3FI['ar']
    r_PO_3 = dic3PO['ar']
    
    t_PO_3 = np.array(dic3PO['t']).sum()
    
    best_r_FI = np.array(dic3FI['best_r'])
    best_r_PO = np.array(dic3PO['best_r'])
    
    score_FI_3 = best_r_FI.mean()
    score_PO_3 = best_r_PO.mean()
    
    sd_FI_3 = best_r_FI.std()
    sd_PO_3 = best_r_PO.std()
    
    print(f'3comp, agent {labels[i]} FI : {score_FI_3:.1f} +- {sd_FI_3:.1f} ')
    print(f'3comp, agent {labels[i]} PO : {score_PO_3:.1f} +- {sd_PO_3:.1f} ')
    print(f'3comp, agent {labels[i]} PO , time: {t_PO_3:.0f}')
    
    for j, pol in enumerate(pols):
        val = vidics[1][pol]
        axis[1,i].axhline(val, label=f'{pol_label[j]}: {val:.1f}', color='r', linestyle = st[j])
    
    sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_FI_3).melt(), label = f'FI: {score_FI_3:.1f}', ax=axis[1,i])
    sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_PO_3).melt(), label = f'PO: {score_PO_3:.1f}', ax=axis[1,i])
    
    axis[1,i].set_ylim((-60,-15))
    axis[1,i].legend(loc='lower right')
    axis[1,i].set_xlabel('Training Iterations')
    axis[1,i].set_xticks([4,9])
    axis[1,i].set_xticklabels(['100k', '200k'])
    axis[1,i].set_title(f'{figlabel[1][i]}) 3 comp, agent {labels[i]}')
    if i==0:
        axis[1,i].set_ylabel('Average Reward')
    else:
        axis[1,i].set_ylabel('')
   
    
    
     # 4 comp
    dic4FI = dics4_FI[i]
    dic4PO = dics4_PO[i]
    
    r_FI_4 = dic4FI['ar']
    r_PO_4 = dic4PO['ar']
    
    t_PO_4 = np.array(dic4PO['t']).sum()
    
    best_r_FI = np.array(dic4FI['best_r'])
    best_r_PO = np.array(dic4PO['best_r'])
    
    score_FI_4 = best_r_FI.mean()
    score_PO_4 = best_r_PO.mean()
    
    sd_FI_4 = best_r_FI.std()
    sd_PO_4 = best_r_PO.std()
    
    print(f'4comp, agent {labels[i]} FI : {score_FI_4:.1f} +- {sd_FI_4:.1f} ')
    print(f'4comp, agent {labels[i]} PO : {score_PO_4:.1f} +- {sd_PO_4:.1f} ')
    print(f'4comp, agent {labels[i]} PO , time: {t_PO_4:.0f}')
    
    for j, pol in enumerate(pols):
        val = vidics[2][pol]
        axis[2,i].axhline(val, label=f'{pol_label[j]}: {val:.1f}', color='r', linestyle = st[j])
    
    sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_FI_4).melt(), label = f'FI: {score_FI_4:.1f}', ax=axis[2,i])
    sns.lineplot(x= 'variable',y='value',data=pd.DataFrame(r_PO_4).melt(), label = f'PO: {score_PO_4:.1f}', ax=axis[2,i])
    
    axis[2,i].set_ylim((-70,-20))
    axis[2,i].legend(loc='lower right')
    axis[2,i].set_xlabel('Training Iterations')
    axis[2,i].set_xticks([4,9])
    axis[2,i].set_xticklabels(['200k', '400k'])
    axis[2,i].set_title(f'{figlabel[2][i]}) 4 comp, agent {labels[i]}')
    if i==0:
        axis[2,i].set_ylabel('Average Reward')
    else:
        axis[2,i].set_ylabel('')
    
   
    
    plt.tight_layout()

哪个创建了以下图形:

enter image description here

1 个答案:

答案 0 :(得分:1)

看看分配标签值的位置:

label=f'{pol_label[j]}: {val:.1f}'

所有格式都保持对齐。与例如:

print('{:<2}: {:<8}'.format(*['label','value']))

意思是,“左对齐所有内容,但让第一个单词的可用空间为2(从左数起),第二个单词的可用空间为8”

要解决此问题,在给定适当的可用空间的情况下,我将尝试使第一个单词左对齐,而第二个右对齐。在上一行中,只需更改第二个符号,并可能更改空格:

 print('{:<2}: {:>8}'.format(*['label','value']))

实现(输出):

label:      value

(标签左对齐,值右对齐)

reference

相关问题