How to cluster Gantt bars without overlap?

2024/9/30 13:24:44

Using create_gantt I have overlapping start and end dates:

import plotly.plotly as py
import plotly.figure_factory as ff
import plotlydf = [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')

Bars for Joe, Jack and John overlap for Milestone A and Milestone B :

Bad Output

I want 3 lines for Milestone A for Joe, John and Jack clustered but not overlapped :

this

How to achieve this?

Answer

How about altair-viz (docs)?

import pandas as pd
import numpy as np
import altair as alt
# alt.renderers.enable('notebook') # if in jupyterdf = 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

enter image description here

Example 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
-  -----------------------------------  -------------------  -------------------  ---------------------------------

Edit: I also found a way to add text and make it appear as if it has a progress bar. It works by creating another series whose bars have height equal to original * progress and appending it to the original dataframe

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

Result: enter image description here

https://en.xdnf.cn/q/71075.html

Related Q&A

Fail to install lxml using pip

This is the command I used to install lxml:sudo pip install lxmlAnd I got the following message in the Cleaning Up stage:Cleaning up... Command /usr/bin/python -c "import setuptools, tokenize;…

Python 3.x list comprehension VS tuple generator

Is there any reason for memory, speed or whatever, that I would want to use:tuple(i for i in range(5000))instead of:[i for i in range(5000)]If I didnt mind the immutability of tuples

Using Sphinx with a distutils-built C extension

I have written a Python module including a submodule written in C: the module itself is called foo and the C part is foo._bar. The structure looks like:src/ foo/__init__.py <- contains the public …

PyYAML error: Could not determine a constructor for the tag !vault

I am trying to read a YAML file that has the tag !vault in it. I get the error:could not determine a constructor for the tag !vaultUpon reading a couple of blogs, I understood that I need to specify so…

Accessing a XAMPP mysql via Python

Im attempting to use mysql after only having worked with sqlite in the past.Ive installed XAMPP on Linux (ubuntu) and have mysql up and running fine (seems like that with phpMyadmin at least). However,…

How to use deep learning models for time-series forecasting?

I have signals recorded from machines (m1, m2, so on) for 28 days. (Note: each signal in each day is 360 length long).machine_num, day1, day2, ..., day28 m1, [12, 10, 5, 6, ...], [78, 85, 32, 12, ...],…

Python - Create Shortcut with arguments

Using win32com.client, Im attempting to create a simple shortcut in a folder. The shortcut however I would like to have arguments, except I keep getting the following error.Traceback (most recent call …

How to replace a range of values with NaN in Pandas data-frame?

I have a huge data-frame. How should I replace a range of values (-200, -100) with NaN?

django 1.10 Exception while resolving variable is_popup in template admin/login.html

I create a new django project with python3.5 and django1.10.0,I keep getting an error in the admin whenever I want access localhost:8000/admin, He`res the error:[DEBUG]- Exception while resolving varia…

Programmatically extract data from an Excel spreadsheet

Is there a simple way, using some common Unix scripting language (Perl/Python/Ruby) or command line utility, to convert an Excel Spreadsheet file to CSV? Specifically, this one:http://www.econ.yale.e…