简体   繁体   English

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

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

I'm trying to create a machine shop schedule that is color coded by parts that belong to the same assembly.我正在尝试创建一个机械车间计划,该计划由属于同一装配体的零件进行颜色编码。 I'm using plotly express timeline to create the Gantt.我正在使用 plotly 快速时间表来创建甘特图。 It is reading an excel file on my desktop to generate the schedule.它正在读取我桌面上的一个 excel 文件来生成时间表。 I created a sample below.我在下面创建了一个示例。 The goal is to have all the Chair parts be the same color, and all the Desk parts be the same color.目标是让所有的椅子部件都具有相同的颜色,并且所有的桌子部件都具有相同的颜色。

excel表格是这样的

Here's the code to read the excel file and create the Gantt:下面是读取 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()


这是输出甘特图。

  • good practice is paste you data as text into a question好的做法是将数据作为文本粘贴到问题中
  • have made two changes做了两个改变
    1. put Assembly into hover_data so that it is in customdata of each traceAssembly放入hover_data中,使其位于每个跟踪的自定义数据
    2. loop through traces to update marker_color based on Assembly in customdata循环跟踪以根据自定义数据中的程序集更新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]]}}))

full code完整代码

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]]}}))

output output

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM