Plotly Express 时间线甘特图,基于数据框中列的颜色编码

Plotly Express Timeline Gantt Chart, color coding based on column in dataframe

我正在尝试创建一个机加工车间计划,该计划由属于同一装配体的零件进行颜色编码。我正在使用 plotly express timeline 来创建甘特图。它正在读取我桌面上的 excel 文件以生成时间表。我在下面创建了一个示例。目标是让所有椅子部件颜色相同,所有桌子部件颜色相同。

这是读取 excel 文件并创建甘特图的代码:

df = pd.read_excel(r"C:\Users\john.doe\Documents\Machine Durations - Sample.xlsx")

df['Start Shift'] = df['Start Shift'].astype(int)
df['Finish'] = df['Finish'].astype(int)
#display(df)

# create a slice if the df for the rank = 1
dfRank1 = df[df.Rank == 1]
# reindex it 
dfRank1 = dfRank1.reset_index()
#display(dfRank1)

#Create the visual 

df["Part"] = df["Part"].astype(str)
df["delta"] = df["Finish"]-df["Start Shift"]
fig = px.timeline(df,x_start ="Start Shift", x_end = "Finish", y = "Machine", hover_name ="Part",color = "Part", text = "Part", title = "Machine Shop Cycle", opacity = .75)
fig.update_yaxes(autorange="reversed")
fig.layout.xaxis.type = 'linear'
#fig.data[0].x = df.delta.tolist()
for d in fig.data:
    filt = df['Part'] == d.name
    d.x = df[filt]['delta'].tolist()

fig.update_traces(textposition='inside')    
    
fig.show()


  • 好的做法是将您的数据作为文本粘贴到问题中
  • 做了两处改动
    1. Assembly放入hover_data中,使其在customdata中每条痕迹
    2. 循环跟踪以根据 customdata 中的 Assembly 更新 marker_color
# update colors to that of the assembly
cmap = {"Chair":"red", "Desk":"blue"}
fig.for_each_trace(lambda t: t.update({"marker":{"color":[cmap[a] for a in t["customdata"][:,0]]}}))

完整代码

import pandas as pd
import plotly.express as px
import io

df = pd.read_csv(
    io.StringIO(
        """Part,Machine,Duration,Duration Shifts(6),Start Shift,Finish,Index,Assembly,Rank
Legs,Lathe,100,5,0,5,1,Chair,A
Seat,Mill,400,5,0,5,1,Chair,A
Back,Mill,200,3,5,8,1,Chair,A
Legs,Lathe,200,3,5,8,1,Desk,A
Table Top,Mill,200,3,8,11,1,Desk,A
Wheels,Mill-Turn,200,10,0,10,1,Desk,A"""
    )
)

df["Start Shift"] = df["Start Shift"].astype(int)
df["Finish"] = df["Finish"].astype(int)
# display(df)

# create a slice if the df for the rank = 1
dfRank1 = df[df.Rank == 1]
# reindex it
dfRank1 = dfRank1.reset_index()
# display(dfRank1)

# Create the visual

df["Part"] = df["Part"].astype(str)
df["delta"] = df["Finish"] - df["Start Shift"]
fig = px.timeline(
    df,
    x_start="Start Shift",
    x_end="Finish",
    y="Machine",
    hover_name="Part",
    hover_data=["Assembly"], # want this for setting color
    color="Part",
    text="Part",
    title="Machine Shop Cycle",
    opacity=0.75,
)
fig.update_yaxes(autorange="reversed")
fig.layout.xaxis.type = "linear"
# fig.data[0].x = df.delta.tolist()
for d in fig.data:
    filt = df["Part"] == d.name
    d.x = df[filt]["delta"].tolist()

fig.update_traces(textposition="inside")

# update colors to that of the assembly
cmap = {"Chair":"red", "Desk":"blue"}
fig.for_each_trace(lambda t: t.update({"marker":{"color":[cmap[a] for a in t["customdata"][:,0]]}}))

输出