避免在broken_barh中重复图例

时间:2018-10-08 06:20:43

标签: python matplotlib

我已经创建了甘特图,我正在尝试将图例添加到图中

import pandas as pd
import matplotlib.pyplot as plt
data=[['A','B','7:00:00','7:30:00'],['A','C','8:00:00','8:30:00'], 
      ['X','B','7:30:00','8:30:00'],['X','C','7:30:00','8:00:00'],
      ['P','Q','7:30:00','8:30:00'],['P','C','9:00:00','9:30:00']]
df=pd.DataFrame(data,columns=['L','M','stime','etime'])
start_time=[]
end_time=[]
for i,row in df.iterrows():
   a=row['stime'].split(':')
   b=row['etime'].split(':')
   start_hrs=int(a[0])+(int(a[1])/60)+(int(a[2])/3600)
   end_hrs=int(b[0])+(int(b[1])/60)+(int(b[2])/3600)
   start_time.append(start_hrs)
   end_time.append(end_hrs)
df['start']=start_time
df['end']=end_time
df['diff']=df['end']-df['start']
color = {"B":"turquoise", "C":"crimson","Q":"orange"}
fig,ax=plt.subplots(figsize=(6,3))   
w=[]
for i, task in enumerate(df.groupby("L")):
   w.append(task[0])
   for r in task[1].groupby("M"):
      data = r[1][["start", "diff"]]
      ax.broken_barh(data.values, (i-0.4,0.8), color=color[r[0]],label=r[1]
       ['M'])
ax.set_yticks(range(len(label)))
ax.set_yticklabels(label)
ax.set_xlabel("time [hrs]")
ax.set_ylabel("L")
plt.legend()
plt.tight_layout()
plt.show()

enter image description here

图例中的图例重复。我该如何纠正?

1 个答案:

答案 0 :(得分:0)

我认为这段代码非常复杂,应该简化...

但是,第一个提示可能是将循环定义中的groupname和group放到两个不同的变量中,而不是在元组上建立索引:

...
for lbl, grp in task[1].groupby("M"):
    data = grp[["start", "diff"]]
    ax.broken_barh(data.values, (i-0.4,0.8), color=color[lbl], label=lbl)
...

也就是说,我可以给您一个可能,将仅未使用的标签添加到图例。
这个想法是初始化一个空列表lbl_pool来跟踪标签是否已经用于图例。如果是jes,请在标签前加一个下划线,以防止在图例中显示该符号:

w=[]
lbl_pool = []
for i, task in enumerate(df.groupby("L")):
   w.append(task[0])
   for lbl, grp in task[1].groupby("M"):
      data = grp[["start", "diff"]]
      if lbl in lbl_pool:
          prefix = '_'
      else:
          lbl_pool.append(lbl)
          prefix=''
      ax.broken_barh(data.values, (i-0.4,0.8), color=color[lbl], label=prefix+lbl)

结果:

enter image description here

但是,这仍然不能使整个程序中的代码清晰易读。我认为情况甚至变得更糟,因为它是“代码,直到结构正常为止,它一直执行应有的工作”类型的另一个补丁。

我绝对建议您回顾整个过程,并也许可以从头开始重新创建它,并使用从该版本中学到的经验教训来更好地开发它。

(并且仅用于与python中几乎所有其他编码的接口:使用4个空格作为缩进,而不仅仅是3个。)