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()
- 好的做法是将您的数据作为文本粘贴到问题中
- 做了两处改动
- 将Assembly放入hover_data中,使其在customdata中每条痕迹
- 循环跟踪以根据 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]]}}))
输出
我正在尝试创建一个机加工车间计划,该计划由属于同一装配体的零件进行颜色编码。我正在使用 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()
- 好的做法是将您的数据作为文本粘贴到问题中
- 做了两处改动
- 将Assembly放入hover_data中,使其在customdata中每条痕迹
- 循环跟踪以根据 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]]}}))