在matplotlib python

时间:2018-08-07 20:31:07

标签: python matplotlib labels gantt-chart

我是使用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>

0 个答案:

没有答案