CREATE_GANTTを使用してpythonでガントチャートを作成したいです。ただし、開始日と終了日が重複している場合には問題があります。
例えば:
_import plotly.plotly as py
import plotly.figure_factory as ff
import plotly
df = [dict(Task="Milestone A", Start='2017-01-01', Finish='2017-02-02', Resource='Jack'),
dict(Task="Milestone B", Start='2018-01-01', Finish='2018-02-02', Resource='Jack'),
dict(Task="Milestone A", Start='2017-01-17', Finish='2017-04-28', Resource='Joe'),
dict(Task="Milestone B", Start='2017-03-17', Finish='2017-04-28', Resource='Joe'),
dict(Task="Milestone A", Start='2017-01-14', Finish='2017-03-14', Resource='John'),
dict(Task="Milestone B", Start='2018-01-14', Finish='2018-03-14', Resource='John')]
colors = {'Jack': 'rgb(220, 0, 0)',
'Joe': (1, 0.9, 0.16),
'John': 'rgb(0, 255, 100)'}
fig = ff.create_gantt(df, colors=colors, index_col='Resource', show_colorbar=True, group_tasks=True)
plotly.offline.plot(fig, filename='gantt-group-tasks-together')
_
このコードを実行すると、Joe、Jack、John用のバーラインは、図のようにマイルストーンAとマイルストーンBに重なります。 悪い出力 Joe、John、Jack、John、Jack for Joe、John、Jack for Joe、John、Jackが重複していません これ
これを達成するにはどうすればよいですか? 良い出力
altair-viz
( docs )はどうですか?
import pandas as pd
import numpy as np
import altair as alt
# alt.renderers.enable('notebook') # if in jupyter
df = pd.read_csv("tasks.csv")
df["Start date"] = pd.to_datetime(df["Start date"])
df["End date"] = pd.to_datetime(df["End date"])
chart = alt.Chart(df.drop("Resources", 1)).mark_bar().encode(
x='Start date',
x2='End date',
y=alt.Y('Task Name',
sort=list(df.sort_values(["End date", "Start date"])
["Task Name"])), # Custom sorting
)
chart
例DFの例
- ----------------------------------- ------------------- ------------------- ---------------------------------
0 Data type handling / Auto Inference 2019-07-01 00:00:00 2019-07-31 00:00:00 Backend
1 Sklearn & other models 2019-07-01 00:00:00 2019-07-31 00:00:00 Models
2 Maps / Geoplotting 2019-07-01 00:00:00 2019-07-31 00:00:00 Backend, Graphical User Interface
3 Optimize Dockerfile 2019-07-01 00:00:00 2019-07-31 00:00:00 CI/CD
4 Chapter 2: Compare competitors 2019-07-08 00:00:00 2019-10-21 00:00:00 Writing
- ----------------------------------- ------------------- ------------------- ---------------------------------
編集:テキストを追加してプログレスバーがあるかのように表示される方法も見つかりました。バーがoriginal * progress
に等しい高さがある別のシリーズを作成し、元のデータフレームに追加する
# Use the progress to find how much of the bars should be filled
# (i.e. another end date)
df["progress date"] = (df["End date"] - df["Start date"]) * df["Progress %"] / 100 + df["Start date"]
# Concatenate the two
newdf = np.concatenate([df[["Task Name", "Start date", "End date", "Progress %"]].values,
df[["Task Name", "Start date", "progress date", "Progress %"]].values])
newdf = pd.DataFrame(newdf, columns=["Task Name", "Start date", "End date", "Progress %"])
# Reconvert back to datetime
newdf["Start date"] = pd.to_datetime(newdf["Start date"])
newdf["End date"] = pd.to_datetime(newdf["End date"])
# This is the indicator variable (duration vs progress) where the grouping takes place
newdf["progress_"] = np.concatenate([np.ones(len(newdf)//2), np.zeros(len(newdf)//2), ])
# color for first half, color for second half
range_ = ['#1f77b4', '#5fa0d4',]
# The stacked bar chart will be our "gantt with progress"
chart = alt.Chart(newdf).mark_bar().encode(
x=alt.X('Start date', stack=None),
x2='End date',
y=alt.Y('Task Name', sort=list(df.sort_values(["End date",
"Start date"])["Task Name"])*2),
color=alt.Color('progress_', scale=alt.Scale(range=range_), legend=None)
)
# Create appropriate labels
newdf["text%"] = newdf["Progress %"].astype(str) + " %"
# And now add those as text in the graph
text = alt.Chart(newdf).mark_text(align='left', baseline='middle', dx=5, color="white", fontWeight="bold").encode(
y=alt.Y('Task Name', sort=list(df.sort_values(["End date",
"Start date"])["Task Name"])*2),
x=alt.X('Start date'),
text='text%',
)
# Plot the graph
alt.layer(chart, text)