我是使用matplotlib的新手,并且创建了甘特图。一切正常,直到我尝试为每个栏插入作业标签。
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
import matplotlib.dates
from matplotlib.dates import MINUTELY, HOURLY, WEEKLY,MONTHLY, DateFormatter, rrulewrapper, RRuleLocator
import numpy as np
input = [['TechJob_0_1','0','1','04-01-2016-08-00','04-01-2016-10-00', '1'],
['TechJob_0_2','0','2','04-01-2016-10-00','04-01-2016-12-00', '2'],
['TechJob_1_3','1','3','04-01-2016-08-00','04-01-2016-10-00', '3'],
['TechJob_2_4','2','4','04-01-2016-08-00','04-01-2016-10-00', '4'],
['TechJob_3_5','3','5','04-01-2016-11-00','04-01-2016-13-00',' 5'],
['TechJob_3_6','3','6','04-01-2016-13-00','04-01-2016-17-00', '6'],
['TechJob_4_7','4','7','04-01-2016-08-00','04-01-2016-12-00', '7'],
['TechJob_4_8','4','8','04-01-2016-13-00','04-01-2016-16-30', '8']]
def _create_date(datetxt):
"""Creates the date"""
day,month,year,hour,minute=datetxt.split('-')
date = dt.datetime(int(year), int(month), int(day), int(hour), int(minute))
mdate = matplotlib.dates.date2num(date)
return mdate
def CreateGanttChart(input):
"""
Create gantt charts with matplotlib
Give file name.
"""
ylabels = []
customDates = []
techs = []
jobs = []
skills = []
customDates.append([_create_date(startdate.replace('\n','')),_create_date(enddate.replace('\n',''))])
## Read string array:
for i in range(0, len(input)):
ylabels.append(input[i][0])
techs.append(input[i][1])
jobs.append(input[i][2])
customDates.append([_create_date(input[i][3]),_create_date(input[i][4])])
skills.append(input[i][5])
#Create labels for y axis:
mylabels = []
currenttech = 9999
for t in techs:
if t != currenttech:
mylabels.append('Tech_'+t)
currenttech = t
ilen=len(mylabels)
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)
tech_id=0#'TechJob_0_1'
y_shift=0
print('bar coordinates:')
for i in range(len(ylabels)):
colorB = 'orange'
intensity = 1
start_date,end_date = task_dates[ylabels[i]]
if int(techs[i])!=tech_id:
# print('i!=tech_id:' , int(techs[i]), tech_id, 'dur:', end_date - start_date,' start date:' , start_date)
tech_id=int(techs[i])
y_shift+=0.5
ax.barh((y_shift)+0.5, end_date - start_date, left=start_date, height=0.3, align='center', edgecolor='lightgreen', color=colorB, alpha = intensity, tick_label=1)
print((y_shift)+0.5, end_date - start_date)
# ax.text((y_shift)+0.5, end_date - start_date, 'hello')
locsy, labelsy = plt.yticks(pos,mylabels)
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()
myFmt = DateFormatter("%d")
ax.xaxis.set_major_formatter(myFmt)
ax.xaxis.set_major_locator(myFmt)
ax.xaxis.set_major_formatter(myFmt)
rule = rrulewrapper(MINUTELY, interval=15)
loc = RRuleLocator(rule)
#print bar labels
rects = ax.patches
# For each bar: Place a label
print('label coordinates:')
for rect in rects:
# Get X and Y placement of label from rect.
x_value = rect.get_width()
y_value = rect.get_y() + rect.get_height() / 2
# Number of points between bar and label. Change to your liking.
space = .5
# Vertical alignment for positive values
ha = 'center'
# If value of bar is negative: Place label left of bar
if x_value < 0:
# Invert space to place label to the left
space *= -1
# Horizontally align label at right
ha = 'center'
# Use X value as label and format number with one decimal place
label = "Job_no."
#print labels:
ax.text(y_value, x_value, label,
horizontalalignment='center',
verticalalignment='center',
transform=ax.transAxes)
# ax.text(y_value, x_value, label)
print(y_value, x_value)
#########################################
#formatter = DateFormatter("%d-%b '%y")
formatter = DateFormatter("%H:%M")
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('gantt.svg')
plt.show()
if __name__ == '__main__':
fname="ganttinput.txt"
CreateGanttChart(input)
问题是,即使文件中的两个打印输出显示坐标相同,像这样打印条形标签也不会使它们显示在正确的位置。 我认为这可能与本部分提供的其他输入元素有关:
#print labels:
ax.text(y_value, x_value, label,
horizontalalignment='center',
verticalalignment='center')
但是,如果我将它们取出,则会出现如下错误:
self._renderer = _RendererAgg(int(width), int(height), dpi)
ValueError: Image size of -2104728849x439 pixels is too large. It must be less than 2^16 in each direction.
<Figure size 1440x576 with 1 Axes>