我已经创建了甘特图,我正在尝试将图例添加到图中
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()
图例中的图例重复。我该如何纠正?
答案 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)
结果:
但是,这仍然不能使整个程序中的代码清晰易读。我认为情况甚至变得更糟,因为它是“代码,直到结构正常为止,它一直执行应有的工作”类型的另一个补丁。
我绝对建议您回顾整个过程,并也许可以从头开始重新创建它,并使用从该版本中学到的经验教训来更好地开发它。
(并且仅用于与python中几乎所有其他编码的接口:使用4个空格作为缩进,而不仅仅是3个。)