1

I'm implementing a time schedule associated with business hour (8am to 5pm) using pd.offsets.CustomBusinessHour and attempting to plot the gantt chart or horizonal bar chart using matplotlib. At this point, I want to cut off the interval between x-axis ticks out of business hour which is unnecessary. It seems like breaking hours exist between 5pm of d-day and 8am of d+1 day

(As-Is) Chart Image (To-Be) Chart Image

I searched parameter configuration of BusinessHour method, way of tick setting using keyword 'interval', 'spacing', however I couldn't find appropriate solution. I considered other plotting approaches using matplotlib.dates module but the result was in vain.

And this is my python code.

import pandas as pd
from datetime import datetime, date, timedelta, time
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.dates as mdates

num = 6

start_time = datetime(2021, 7, 7, 13, 5, 16, 268902)
int_to_time = pd.offsets.CustomBusinessHour(start="08:00", end="17:00", weekmask="1111111")

duration = num * int_to_time

horizon = [start_time + (i+1) * int_to_time for i in range(num+1)]
horizon = [i.replace(microsecond=0) for i in horizon]

fig, gnt = plt.subplots(figsize=(12,3))

gnt.barh(y=1, width=duration, left=start_time, color="cyan", height=0.2)

gnt.set_xticks(horizon)
gnt.set_xticklabels(horizon, rotation=90)

gnt.tick_params(bottom=False, labelbottom=False, top=True, labeltop=True)

plt.show()
Alex
  • 6,610
  • 3
  • 20
  • 38

1 Answers1

0

You are trying to develop a Gantt chart and are having issues with spacing of the x axis labels. Your x-axis is representing Timestamps and you want them evenly spaced out (hourly).

Axis tick locations are determined by Tick Locators and the labels are determined by Tick Formatters. The default tick locator for datetimes is AutoDatesLocator which is likely implementing HourLocator. This will return x and y values that correspond to a 24 hour date time axis.

One solution to your problem is to simply use LinearLocator or FixedLocator along with a FixedFormatter. This puts you in very direct control over the tick locations and labels.

I must add that there are many tutorials and posts about how to make a Gantt chart with matplotlib or plotly that are easily searchable. I recommend reviewing some of those as you develop your plots.

The solution is implemented below in the context of your code.

enter image description here

import pandas as pd
from datetime import datetime, date, timedelta, time
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.dates as mdates

num = 6

start_time = datetime(2021, 7, 7, 13, 5, 16, 268902)
int_to_time = pd.offsets.CustomBusinessHour(start="08:00", end="17:00", weekmask="1111111")

duration = num * int_to_time

horizon = [start_time + (i+1) * int_to_time for i in range(num+1)]
horizon = [i.replace(microsecond=0) for i in horizon]

fig, gnt = plt.subplots(figsize=(12,3))

gnt.barh(y=1, width=duration, left=start_time, color="cyan", height=0.2)

gnt.xaxis.set_major_locator(ticker.LinearLocator(7))
gnt.xaxis.set_major_formatter(ticker.FixedFormatter(horizon))

gnt.tick_params(bottom=False, labelbottom=False, top=True, labeltop=True, rotation=90)
Coup
  • 695
  • 4
  • 6
  • 1
    Thank you for your kind reply, Coup. I was aware of locator and formatter usage, but at this time I come to understand how to handle them specifically thanks to you. – Nam-kyoung Lee Jul 09 '21 at 22:27