def plot_attAUC(GT, attributepattern, clf): AUC = [] P = np.loadtxt(attributepattern) attributes = get_attributes() # Loading ground truth test_index = bzUnpickle('./CreatedData/test_features_index.txt') test_attributes = get_class_attributes('./Classes/', name='test') _, y_true = create_data('./CreatedData/test_featuresVGG19.pic.bz2', test_index, test_attributes) for i in range(y_true.shape[1]): fp, tp, _ = roc_curve(y_true[:, i], P[:, i]) roc_auc = auc(fp, tp) AUC.append(roc_auc) print("Mean attrAUC %g" % (np.nanmean(AUC))) xs = np.arange(y_true.shape[1]) width = 0.5 fig = plt.figure(figsize=(15, 5)) ax = fig.add_subplot(1, 1, 1) rects = ax.bar(xs, AUC, width, align='center') ax.set_xticks(xs) ax.set_xticklabels(attributes, rotation=90) ax.set_ylabel("area under ROC curve") autolabel(rects, ax) plt.savefig('results/AwA-AttAUC-DAP-%s.pdf' % clf)
def _draw_compare_area_bar(self, ax, ibtracs_area, era5_area, tc_row): labels = ['R34 area', 'R50 area', 'R64 area'] x = np.arange(len(labels)) # the label locations width = 0.35 # the width of the bars rects1 = ax.bar(x - width / 2, ibtracs_area, width, label='IBTrACS') rects2 = ax.bar(x + width / 2, era5_area, width, label='ERA5') self._set_bar_title_and_so_on(ax, tc_row, labels, x) utils.autolabel(ax, rects1) utils.autolabel(ax, rects2)
def retraining_accuracy_barchart(model, dataset, unrotated_accuracies, rotated_accuracies, labels, savefig=True): import os assert len(unrotated_accuracies) == len(rotated_accuracies) == len(labels) unrotated_accuracies = np.array(unrotated_accuracies) rotated_accuracies = np.array(rotated_accuracies) n = len(labels) fig, ax = plt.subplots(figsize=(20, 8), dpi=150) bar_width = 0.2 index = np.arange(n) - np.arange(n) * bar_width * 2.5 opacity = 0.4 rects1 = ax.bar(index, unrotated_accuracies, bar_width, alpha=opacity, color='b', label="Test unrotated") rects2 = ax.bar(index + bar_width, rotated_accuracies, bar_width, alpha=opacity, color='r', label="Test rotated") fontsize = 15 ax.set_ylim(0, 1.19) ax.set_xlabel('Layers retrained', fontsize=fontsize + 2) ax.set_ylabel('Test accuracy', fontsize=fontsize + 2) ax.set_title( f'Accuracy on test sets after retraining for {model} on {dataset}.', fontsize=fontsize + 4) ax.set_xticks(index + bar_width / 2) ax.set_xticklabels(labels, fontsize=fontsize) ax.legend(loc="upper center", fontsize=fontsize + 2) autolabel(rects1, ax, fontsize=fontsize) autolabel(rects2, ax, fontsize=fontsize) fig.tight_layout() path = os.path.join("plots/", f"retraining_{model}_{dataset}.png") if savefig: plt.savefig(path) plt.show() return path
def train_test_accuracy_barchart(model_name, dataset_name, accuracies, savefig): import os # Accuracies: | Train unrotated | Train rotated # Test unrotated | | # Test rotated | | # assert (accuracies.shape == (2, 2)) fig, ax = plt.subplots() index = np.arange(2) bar_width = 0.3 opacity = 0.4 rects1 = ax.bar(index, accuracies[0, :], bar_width, alpha=opacity, color='b', label="Test unrotated") rects2 = ax.bar(index + bar_width, accuracies[1, :], bar_width, alpha=opacity, color='r', label="Test rotated") ax.set_ylim(0, 1.19) # ax.set_xlabel('Training scheme') ax.set_ylabel('Test accuracy') ax.set_title(f'Final accuracy on test sets.') ax.set_xticks(index + bar_width / 2) ax.set_xticklabels(("Train unrotated", "Train rotated")) ax.legend(loc="upper center") autolabel(rects1, ax) autolabel(rects2, ax) fig.tight_layout() path = os.path.join(experiment_plot_path(model_name, dataset_name), f"train_test.png") if savefig: plt.savefig(path) plt.show() return path
def plot_realdata_comm(datas, configs): def calculate_real_comms(data, bs): times = [bs / ((d / 2) / 2**(i - 1)) for i, d in enumerate(data)] comp = times[0] comms = [t - times[0] for t in times[1:]] return comp, comms fig, ax = plt.subplots(figsize=(4.8, 3.4)) count = len(datas[0][1:]) ind = np.arange(count) width = 0.25 s = -int(count / 2) print('s: ', s) margin = 0.05 xticklabels = [str(2**(i + 1)) for i in range(count)] s = (1 - (width * count + (count - 1) * margin)) / 2 + width ind = np.array([s + i + 1 for i in range(count)]) centerind = None labels = ['WF.', 'S.E.', 'M.W.'] for i, data in enumerate(datas): comp, comms = calculate_real_comms(data, configs[1]) comps = [comp for j in comms] newind = ind + s * width + (s + 1) * margin p1 = ax.bar(newind, comps, width, color=Color.comp_color, hatch='x', label='Comp.') p2 = ax.bar(newind, comms, width, bottom=comps, color=Color.comm_color, label='Comm.') s += 1 autolabel(p2, ax, labels[i], 0) print('comp: ', comp) print('comms: ', comms) print('') rects = ax.patches ax.text(10, 10, 'ehhlo', color='b') handles, labels = ax.get_legend_handles_labels() #ax.legend([handles[0][0]], [labels[0][0]], ncol=2) print(labels) print(handles) ax.set_xlim(left=1 + 0.3) ax.set_ylim(top=ax.get_ylim()[1] * 1.3) ax.set_xticks(ind + 2 * (width + margin)) ax.set_xticklabels(xticklabels) ax.set_xlabel('# of nodes') ax.set_ylabel('Time [s]') update_fontsize(ax, 14) ax.legend((p1[0], p2[0]), (labels[0], labels[1]), ncol=2, handletextpad=0.2, columnspacing=1.) fig.subplots_adjust(left=0.16, right=0.96, bottom=0.17, top=0.94) #plt.savefig('%s/comm%sreal.pdf' % (OUTPUT_PATH, configs[0].lower())) plt.show()
def animate(): aid_list = [] bad_list = [] good_list = [] neutral_list = [] humour_list_names = ["bad_list", "good_list", "neutral_list"] count_list = [] # BEGIN SOCKET_INIT sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) hostname = socket.gethostname() # fully qualified domain name fqdn = socket.getfqdn() ip_address = socket.gethostbyname(hostname) port = METRICS_SOCKETS["metric4"]["port"] print(f"server working on {hostname} {fqdn} with {ip_address}") server_sckt = (ip_address, port) print(f"starting up on {server_sckt[0]} port {server_sckt[1]}") sckt.bind(server_sckt) sckt.listen(1) print("waiting for a connection") # END SOCKET_INIT # we initialize the dataset that we gonna plot try: # show who connected to us connection, client_address = sckt.accept() print("connection from", client_address) while True: # listening to incomming data through socket connection # and integrate them to the graph in realtime data = connection.recv(1024) if data: # output received data unserialised_data = pickle.loads(data) # print("received:", unserialised_data) humour_list_as_string = unserialised_data[1].lower() + "_list" try: i = aid_list.index(unserialised_data[2]) humour_list = eval(humour_list_as_string) humour_list[i] = unserialised_data[3] except Exception as exception: aid_list.append(unserialised_data[2]) j = humour_list_names.index(humour_list_as_string) eval(humour_list_names[j]).append(unserialised_data[3]) tmp_list = humour_list_names[:j] tmp_list.extend(humour_list_names[j+1:]) for __, hl in enumerate(tmp_list): eval(hl).append(0) finally: assert len(aid_list) == len(bad_list) assert len(aid_list) == len(good_list) assert len(aid_list) == len(neutral_list) count_list = [sum(count) for count in zip(good_list, bad_list, neutral_list)] print("aid_list:", M, aid_list, W) print("bad_list:", M, bad_list, W) print("good_list:", M, good_list, W) print("neutral_list:", M, neutral_list, W) totals = [i+j+k for i,j,k in zip(bad_list, good_list, neutral_list)] good_bar = [i / j * 100 for i,j in zip(good_list, totals)] bad_bar = [i / j * 100 for i,j in zip(bad_list, totals)] neutral_bar = [i / j * 100 for i,j in zip(neutral_list, totals)] count_bar = [0.5 for i in range(len(aid_list))] good_rect = plt.bar(aid_list, good_bar, color=BARS_COLOR[2], edgecolor='white', width=BAR_WIDTH, label="Good comment %") bad_rect = plt.bar(aid_list, bad_bar, bottom=good_bar, color=BARS_COLOR[1], edgecolor='white', width=BAR_WIDTH, label="Bad comment %") neutral_rect = plt.bar(aid_list, neutral_bar, bottom=[i+j for i,j in zip(good_bar, bad_bar)], color=BARS_COLOR[0], edgecolor='white', width=BAR_WIDTH, label="Neutral comment %") count_rect = plt.bar(aid_list, count_bar, bottom=[i+j+k for i,j,k in zip(good_bar, bad_bar, neutral_bar)], color='black', edgecolor='white', width=BAR_WIDTH) autolabel(plt, count_rect, count_list) plt.xticks(aid_list) plt.yticks(range(0,101,10)) plt.xlabel("Identifiants de articles") plt.ylabel("Pourcentage humour") plt.legend(bbox_to_anchor=(0,1.02,1,0.2), loc="lower left", mode="expand", borderaxespad=0, ncol=3) fig.canvas.draw() plt.cla() else: # no more data -- quit the loop print ("no more data.") # break finally: # clean up the connection # connection.close() pass
# save random forest stats for final plotting accuracy_lst.append(accuracy) mathews_cc_lst.append(mathew_cc_forest) # delete directory to free space for next fold shutil.rmtree(tar_extract_path + tar_name) # Plotting accuracy and mathews cc labels = ['Fold 1', 'Fold 2', 'Fold 3', 'Fold 4', 'Fold 5'] x = np.arange(len(labels)) width = 0.35 fig, ax = plt.subplots() rects1 = ax.bar(x - width / 2, accuracy_lst, width, label='acc') rects2 = ax.bar(x + width / 2, mathews_cc_lst, width, label='mathew') # Add some text for labels, title and custom x-axis tick labels, etc. ax.set_ylabel('Scores') ax.set_title('Accuracy and Mathews Correlation Coefficient') ax.set_xticks(x) ax.set_xticklabels(labels) ax.legend() autolabel(rects1) autolabel(rects2) plt.ylim([0, 1]) fig.tight_layout() plt.savefig('randomforest-acc-mathewscc.png', dpi=2000, bbox_inches="tight") # plt.show()
index=df1.index.date, columns=['BM'], aggfunc=np.sum, fill_value=0) # Pandas bar plot doesn't work out of box, see link below # https://stackoverflow.com/questions/49269927/missing-bars-in-matplotlib-bar-chart rects_bm = plt.bar( by_date.index, by_date[True].values, bottom=by_date[False].values, # width=0.3, label='breast milk', color='g') rects_f = plt.bar( by_date.index, by_date[False].values, label='formula', color='r') utils.autolabel(rects_bm, rects_f) plt.ylabel('Feed (oz)') plt.legend(loc='upper left') utils.set_y_major(10) # ------------ plot daily feeding pattern ----------------- # ax4 = plt.subplot2grid((6, 1), (3, 0), rowspan=3, sharex=ax2) # ax4 = plt.subplot(212, sharex=ax2) ax4 = fig.add_subplot(gs[3], sharex=ax2) bm = df1.loc[df1.BM] formula = df1.loc[df1.BM == False] for d, color, text in zip([bm, formula], ['g', 'r'], ['breast milk', 'formula']): date = d.index.date times = d.index.time
def plot_breakdown(): FONTSIZE = 16 names = [ 'FF & BP', 'GradComm', 'FactorComp', 'FactorComm', 'InverseComp', 'InverseComm' ] colors = [ Color.backward_color, Color.comm_color, Color.lars_color, Color.io_color, Color.compression_color, Color.synceasgd_color ] sgd = [0.132, 0, 0, 0, 0, 0] ssgd = [0.132, 0.067, 0, 0, 0, 0] kfac = [0.132, 0, 0.205, 0, 0, 0.15, 0] dkfac = [ 0.132, 0.199 - 0.132, 0.404 - 0.199, 0.704 - 0.404, 0.736 - 0.704, 0.882 - 0.736 ] #names = ['FF & BP', 'Compression', 'Communication', 'LARS'] #colors = [Color.backward_color, Color.compression_color, Color.comm_color, Color.lars_color] #densesgd = [0.204473, 0, 0.24177, 0.01114] #topksgd = [0.204473, 0.239, 0.035, 0.01114] #densesgd96 = [0.054376, 0, 0.366886, 0.012794] #topksgd96 = [0.054376, 0.239, 0.035, 0.012794] fig, ax = plt.subplots(figsize=(4.8, 4.4)) count = 2 ind = np.arange(count) width = 0.28 margin = 0.02 xticklabels = ['SGD', 'KFAC'] newind = np.arange(count).astype(np.float32) bars = [] bottom = np.array([0, 0]).astype(np.float32) for i in range(len(sgd)): label = names[i] data = [sgd[i], kfac[i]] p1 = ax.bar(newind, data, width, bottom=bottom, color=colors[i], label=label, edgecolor='black') bottom += np.array(data) bars.append(p1[0]) utils.autolabel(p1, ax, r'1 GPU', 0, 10) newind += width + margin bottom = 0 for i in range(len(sgd)): label = names[i] data = [ssgd[i], dkfac[i]] p1 = ax.bar(newind, data, width, bottom=bottom, color=colors[i], label=label, edgecolor='black') bottom += np.array(data) utils.autolabel(p1, ax, r'64 GPUs', 0, 10) #bars.append(p1[0]) handles, labels = ax.get_legend_handles_labels() #ax.legend([handles[0][0]], [labels[0][0]], ncol=2) print(labels) print(handles) #ax.set_xlim(right=2.5) ax.set_ylim(top=ax.get_ylim()[1] * 1.05) ax.set_xticks(newind - (width + margin) / 2) ax.set_xticklabels(xticklabels) #ax.set_xlabel('Model') ax.set_ylabel('Time [s]') utils.update_fontsize(ax, FONTSIZE) ax.legend(tuple(bars), tuple(names), loc='center left', bbox_to_anchor=(1, 0.5), fontsize=FONTSIZE) #, handletextpad=0.2, columnspacing =1.) #fig.subplots_adjust(left=0.16, right=0.96, bottom=0.19, top=0.94) #plt.savefig('%s/naive-breakdown.pdf' % (OUTPUT_PATH), bbox_inches='tight') plt.show()
def plot_breakdown_bwp(): fig, ax = plt.subplots(figsize=(7.0, 4.4)) FONTSIZE = 12 names = ['InverseComp', 'InverseComm'] colors = [Color.inverse_color, Color.inversecomm_color] xticklabels = ['ResNet-50', 'ResNet-152', 'DenseNet-201', 'Inception-v4'] dnns = ['resnet50', 'resnet152', 'densenet201', 'inceptionv4'] #algos = ['dkfac', 'dkfac-mp', 'spd-kfac'] #algos = ['mpd-kfac', 'spd-kfac'] algos = ['algo1', 'algo2', 'algo3'] labels = ['Non-Dist', 'Seq-Dist', 'LBP'] data = { 'resnet50': { 'algo1': [0.2742, 0.2742], 'algo2': [0.0512, 0.1852], 'algo3': [0.1049, 0.1691], }, 'resnet152': { 'algo1': [0.6759, 0.6759], 'algo2': [0.0539, 0.4917], 'algo3': [0.2814, 0.4271], }, 'densenet201': { 'algo1': [0.4818, 0.4818], 'algo2': [0.0352, 0.5032], 'algo3': [0.4023, 0.4373], }, 'inceptionv4': { 'algo1': [0.4306, 0.4306], 'algo2': [0.0487, 0.3926], 'algo3': [0.2539, 0.3272], }, } count = len(dnns) width = 0.2 margin = 0.02 s = (1 - (width * count + (count - 1) * margin)) / 2 + width ind = np.array([s + i + 1 for i in range(count)]) for i, algo in enumerate(algos): newind = ind + s * width + (s + 1) * margin bp = [] gradcomm = [] factorcomp = [] factorcomm = [] inversecomp = [] inversecomm = [] one_group = [[] for ii in range(len(names))] for dnn in dnns: d = data[dnn] ald = d[algo] t0 = 0.0 for j, t in enumerate(ald): one_group[j].append(t - t0) t0 = t legend_p = [] bottom = np.array([0.0] * len(one_group[0])) for k, d in enumerate(one_group): color = colors[k] label = names[k] p = ax.bar(newind, d, width, bottom=bottom, color=color, edgecolor='black', label=label) legend_p.append(p[0]) bottom += np.array(d) s += 1 #ax.text(4, 4, 'ehhlo', color='b') utils.autolabel(p, ax, labels[i], 90, FONTSIZE - 2) ax.set_ylim(top=ax.get_ylim()[1] * 1.25) handles, labels = ax.get_legend_handles_labels() ax.legend(legend_p, names, ncol=1, handletextpad=0.2, columnspacing=1., loc='upper right', fontsize=FONTSIZE) ax.set_ylabel('Time [s]') #ax.set_xticks(newind-width-margin/2) ax.set_xticks(newind - width * 2 / 2 - margin * 2 / 2) ax.set_xticklabels(xticklabels) utils.update_fontsize(ax, FONTSIZE) plt.savefig('%s/bwp-timebreakdown.pdf' % (OUTPUT_PATH), bbox_inches='tight')
def plot_breakdown_pipelining(): fig, ax = plt.subplots(figsize=(7.0, 4.4)) FONTSIZE = 12 names = ['FactorComp', 'FactorComm'] colors = [Color.factor_color, Color.factorcomm_color] xticklabels = ['ResNet-50', 'ResNet-152', 'DenseNet-201', 'Inception-v4'] dnns = ['resnet50', 'resnet152', 'densenet201', 'inceptionv4'] #algos = ['dkfac', 'dkfac-mp', 'spd-kfac'] #algos = ['mpd-kfac', 'spd-kfac'] algos = ['mpd-kfac', 'lw-wo-tf', 'lw-wi-ttf', 'sp-wi-otf'] labels = ['Naive', 'LW w/o TF', 'LW w/ TTF', 'SP w/ OTF'] data = { 'resnet50': { 'mpd-kfac': [0.2115, 0.3814], 'lw-wo-tf': [0.2115, 0.4174], 'lw-wi-ttf': [0.2115, 0.3401], 'sp-wi-otf': [0.2115, 0.3096], }, 'resnet152': { 'mpd-kfac': [0.1927, 0.6285], 'lw-wo-tf': [0.1927, 0.7158], 'lw-wi-ttf': [0.1927, 0.5371], 'sp-wi-otf': [0.1927, 0.4687], }, 'densenet201': { 'mpd-kfac': [0.3163, 0.6665], 'lw-wo-tf': [0.3163, 0.7714], 'lw-wi-ttf': [0.3163, 0.5841], 'sp-wi-otf': [0.3163, 0.5600], }, 'inceptionv4': { 'mpd-kfac': [0.1979, 0.4882], 'lw-wo-tf': [0.1979, 0.6683], 'lw-wi-ttf': [0.1979, 0.4115], 'sp-wi-otf': [0.1979, 0.3967], }, } count = len(dnns) width = 0.2 margin = 0.02 s = (1 - (width * count + (count - 1) * margin)) / 2 + width ind = np.array([s + i + 1 for i in range(count)]) for i, algo in enumerate(algos): newind = ind + s * width + (s + 1) * margin bp = [] gradcomm = [] factorcomp = [] factorcomm = [] inversecomp = [] inversecomm = [] one_group = [[] for ii in range(len(names))] for dnn in dnns: d = data[dnn] ald = d[algo] t0 = 0.0 for j, t in enumerate(ald): one_group[j].append(t - t0) t0 = t legend_p = [] bottom = np.array([0.0] * len(one_group[0])) for k, d in enumerate(one_group): color = colors[k] label = names[k] p = ax.bar(newind, d, width, bottom=bottom, color=color, edgecolor='black', label=label) legend_p.append(p[0]) bottom += np.array(d) s += 1 #ax.text(4, 4, 'ehhlo', color='b') utils.autolabel(p, ax, labels[i], 90, FONTSIZE - 2) ax.set_ylim(top=ax.get_ylim()[1] * 1.25) handles, labels = ax.get_legend_handles_labels() ax.legend(legend_p, names, ncol=1, handletextpad=0.2, columnspacing=1., loc='upper left', fontsize=FONTSIZE) ax.set_ylabel('Time [s]') #ax.set_xticks(newind-width-margin/2) ax.set_xticks(newind - width * 3 / 2 - margin * 3 / 2) ax.set_xticklabels(xticklabels) utils.update_fontsize(ax, FONTSIZE) plt.savefig('%s/pipelining-timebreakdown.pdf' % (OUTPUT_PATH), bbox_inches='tight')
def plot_breakdown_spdkfac(): fig, ax = plt.subplots(figsize=(7.0, 4.4)) FONTSIZE = 12 names = [ 'FF & BP', 'GradComm', 'FactorComp', 'FactorComm', 'InverseComp', 'InverseComm' ] colors = [ Color.backward_color, Color.comm_color, Color.factor_color, Color.factorcomm_color, Color.inverse_color, Color.inversecomm_color ] xticklabels = ['ResNet-50', 'ResNet-152', 'DenseNet-201', 'Inception-v4'] dnns = ['resnet50', 'resnet152', 'densenet201', 'inceptionv4'] #algos = ['dkfac', 'dkfac-mp', 'spd-kfac'] algos = ['dkfac', 'mpd-kfac', 'spd-kfac'] labels = ['D-KFAC', 'MPD-KFAC', 'SPD-KFAC'] data = { 'resnet50': # [compute, communicate gradient, compute factor, communicate factor, compute inverse, communicate inverse] { 'dkfac': [0.132, 0.1968, 0.4083, 0.5783, 0.8525, 0.8525], 'mpd-kfac': [0.132, 0.1968, 0.4083, 0.5783, 0.6295, 0.7635], 'spd-kfac': [0.132, 0.1968, 0.4083, 0.5064, 0.6114, 0.6755], }, 'resnet152': { 'dkfac': [0.1140, 0.2730, 0.4657, 0.9048, 1.5807, 1.5807], 'mpd-kfac': [0.1140, 0.2730, 0.4657, 0.9016, 0.9555, 1.3933], 'spd-kfac': [0.1140, 0.2730, 0.4657, 0.7417, 1.0231, 1.1689], }, 'densenet201': { 'dkfac': [0.178, 0.3643, 0.6829, 1.0146, 1.4964, 1.4964], 'mpd-kfac': [0.178, 0.3643, 0.6806, 1.0308, 1.0660, 1.5340], 'spd-kfac': [0.178, 0.3643, 0.6806, 0.9243, 1.3266, 1.3615], }, 'inceptionv4': { 'dkfac': [0.134, 0.2669, 0.4648, 0.7551, 1.1857, 1.1857], 'mpd-kfac': [0.134, 0.2669, 0.4597, 0.7547, 0.8034, 1.1473], 'spd-kfac': [0.134, 0.2669, 0.4597, 0.6635, 0.9174, 0.9907], }, } def Smax(times): tf = times[0] tb = times[1] tc = times[2] r = tc / tb s = 1 + 1.0 / (tf / min(tc, tb) + max(r, 1. / r)) return s count = len(dnns) width = 0.2 margin = 0.02 s = (1 - (width * count + (count - 1) * margin)) / 2 + width ind = np.array([s + i + 1 for i in range(count)]) for ia, algo in enumerate(algos): newind = ind + s * width + (s + 1) * margin bp = [] gradcomm = [] factorcomp = [] factorcomm = [] inversecomp = [] inversecomm = [] one_group = [[] for i in range(len(names))] for dnn in dnns: d = data[dnn] ald = d[algo] t0 = 0.0 for j, t in enumerate(ald): one_group[j].append(t - t0) t0 = t legend_p = [] bottom = np.array([0.0] * len(one_group[0])) for k, d in enumerate(one_group): color = colors[k] label = names[k] p = ax.bar(newind, d, width, bottom=bottom, color=color, edgecolor='black', label=label) legend_p.append(p[0]) bottom += np.array(d) s += 1 #ax.text(4, 4, 'ehhlo', color='b') utils.autolabel(p, ax, labels[ia], 90, FONTSIZE - 2) ax.set_ylim(top=ax.get_ylim()[1] * 1.3) handles, labels = ax.get_legend_handles_labels() ax.legend(legend_p, names, ncol=3, handletextpad=0.2, columnspacing=1., loc='upper center', fontsize=FONTSIZE, bbox_to_anchor=[0.5, 1.2]) ax.set_ylabel('Time [s]') #ax.set_xticks(newind-width-margin/2) #ax.set_xticks(newind-width/2-margin/2) ax.set_xticks(newind - width * 2 / 2 - margin * 2 / 2) ax.set_xticklabels(xticklabels) utils.update_fontsize(ax, FONTSIZE) plt.savefig('%s/spdkfac-vs-mpd-fac-timebreakdown.pdf' % (OUTPUT_PATH), bbox_inches='tight')