Skip to content

Instantly share code, notes, and snippets.

@aabiddanda
Last active June 27, 2023 01:33
Show Gist options
  • Save aabiddanda/2a5eaa671e26898c3b398d32473a2430 to your computer and use it in GitHub Desktop.
Save aabiddanda/2a5eaa671e26898c3b398d32473a2430 to your computer and use it in GitHub Desktop.
"""
GANTT Chart with Matplotlib
Sukhbinder
Inspired from
https://sukhbinder.wordpress.com/2016/05/10/quick-gantt-chart-with-matplotlib/
"""
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
import matplotlib.dates
from matplotlib.dates import WEEKLY,MONTHLY, DateFormatter, rrulewrapper, RRuleLocator
import numpy as np
import click
def _create_date(datetxt):
"""Creates the date"""
day,month,year=datetxt.split('-')
date = dt.datetime(int(year), int(month), int(day))
mdate = matplotlib.dates.date2num(date)
return mdate
def CreateGanttChart(fname, outname):
"""
Create gantt charts with matplotlib
Input is a data file for the GANNT chart
Output is a image file for the figure
"""
ylabels = []
customDates = []
try:
textlist=open(fname).readlines()
except:
return
for tx in textlist:
if not tx.startswith('#'):
ylabel,startdate,enddate=tx.split(',')
ylabels.append(ylabel.replace('\n',''))
customDates.append([_create_date(startdate.replace('\n','')),_create_date(enddate.replace('\n',''))])
ilen=len(ylabels)
pos = np.arange(0.5,ilen*0.5+0.5,0.5)
task_dates = {}
for i,task in enumerate(ylabels):
task_dates[task] = customDates[i]
fig = plt.figure(figsize=(20,8))
ax = fig.add_subplot(111)
for i in range(len(ylabels)):
start_date,end_date = task_dates[ylabels[i]]
ax.barh((i*0.5)+0.5, end_date - start_date, left=start_date, height=0.3, align='center', color='blue', alpha = 0.8)
locsy, labelsy = plt.yticks(pos,ylabels)
plt.setp(labelsy, fontsize = 14)
# ax.axis('tight')
ax.set_ylim(ymin = -0.1, ymax = ilen*0.5+0.5)
ax.grid(color = 'g', linestyle = ':')
ax.xaxis_date()
rule = rrulewrapper(WEEKLY, interval=1)
loc = RRuleLocator(rule)
formatter = DateFormatter("%d-%b")
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_major_formatter(formatter)
labelsx = ax.get_xticklabels()
plt.setp(labelsx, rotation=30, fontsize=10)
font = font_manager.FontProperties(size='small')
ax.legend(loc=1,prop=font)
ax.invert_yaxis()
fig.autofmt_xdate()
plt.savefig(outname)
@click.command()
@click.option('--gannt_file', required=True, help='File with dates for the GANNT file creation')
@click.option('--out', required=True, default='gannt.png', help='Output Figure with ')
def main(gannt_file, out):
CreateGanttChart(gannt_file, out)
if __name__ == '__main__':
main()
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "c194569d-3736-461c-8e98-b815febb6d6f",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import pandas as pd\n",
"from matplotlib.patches import Patch\n",
"\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "fecdcf14-3d2e-4462-9cff-fdecdc5f11d2",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Task</th>\n",
" <th>Type</th>\n",
" <th>Start</th>\n",
" <th>End</th>\n",
" <th>start_num</th>\n",
" <th>end_num</th>\n",
" <th>days_start_to_end</th>\n",
" <th>color</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Figure 6</td>\n",
" <td>Figure</td>\n",
" <td>2023-08-01</td>\n",
" <td>2023-08-20</td>\n",
" <td>29</td>\n",
" <td>48</td>\n",
" <td>19</td>\n",
" <td>#E64646</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Figure 5</td>\n",
" <td>Figure</td>\n",
" <td>2023-07-25</td>\n",
" <td>2023-08-04</td>\n",
" <td>22</td>\n",
" <td>32</td>\n",
" <td>10</td>\n",
" <td>#E64646</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Manuscript Writing</td>\n",
" <td>Writing</td>\n",
" <td>2023-07-17</td>\n",
" <td>2023-09-04</td>\n",
" <td>14</td>\n",
" <td>63</td>\n",
" <td>49</td>\n",
" <td>#E69646</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Figure 4</td>\n",
" <td>Figure</td>\n",
" <td>2023-07-15</td>\n",
" <td>2023-07-28</td>\n",
" <td>12</td>\n",
" <td>25</td>\n",
" <td>13</td>\n",
" <td>#E64646</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Figure 3</td>\n",
" <td>Figure</td>\n",
" <td>2023-07-09</td>\n",
" <td>2023-07-14</td>\n",
" <td>6</td>\n",
" <td>11</td>\n",
" <td>5</td>\n",
" <td>#E64646</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Figure 2</td>\n",
" <td>Figure</td>\n",
" <td>2023-07-03</td>\n",
" <td>2023-07-09</td>\n",
" <td>0</td>\n",
" <td>6</td>\n",
" <td>6</td>\n",
" <td>#E64646</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Task Type Start End start_num end_num \\\n",
"4 Figure 6 Figure 2023-08-01 2023-08-20 29 48 \n",
"3 Figure 5 Figure 2023-07-25 2023-08-04 22 32 \n",
"5 Manuscript Writing Writing 2023-07-17 2023-09-04 14 63 \n",
"2 Figure 4 Figure 2023-07-15 2023-07-28 12 25 \n",
"1 Figure 3 Figure 2023-07-09 2023-07-14 6 11 \n",
"0 Figure 2 Figure 2023-07-03 2023-07-09 0 6 \n",
"\n",
" days_start_to_end color \n",
"4 19 #E64646 \n",
"3 10 #E64646 \n",
"5 49 #E69646 \n",
"2 13 #E64646 \n",
"1 5 #E64646 \n",
"0 6 #E64646 "
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# This code is derived from: https://towardsdatascience.com/gantt-charts-with-pythons-matplotlib-395b7af72d72\n",
"\n",
"df = pd.DataFrame({\n",
" \"Task\": [\"Figure 2\", \"Figure 3\", \"Figure 4\", \"Figure 5\", \"Figure 6\", \"Manuscript Writing\"],\n",
" \"Type\": [\"Figure\", \"Figure\", \"Figure\", \"Figure\", \"Figure\", \"Writing\"],\n",
" \"Start\": [\"2023-7-3\", \"2023-7-9\", \"2023-7-15\", \"2023-7-25\", \"2023-8-1\", \"2023-7-17\"],\n",
" \"End\": [\"2023-7-9\", \"2023-7-14\", \"2023-7-28\", \"2023-8-4\", \"2023-8-20\", \"2023-9-04\"]\n",
"})\n",
"df['Start'] = pd.to_datetime(df['Start'])\n",
"df['End'] = pd.to_datetime(df['End'])\n",
"# project start date\n",
"proj_start = df.Start.min()\n",
"# number of days from project start to task start\n",
"df['start_num'] = (df.Start-proj_start).dt.days\n",
"# number of days from project start to end of tasks\n",
"df['end_num'] = (df.End-proj_start).dt.days\n",
"# days between start and end of each task\n",
"df['days_start_to_end'] = df.end_num - df.start_num\n",
"\n",
"# Setup the color-dictionary.\n",
"c_dict = {'Figure':'#E64646', 'Writing':'#E69646', 'XXX':'#34D05C', 'YYY':'#34D0C3', 'ZZZ':'#3475D0'}\n",
"def color(row):\n",
" return c_dict[row['Type']]\n",
"df['color'] = df.apply(color, axis=1)\n",
"\n",
"\n",
"df.sort_values('Start', ascending=False, inplace=True)\n",
"df"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "448e108d-0ecf-408a-814e-cf7dbb28a976",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 800x200 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots(1, figsize=(8,2))\n",
"ax.barh(df.Task, df.days_start_to_end, left=df.start_num, color=df.color, height=0.6)\n",
"\n",
"legend_elements = [Patch(facecolor=c_dict[i], label=i) for i in c_dict if i in df.Type.values]\n",
"ax.legend(handles=legend_elements, frameon=False)\n",
"\n",
"\n",
"##### TICKS #####\n",
"\n",
"# This dictates the spacing of the ticks \n",
"tick_space = 6\n",
"\n",
"xticks = np.arange(0, df.end_num.max()+1, tick_space)\n",
"xticks_labels = pd.date_range(proj_start, end=df.End.max()).strftime(\"%m/%d\")\n",
"xticks_minor = np.arange(0, df.end_num.max()+1, 1)\n",
"ax.set_xticks(xticks)\n",
"ax.set_xticks(xticks_minor, minor=True)\n",
"ax.set_xticklabels(xticks_labels[::tick_space], fontsize=8);\n",
"plt.savefig('gannt.png', dpi=300, bbox_inches='tight')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fc6f3de5-ce9b-4aa2-8647-82574b374e30",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Requirements/Design 04-01-2016 26-02-2016
Development 20-02-2016 27-03-2016
Test Planning 27-03-2016 3-04-2016
Testing 30-03-2016 30-04-2016
Bug Fixes 08-04-2016 15-05-2016
Documentation 15-04-2016 08-05-2016
Deployment 15-05-2016 25-05-2016
Final Report 8-05-2016 25-06-2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment