Избегайте дублирования легенд в broken_barh - PullRequest
0 голосов
/ 08 октября 2018

Я создал диаграмму Ганта, я пытаюсь добавить легенду к своему сюжету

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 голосов
/ 08 октября 2018

По моему мнению, этот код очень сложен и его следует упростить ...

Однако, первым намеком может быть поместить имя группы и группу прямо в определении цикла в две разные переменные вместо индексации покортеж:

...
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, чтобы сохранитьотслеживать, если метка уже использовалась для легенды.Если да, поставьте подчеркивание перед надписью, которое превосходит отображаемое в легенде:

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.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...