def rama_pmf(data, A, C, **kw): pt_dd = U.get_pt_dd(C, A.property, A.plot_type, A.v) if not pt_dd: # if there is no rama_pmf, search for rama instead, this is trying to # reduce duplication in .xitconfig.yaml pt_dd = U.get_pt_dd(C, A.property, 'rama', A.v) logger.info(pt_dd) ncol, nrow = U.gen_rc(len(data.keys()), pt_dd) fig, axes = plt.subplots(nrows=nrow, ncols=ncol, figsize=(ncol * 7, nrow * 6)) # to make the data type consistent for following analysis. # by the way, this is a very wiredly behaved api --2013-08-07 # http://matplotlib.org/api/pyplot_api.html?highlight=subplots#matplotlib.pyplot.subplots if isinstance(axes, np.ndarray): axes = axes.flat elif isinstance(axes, Subplot): axes = [axes] if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) if 'bins' in pt_dd: bins = np.arange(*pt_dd.get('bins')) else: bins = np.arange(-180, 171, 4) logger.info('bins:\n {0}'.format(bins)) normed = pt_dd.get('normed', False) gk_xypmfs = [] min_, max_ = get_min_max(data, bins, normed, gk_xypmfs) logger.info("min: {0}; max: {1}".format(min_, max_)) for c, (gk, phi_edges, psi_edges, h_pmf) in enumerate(gk_xypmfs): ax = axes[c] cmap = getattr(cm, pt_dd.get('cmap', 'jet')) cmap.set_over('white') params = get_params(gk, pt_dd) logger.info('params: {0}'.format(params)) F = U.timeit(ax.contourf) contour = F(phi_edges, psi_edges, h_pmf, **params) decorate_ax(ax, pt_dd, ncol, nrow, c, gk, A) cax = fig.add_axes([0.92, 0.2, 0.02, 0.6]) # left, bottom, width, hight cbar = plt.colorbar(contour, cax=cax) if 'cbar_ylabel' in pt_dd: cbar.ax.set_ylabel(**pt_dd['cbar_ylabel']) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def rama_pmf(data, A, C, **kw): pt_dd = U.get_pt_dd(C, A.property, A.plot_type, A.v) if not pt_dd: # if there is no rama_pmf, search for rama instead, this is trying to # reduce duplication in .xitconfig.yaml pt_dd = U.get_pt_dd(C, A.property, 'rama', A.v) logger.info(pt_dd) ncol, nrow = U.gen_rc(len(data.keys()), pt_dd) fig, axes = plt.subplots(nrows=nrow, ncols=ncol, figsize=(ncol*7, nrow*6)) # to make the data type consistent for following analysis. # by the way, this is a very wiredly behaved api --2013-08-07 # http://matplotlib.org/api/pyplot_api.html?highlight=subplots#matplotlib.pyplot.subplots if isinstance(axes, np.ndarray): axes = axes.flat elif isinstance(axes, Subplot): axes = [axes] if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) if 'bins' in pt_dd: bins = np.arange(*pt_dd.get('bins')) else: bins = np.arange(-180, 171, 4) logger.info('bins:\n {0}'.format(bins)) normed = pt_dd.get('normed', False) gk_xypmfs = [] min_, max_ = get_min_max(data, bins, normed, gk_xypmfs) logger.info("min: {0}; max: {1}".format(min_, max_)) for c, (gk, phi_edges, psi_edges, h_pmf) in enumerate(gk_xypmfs): ax = axes[c] cmap = getattr(cm, pt_dd.get('cmap', 'jet')) cmap.set_over('white') params = get_params(gk, pt_dd) logger.info('params: {0}'.format(params)) F = U.timeit(ax.contourf) contour = F(phi_edges, psi_edges, h_pmf, **params) decorate_ax(ax, pt_dd, ncol, nrow, c, gk, A) cax = fig.add_axes([0.92, 0.2, 0.02, 0.6]) # left, bottom, width, hight cbar = plt.colorbar(contour, cax=cax) if 'cbar_ylabel' in pt_dd: cbar.ax.set_ylabel(**pt_dd['cbar_ylabel']) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def mp_alx(data, A, C, **kw): """alx for multiple properties (mp)""" pt_dd = U.get_pt_dd(C, '_'.join(A.properties), A.plotmp_type) dsets = grp_datasets(data, pt_dd) fig = plt.figure(figsize=(12, 9)) if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) ncol, nrow = U.gen_rc(len(dsets.keys()), pt_dd) logger.info('Chosen # of cols: {0}, # of rows; {1}'.format(ncol, nrow)) for c, sys_key in enumerate(dsets.keys()): ax = fig.add_subplot(nrow, ncol, c + 1) for prop_key in dsets[sys_key]: da = dsets[sys_key][prop_key] params = get_params(sys_key, prop_key, pt_dd, c) ax.plot(da[0], da[1], **params) ax.fill_between(da[0], da[1] - da[2], da[1] + da[2], where=None, facecolor=params.get('color'), alpha=.3) if 'texts' in pt_dd: ax.text(**U.get_param(pt_dd['texts'], sys_key)) decorate_ax(ax, pt_dd, ncol, nrow, c) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def mp_alx(data, A, C, **kw): """alx for multiple properties (mp)""" pt_dd = U.get_pt_dd(C, '_'.join(A.properties), A.plotmp_type) dsets = grp_datasets(data, pt_dd) fig = plt.figure(figsize=(12,9)) if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) ncol, nrow = U.gen_rc(len(dsets.keys()), pt_dd) logger.info('Chosen # of cols: {0}, # of rows; {1}'.format(ncol, nrow)) for c, sys_key in enumerate(dsets.keys()): ax = fig.add_subplot(nrow, ncol, c+1) for prop_key in dsets[sys_key]: da = dsets[sys_key][prop_key] params = get_params(sys_key, prop_key, pt_dd, c) ax.plot(da[0], da[1], **params) ax.fill_between(da[0], da[1]-da[2], da[1]+da[2], where=None, facecolor=params.get('color'), alpha=.3) if 'texts' in pt_dd: ax.text(**U.get_param(pt_dd['texts'], sys_key)) decorate_ax(ax, pt_dd, ncol, nrow, c) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def calc_distr(h5, gk, grp, prop_obj, prop_dd, A, C): grp_tb = fetch_grp_tb(h5, grp, prop_obj.name) min_len = min(tb.read(field='time').shape[0] for tb in grp_tb) _l = [] for tb in grp_tb: _l.append(tb.read(field=prop_obj.ifield)[:min_len]) _la = np.array(_l) # grped_distr_ave is a variant of grped_distr special_cases = {'grped_distr_ave': 'grped_distr'} pt_dd = U.get_pt_dd( C, A.property, special_cases.get(A.plot_type, A.plot_type)) if 'bins' in pt_dd: i, j, s = [float(_) for _ in pt_dd['bins']] bins = np.arange(i, j, s) else: # assume usually 36 bins would be enough bins = np.linspace(_la.min(), _la.max(), 36) ps = [] # probability distributions for each tb for _ in _la: fnormed = pt_dd.get('normed', False) p, __ = np.histogram(_, bins, normed=fnormed) if not fnormed: p = p / float(sum(p)) # unnormed probability ps.append(p) ps = np.array(ps) bn = (bins[:-1] + bins[1:]) / 2. # to gain the same length as psm, pse psm = ps.mean(axis=0) pse = [U.sem(ps[:,i]) for i in xrange(len(ps[0]))] pse = np.array(pse) return np.array([bn, psm, pse])
def grped_omega_distr(data, A, C, **kw): pt_dd = U.get_pt_dd(C, A.property, A.plot_type) dsets = grp_datasets(data, pt_dd) if 'bins' in pt_dd: i, j, s = [float(_) for _ in pt_dd['bins']] else: i, j, s = [-0.1, 1.1, 0.1] bins = np.arange(i, j, s) fig = plt.figure(figsize=pt_dd.get('figsize', (12,9))) if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) ncol, nrow = U.gen_rc(len(dsets.keys()), pt_dd) logger.info('Chosen # of cols: {0}, # of rows; {1}'.format(ncol, nrow)) for c, dsetk in enumerate(dsets): dset = dsets[dsetk] ax = fig.add_subplot(nrow, ncol, c+1) if 'text' in dset: ax.text(s=dset['text'], **pt_dd['text']) for gk in dsets[dsetk]['data']: da = dsets[dsetk]['data'][gk] params = get_params(gk, pt_dd) ax.hist(da, bins=bins, normed=False, alpha=0.3, **params) decorate_ax(ax, pt_dd, ncol, nrow, c) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def imap(data, A, C, **kw): """imap: interaction map""" logger.info('start plotting interaction map...') pt_dd = U.get_pt_dd(C, A.property, A.plot_type) fig = plt.figure(figsize=(12,9)) col, row = U.gen_rc(len(data.keys()), pt_dd) grid = ImageGrid(fig, 111, nrows_ncols = (row, col), axes_pad = 0.3, add_all=True, label_mode = "L") if 'denorminators' in pt_dd: for gk in data: dn = U.get_param(pt_dd['denorminators'], gk) logger.info('denorminator: {0}'.format(dn)) data[gk] = data[gk] / dn # used to set up the reference point and the range of color bar max_ = get_max(data) for k, gk in enumerate(data.keys()): ax = grid[k] da = data[gk] rda = da logger.info('map max: {0}; map min: {1}'.format(rda.max(), rda.min())) # JUST FOR REFERENCE OF SEEING WHERE THE END POINTS ARE, DEBUGGING USES # rda[-1][-1] = max_ # rda[0][-1] = max_ # sophisticated reversal to make x axis donor, y axis acceptor # rda = np.array([i[::-1] for i in da.transpose()[::-1]]) # sophisticated reversal to make x axis acceptor, y axis donor # rda = np.array([i[::-1] for i in da[::-1]]) params = get_params(gk, pt_dd) logger.info(params) # cmap_options: hot, gist_heat, Orange (printer friendly) # remove the info about the Hbonding information about first residue, # which ACE, this make the final map easier to understand rda = np.delete(np.delete(rda, 0, 0), 0, 1) im = ax.pcolormesh(rda, **params) if 'clim' in pt_dd: im.set_clim(**pt_dd['clim']) else: im.set_clim(0, max_) logger.info('shape after removal of the 0th residue: {0}'.format(rda.shape)) ax.set_xlim([0, rda.shape[0]]) ax.set_ylim([0, rda.shape[1]]) ax.minorticks_on() decorate_ax(ax, pt_dd, gk) plt.colorbar(im, shrink=.5, orientation='vertical', anchor=(1.3, 0)) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def grped_bars(data, A, C, **kw): pt_dd = U.get_pt_dd(C, A.property, A.plot_type) grp_REs = pt_dd['grp_REs'] dsets = grp_datasets(data, grp_REs) bar_width = pt_dd.get('bar_width', 1) nbars_per_cluster = len(dsets.keys()) nclusters = len(data) / nbars_per_cluster logger.info('number of clusters: {0}; # bars per cluster: {1}'.format( nclusters, nbars_per_cluster)) cluster_width = bar_width * nbars_per_cluster # space between neigbouring groups of bars spacing = pt_dd.get('spacing', 0.35) xlocs = np.arange(0, nclusters * (cluster_width + spacing), cluster_width + spacing) logger.info('xlocs: {0}'.format(xlocs)) fig = plt.figure() ax = fig.add_subplot(111) rectss = [] # plural of rects for c, dsetk in enumerate(dsets.keys()): dset = dsets[dsetk] for cc, kk in enumerate(dset.keys()): mean = dset[kk][0] std = dset[kk][1] params = get_params(kk, pt_dd) if cc != len(dset.keys()) - 1 and 'label' in params.keys(): # since you just need one legend for all set of bars params.pop('label') xloc = xlocs[cc] + c * bar_width rects = ax.bar(xloc, mean, bar_width, yerr=std, **params) rectss.append(rects) ax.set_xticks(xlocs + cluster_width / 2.) def autolabel(rects): # attach some text labels for rect in rects: height = rect.get_height() ax.text(rect.get_x() + rect.get_width() / 2., 1.05 * height, '%.2f' % float(height), ha='center', va='bottom') f_autolabel = pt_dd.get('f_autolabel', True) if f_autolabel: for rects in rectss: autolabel(rects) decorate_ax(ax, pt_dd) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {})) dsets = OrderedDict( ) # dsets: meaning further grouping, based on which ploting
def grped_bars(data, A, C, **kw): pt_dd = U.get_pt_dd(C, A.property, A.plot_type) grp_REs = pt_dd['grp_REs'] dsets = grp_datasets(data, grp_REs) bar_width = pt_dd.get('bar_width', 1) nbars_per_cluster = len(dsets.keys()) nclusters = len(data) / nbars_per_cluster logger.info('number of clusters: {0}; # bars per cluster: {1}'.format(nclusters, nbars_per_cluster)) cluster_width = bar_width * nbars_per_cluster # space between neigbouring groups of bars spacing = pt_dd.get('spacing', 0.35) xlocs = np.arange(0, nclusters * (cluster_width + spacing), cluster_width + spacing) logger.info('xlocs: {0}'.format(xlocs)) fig = plt.figure() ax = fig.add_subplot(111) rectss = [] # plural of rects for c, dsetk in enumerate(dsets.keys()): dset = dsets[dsetk] for cc, kk in enumerate(dset.keys()): mean = dset[kk][0] std = dset[kk][1] params = get_params(kk, pt_dd) if cc != len(dset.keys()) - 1 and 'label' in params.keys(): # since you just need one legend for all set of bars params.pop('label') xloc = xlocs[cc] + c * bar_width rects = ax.bar(xloc, mean, bar_width, yerr=std, **params) rectss.append(rects) ax.set_xticks(xlocs + cluster_width / 2.) def autolabel(rects): # attach some text labels for rect in rects: height = rect.get_height() ax.text(rect.get_x()+rect.get_width()/2., 1.05*height, '%.2f'%float(height), ha='center', va='bottom') f_autolabel = pt_dd.get('f_autolabel', True) if f_autolabel: for rects in rectss: autolabel(rects) decorate_ax(ax, pt_dd) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {})) dsets = OrderedDict() # dsets: meaning further grouping, based on which ploting
def calc_pmf(h5, gk, grp, prop_obj, prop_dd, A, C): pt_dd = U.get_pt_dd(C, A.property, A.plot_type) if 'bins' not in pt_dd: raise ValueError('bins not found in {0}, but be specified when plotting pmf'.format(A.config)) subgrps = U.split(grp, 10) # 10 is the group_size da = [] for sp in subgrps: bn, psm, pse = calc_distr(h5, '', sp, prop_obj, prop_dd, A, C) pmf, pmf_e = U.prob2pmf(psm, max(psm), pse) for b, i in zip(bn, pmf): print b, i sub_da = np.array([bn, pmf, pmf_e]) da.append(sub_da) return np.array(da)
def distr(data, A, C, **kw): """data: is an OrderedDict""" logger.info('start plotting distr...') pt_dd = U.get_pt_dd(C, A.property, A.plot_type) fig = plt.figure(figsize=pt_dd.get('figsize', (12,9))) if A.merge: ax = fig.add_subplot(111) for c, gk in enumerate(data.keys()): da = data[gk] params = get_params(gk, pt_dd) line = ax.plot(da[0], da[1], **params) # facecolor uses the same color as ax.plot ax.fill_between(da[0], da[1]-da[2], da[1]+da[2], where=None, facecolor=line[0].get_color(), alpha=.3) decorate_ax(ax, pt_dd) else: col, row = U.gen_rc(len(data.keys()), pt_dd) for c, gk in enumerate(data.keys()): ax = fig.add_subplot(row, col, c+1) da = data[gk] params = get_params(gk, pt_dd) # ax.errorbar(da[0], da[1], yerr=da[2], **params) xs, ys, es = da[0], da[1], da[2] # es: errors line = ax.plot(xs, ys, **params) ax.fill_between(xs, ys-es, ys+es, where=None, facecolor=line[0].get_color(), alpha=.3) # do a gaussian fit if pt_dd.get('gaussian_fit'): # maybe it's better to use p0 for curve_fit popt, pcov = curve_fit(gaussian, xs, ys) _, mu, sigma = popt logger.info('mean of the fitted normal distribution: {0}'.format(mu)) new_ys = gaussian(xs, *popt) # pearsonr creates different value from that by calc_r2 # corr, p_val = pearsonr(ys, new_ys) r2 = U.calc_r2(ys, new_ys) ax.plot(xs, new_ys, linewidth="2", color='black', label='r$^2$ = {0:.3f}'.format(r2)) decorate_ax(ax, pt_dd) output = U.gen_output_filename(A, C) logger.info('saving to {0}'.format(output)) plt.savefig(output)
def grped_along_var_2prop(data, A, C, **kw): pt_dd = U.get_pt_dd(C, '_'.join(A.properties), A.plotmp_type) dsets = group_datasets(data, pt_dd['grp_REs']) fig = plt.figure() for c, propi in enumerate(dsets.keys()): i = c+1 # i tracks whether it's prop1 or prop2 subdsets = dsets[propi] if c == 0: ax1 = fig.add_subplot(111) ax_plot(ax1, subdsets, pt_dd, A, i) decorate_ax(ax1, pt_dd, i) else: ax2 = ax1.twinx() ax_plot(ax2, subdsets, pt_dd, A, i) decorate_ax(ax2, pt_dd, i) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def rama(data, A, C, **kw): pt_dd = U.get_pt_dd(C, A.property, A.plot_type, A.v) ncol, nrow = U.gen_rc(len(data.keys()), pt_dd) # ncol * 8 instead of 6 is because color bar will squeeze the subplot # otherwise. fig = plt.figure(figsize=(ncol * 8, nrow * 6)) if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) bins = pt_dd.get('bins', 36) normed = pt_dd.get('normed', False) contours = [] max_ = 0 for c, gk in enumerate(data.keys()): ax = fig.add_subplot(nrow, ncol, c + 1) da = data[gk] phis, psis = da h, phip, psip = np.histogram2d(psis, phis, range=[[-180, 180], [-180, 180]], bins=bins, normed=normed) phip = (phip[1:] + phip[:-1]) / 2. psip = (psip[1:] + psip[:-1]) / 2. cmap = getattr(cm, pt_dd.get('cmap', 'gray_r')) contour = ax.contourf(phip, psip, h, cmap=cmap) fig.colorbar(contour, shrink=0.6, extend='both') contours.append(contour) decorate_ax(ax, pt_dd, ncol, nrow, c, gk, A) _ = max(phip.max(), psip.max()) if _ > max_: max_ = _ for _ in contours: _.set_clim(0, max_) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def bars(grps, A, C, **kw): dd = utils.get_pt_dd(C, A.property, A.plot_type) logger.debug('\n{0}'.format(pformat((dict(grps))))) bar_width = 1. type_of_bars = 1 # i.e. w, m space = 0.35 # space between neigbouring groups of bars # x coordinates for bars min_, max_ = 0, len(grps.items()) * (bar_width * type_of_bars + space) step = bar_width * type_of_bars + space xlocs = np.arange(min_, max_, step)[:len(grps.items())] fig = plt.figure() ax = fig.add_subplot(111) means = [i[0] for i in grps.values()] stds = [i[1] for i in grps.values()] ax.bar(xlocs, means, bar_width, yerr=stds, color='white', hatch="\\") # decorate a bit ax.set_xlim( (0 - 2 * space), (len(grps.items()) * (bar_width * type_of_bars + space) + space)) ax.set_xticks(xlocs + bar_width / 2.) # /2. to make it in the middle ax.set_xticks(xlocs + bar_width / 2.) # /2. to make it in the middle ax.grid(which="major", axis='y') if 'grid' in dd: ax.grid(**dd['grid']) if 'xlim' in dd: ax.set_xlim(**dd['xlim']) if 'ylim' in dd: ax.set_ylim(**dd['ylim']) if 'xlabel' in dd: ax.set_xlabel(**dd['xlabel']) if 'ylabel' in dd: ax.set_ylabel(**dd['ylabel']) if 'title' in dd: ax.set_title(**dd['title']) if 'legend' in dd: ax.legend(**dd['legend']) if 'xticklabels' in dd: ax.set_xticklabels(**dd['xticklabels']) else: ax.set_xticklabels(grps.keys(), rotation=20) plt.tight_layout() # sometime text could be hidden due to not # enough padding, then use this. plt.savefig(utils.gen_output_filename(A, C))
def bars(grps, A, C, **kw): dd = utils.get_pt_dd(C, A.property, A.plot_type) logger.debug('\n{0}'.format(pformat((dict(grps))))) bar_width = 1. type_of_bars = 1 # i.e. w, m space = 0.35 # space between neigbouring groups of bars # x coordinates for bars min_, max_ = 0, len(grps.items()) * (bar_width * type_of_bars + space) step = bar_width * type_of_bars + space xlocs = np.arange(min_, max_, step)[:len(grps.items())] fig = plt.figure() ax = fig.add_subplot(111) means = [i[0] for i in grps.values()] stds = [i[1] for i in grps.values()] ax.bar(xlocs, means, bar_width, yerr=stds, color='white', hatch="\\") # decorate a bit ax.set_xlim((0 - 2 *space), (len(grps.items()) * (bar_width * type_of_bars + space) + space)) ax.set_xticks(xlocs + bar_width/2.) # /2. to make it in the middle ax.set_xticks(xlocs + bar_width/2.) # /2. to make it in the middle ax.grid(which="major", axis='y') if 'grid' in dd: ax.grid(**dd['grid']) if 'xlim' in dd: ax.set_xlim(**dd['xlim']) if 'ylim' in dd: ax.set_ylim(**dd['ylim']) if 'xlabel' in dd: ax.set_xlabel(**dd['xlabel']) if 'ylabel' in dd: ax.set_ylabel(**dd['ylabel']) if 'title' in dd: ax.set_title(**dd['title']) if 'legend' in dd: ax.legend(**dd['legend']) if 'xticklabels' in dd: ax.set_xticklabels(**dd['xticklabels']) else: ax.set_xticklabels(grps.keys(), rotation=20) plt.tight_layout() # sometime text could be hidden due to not # enough padding, then use this. plt.savefig(utils.gen_output_filename(A, C))
def pot_ener_map(data, A, C, **kw): for k in data.keys(): data[k] = pickle.loads(data[k]) adjust_minima(data) pt_dd = U.get_pt_dd(C, A.property, A.plot_type) logger.info(pt_dd) ncol, nrow = U.gen_rc(len(data.keys()), pt_dd) fig, axes = plt.subplots(nrows=nrow, ncols=ncol, figsize=(ncol * 7, nrow * 6)) axes = axes.flat if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) for c, gk in enumerate(data.keys()): ax = axes[c] [phis, psis], da = data[gk] # this is just for determining the proper levels logger.info('min, max of the original map: {0}, {1}'.format( da.min(), da.max())) # further process da, mainly about removing peaks if 'levels' in pt_dd: min_, max_, step = U.get_param(pt_dd['levels'], gk) logger.info('min, max, step from pt_dd: {0}, {1}, {2}'.format( min_, max_, step)) params = get_params(gk, pt_dd) contour = ax.contourf(phis, psis, da, **params) decorate_ax(ax, gk, pt_dd, ncol, nrow, c) cax = fig.add_axes([0.92, 0.2, 0.02, 0.6]) # left, bottom, width, hight cbar = plt.colorbar(contour, cax=cax) if 'cbar_ylabel' in pt_dd: cbar.ax.set_ylabel(**pt_dd['cbar_ylabel']) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def rama(data, A, C, **kw): pt_dd = U.get_pt_dd(C, A.property, A.plot_type, A.v) ncol, nrow = U.gen_rc(len(data.keys()), pt_dd) # ncol * 8 instead of 6 is because color bar will squeeze the subplot # otherwise. fig = plt.figure(figsize=(ncol*8, nrow*6)) if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) bins = pt_dd.get('bins', 36) normed = pt_dd.get('normed', False) contours = [] max_ = 0 for c, gk in enumerate(data.keys()): ax = fig.add_subplot(nrow, ncol, c+1) da = data[gk] phis, psis = da h, phip, psip = np.histogram2d(psis, phis, range=[[-180,180], [-180,180]], bins=bins, normed=normed) phip = (phip[1:] + phip[:-1]) / 2. psip = (psip[1:] + psip[:-1]) / 2. cmap = getattr(cm, pt_dd.get('cmap', 'gray_r')) contour = ax.contourf(phip, psip, h, cmap=cmap) fig.colorbar(contour, shrink=0.6, extend='both') contours.append(contour) decorate_ax(ax, pt_dd, ncol, nrow, c, gk, A) _ = max(phip.max(), psip.max()) if _ > max_: max_ = _ for _ in contours: _.set_clim(0, max_) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def mp_grped_along_var(data, A, C, **kw): """along a variable, like var2 e.g. solvent""" pt_dd = U.get_pt_dd(C, '_'.join(A.properties), A.plotmp_type, A.vv) fig = plt.figure(figsize=(12,9)) if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) ncol, nrow = U.gen_rc(len(A.properties), pt_dd) for c, pt in enumerate(A.properties): dsets = grped_along_var.group_datasets(data[pt], pt_dd['grp_REs']) ax = fig.add_subplot(nrow, ncol, c+1) grped_along_var.ax_plot(ax, dsets, pt_dd, A) decorate_ax(ax, pt_dd, pt, ncol, nrow, c) if 'figlegend' in pt_dd: leg = fig.legend(handles=ax.lines, **pt_dd['figlegend']) if 'legend_linewidth' in pt_dd: for _ in leg.legendHandles: _.set_linewidth(pt_dd['legend_linewidth']) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def pot_ener_map(data, A, C, **kw): for k in data.keys(): data[k] = pickle.loads(data[k]) adjust_minima(data) pt_dd = U.get_pt_dd(C, A.property, A.plot_type) logger.info(pt_dd) ncol, nrow = U.gen_rc(len(data.keys()), pt_dd) fig, axes = plt.subplots(nrows=nrow, ncols=ncol, figsize=(ncol*7, nrow*6)) axes = axes.flat if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) for c, gk in enumerate(data.keys()): ax = axes[c] [phis, psis], da = data[gk] # this is just for determining the proper levels logger.info('min, max of the original map: {0}, {1}'.format(da.min(), da.max())) # further process da, mainly about removing peaks if 'levels' in pt_dd: min_, max_, step = U.get_param(pt_dd['levels'], gk) logger.info( 'min, max, step from pt_dd: {0}, {1}, {2}'.format( min_, max_, step)) params = get_params(gk, pt_dd) contour = ax.contourf(phis, psis, da, **params) decorate_ax(ax, gk, pt_dd, ncol, nrow, c) cax = fig.add_axes([0.92, 0.2, 0.02, 0.6]) # left, bottom, width, hight cbar = plt.colorbar(contour, cax=cax) if 'cbar_ylabel' in pt_dd: cbar.ax.set_ylabel(**pt_dd['cbar_ylabel']) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def xy(data, A, C, **kw): """ data structure of data, an OrderedDict data = { 'x': { 'groupkey0': [mean0, std0], 'groupkey1': [mean1, std1], ... }, 'y': { 'groupkey0': [mean0, std0], 'groupkey1': [mean1, std1], ... } } """ pt_dd = U.get_pt_dd(C, '_'.join(A.properties), A.plotmp_type) xp, yp = A.properties # e.g. upup, unun xdata, ydata = data[xp], data[yp] # x, y means and errors xms, xes, yms, yes = [], [], [], [] for c, key in enumerate(xdata.keys()): # xdata and ydata must have the same keys() xms.append(xdata[key][0]) xes.append(xdata[key][1]) yms.append(ydata[key][0]) yes.append(ydata[key][1]) fig = plt.figure() ax = fig.add_subplot(111) for xm, xe, ym, ye in zip(xms, xes, yms, yes): ax.errorbar(xm, ym, xerr=xe, yerr=ye) decorate_ax(ax, pt_dd) plt.savefig(U.gen_output_filename(A, C))
def xy(data, A, C, **kw): """ data structure of data, an OrderedDict data = { 'x': { 'groupkey0': [mean0, std0], 'groupkey1': [mean1, std1], ... }, 'y': { 'groupkey0': [mean0, std0], 'groupkey1': [mean1, std1], ... } } """ pt_dd = U.get_pt_dd(C, '_'.join(A.properties), A.plotmp_type) xp, yp = A.properties # e.g. upup, unun xdata, ydata = data[xp], data[yp] # x, y means and errors xms, xes, yms, yes = [], [], [], [] for c, key in enumerate(xdata.keys()): # xdata and ydata must have the same keys() xms.append(xdata[key][0]) xes.append(xdata[key][1]) yms.append(ydata[key][0]) yes.append(ydata[key][1]) fig = plt.figure() ax = fig.add_subplot(111) for xm, xe, ym, ye in zip(xms, xes, yms, yes): ax.errorbar(xm, ym, xerr=xe, yerr=ye) decorate_ax(ax, pt_dd) plt.savefig(U.gen_output_filename(A, C))
def grped_pmf(data, A, C, **kw): pt_dd = U.get_pt_dd(C, A.property, A.plot_type) logger.info('pt_dd: {0}'.format(pt_dd)) dsets = grp_datasets(data, pt_dd) ncol, nrow = U.gen_rc(len(dsets.keys()), pt_dd) logger.info('col: {0}, row; {1}'.format(ncol, nrow)) fig = plt.figure(figsize=pt_dd.get('figsize', [16,9])) if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) for dsetc, dsetk in enumerate(dsets.keys()): # dsetc: dset counter ax = fig.add_subplot(nrow, ncol, dsetc+1) # da.shape: (x, 3, y), where x: # of replicas; 3: the shape of [bn, pmf, pmf_e], # y: # of bn, pmf, or pmf_e of each subgroup for k, gk in enumerate(dsets[dsetk].keys()): da = data[gk] pre_pmfm = da.mean(axis=0) # means over x, DIM: (3, y) pre_pmfe = U.sem3(da) # sems over x, DIM: (3, y) if 'pmf_cutoff' in pt_dd: cf = float(pt_dd['pmf_cutoff']) bs, es = filter_pmf_data(pre_pmfm, cf) # get slicing indices else: bs, es = filter_pmf_data(pre_pmfm) bn, pmfm, _ = sliceit(pre_pmfm, bs, es) # bn: bin; pmfm: pmf mean bne, pmfe, _ = sliceit(pre_pmfe, bs, es) # bne: bin err; pmfe: pmf err # pmf sem, equivalent to stats.sem(da, axis=0) pmfe = sliceit(pre_pmfe, bs, es)[1] # tricky: 1 corresponds err of pmf mean # now, prepare the errobars for the fit _pfits, _ks, _l0s = [], [], [] for subda in da: sliced = sliceit(subda, bs, es) bn, pm, pe = sliced a, b, c = np.polyfit(bn, pm, deg=2) _pfv = parabola(bn, a, b, c) # pfv: pmf fit values _pfits.append(_pfv) _ks.append(convert_k(a)) _l0s.append(-b/(2*a)) logger.info('modulus values for {0}'.format(pt_dd['grp_REs'][dsetc])) for _ in _ks: logger.info(' {0}'.format(_)) _pfit = np.mean(_pfits, axis=0) _k = np.mean(_ks) # prefix it with _ to avoid confusion _ke = U.sem(_ks) _l0 = np.mean(_l0s) _l0e = U.sem(_l0s) _r2 = U.calc_r2(pmfm, _pfit) _ky, _kye = ky(_k, _l0, _ke, _l0e) ax.annotate('\n'.join(['k = {0:.1f} $\pm$ {1:.1f} pN/nm'.format(_k, _ke), 'd$_0$ = {0:.1f} $\pm$ {1:.1f} nm'.format(_l0, _l0e), 'r$^2$ = {0:.2f}'.format(_r2)]), **pt_dd['annotate']) # ax.text(s = '\n'.join(['k = {0:.1f} $\pm$ {1:.1f} pN/nm'.format(_k, _ke), # 'd$_0$ = {0:.1f} $\pm$ {1:.1f} nm'.format(_l0, _l0e), # 'r$^2$ = {0:.2f}'.format(_r2)]), # # 'ky = {0:.1f} +/- {1:.1f} MPa'.format(_ky, _kye)]), # **pt_dd['text']) params = get_params(gk, pt_dd) line = ax.plot(bn, pmfm, **params) ax.fill_between(bn, pmfm-pmfe, pmfm+pmfe, where=None, facecolor=line[0].get_color(), alpha=.3) ax.plot(bn, _pfit, '--', color=line[0].get_color()) decorate_ax(ax, gk, pt_dd, ncol, nrow, dsetc) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def grped_pmf(data, A, C, **kw): pt_dd = U.get_pt_dd(C, A.property, A.plot_type) logger.info('pt_dd: {0}'.format(pt_dd)) dsets = grp_datasets(data, pt_dd) ncol, nrow = U.gen_rc(len(dsets.keys()), pt_dd) logger.info('col: {0}, row; {1}'.format(ncol, nrow)) fig = plt.figure(figsize=pt_dd.get('figsize', [16, 9])) if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) for dsetc, dsetk in enumerate(dsets.keys()): # dsetc: dset counter ax = fig.add_subplot(nrow, ncol, dsetc + 1) # da.shape: (x, 3, y), where x: # of replicas; 3: the shape of [bn, pmf, pmf_e], # y: # of bn, pmf, or pmf_e of each subgroup for k, gk in enumerate(dsets[dsetk].keys()): da = data[gk] pre_pmfm = da.mean(axis=0) # means over x, DIM: (3, y) pre_pmfe = U.sem3(da) # sems over x, DIM: (3, y) if 'pmf_cutoff' in pt_dd: cf = float(pt_dd['pmf_cutoff']) bs, es = filter_pmf_data(pre_pmfm, cf) # get slicing indices else: bs, es = filter_pmf_data(pre_pmfm) bn, pmfm, _ = sliceit(pre_pmfm, bs, es) # bn: bin; pmfm: pmf mean bne, pmfe, _ = sliceit(pre_pmfe, bs, es) # bne: bin err; pmfe: pmf err # pmf sem, equivalent to stats.sem(da, axis=0) pmfe = sliceit(pre_pmfe, bs, es)[1] # tricky: 1 corresponds err of pmf mean # now, prepare the errobars for the fit _pfits, _ks, _l0s = [], [], [] for subda in da: sliced = sliceit(subda, bs, es) bn, pm, pe = sliced a, b, c = np.polyfit(bn, pm, deg=2) _pfv = parabola(bn, a, b, c) # pfv: pmf fit values _pfits.append(_pfv) _ks.append(convert_k(a)) _l0s.append(-b / (2 * a)) logger.info('modulus values for {0}'.format( pt_dd['grp_REs'][dsetc])) for _ in _ks: logger.info(' {0}'.format(_)) _pfit = np.mean(_pfits, axis=0) _k = np.mean(_ks) # prefix it with _ to avoid confusion _ke = U.sem(_ks) _l0 = np.mean(_l0s) _l0e = U.sem(_l0s) _r2 = U.calc_r2(pmfm, _pfit) _ky, _kye = ky(_k, _l0, _ke, _l0e) ax.annotate( '\n'.join([ 'k = {0:.1f} $\pm$ {1:.1f} pN/nm'.format(_k, _ke), 'd$_0$ = {0:.1f} $\pm$ {1:.1f} nm'.format(_l0, _l0e), 'r$^2$ = {0:.2f}'.format(_r2) ]), **pt_dd['annotate']) # ax.text(s = '\n'.join(['k = {0:.1f} $\pm$ {1:.1f} pN/nm'.format(_k, _ke), # 'd$_0$ = {0:.1f} $\pm$ {1:.1f} nm'.format(_l0, _l0e), # 'r$^2$ = {0:.2f}'.format(_r2)]), # # 'ky = {0:.1f} +/- {1:.1f} MPa'.format(_ky, _kye)]), # **pt_dd['text']) params = get_params(gk, pt_dd) line = ax.plot(bn, pmfm, **params) ax.fill_between(bn, pmfm - pmfe, pmfm + pmfe, where=None, facecolor=line[0].get_color(), alpha=.3) ax.plot(bn, _pfit, '--', color=line[0].get_color()) decorate_ax(ax, gk, pt_dd, ncol, nrow, dsetc) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def imap(data, A, C, **kw): """imap: interaction map""" logger.info('start plotting interaction map...') pt_dd = U.get_pt_dd(C, A.property, A.plot_type) fig = plt.figure(figsize=(12, 9)) col, row = U.gen_rc(len(data.keys()), pt_dd) grid = ImageGrid(fig, 111, nrows_ncols=(row, col), axes_pad=0.3, add_all=True, label_mode="L") if 'denorminators' in pt_dd: for gk in data: dn = U.get_param(pt_dd['denorminators'], gk) logger.info('denorminator: {0}'.format(dn)) data[gk] = data[gk] / dn # used to set up the reference point and the range of color bar max_ = get_max(data) for k, gk in enumerate(data.keys()): ax = grid[k] da = data[gk] rda = da logger.info('map max: {0}; map min: {1}'.format(rda.max(), rda.min())) # JUST FOR REFERENCE OF SEEING WHERE THE END POINTS ARE, DEBUGGING USES # rda[-1][-1] = max_ # rda[0][-1] = max_ # sophisticated reversal to make x axis donor, y axis acceptor # rda = np.array([i[::-1] for i in da.transpose()[::-1]]) # sophisticated reversal to make x axis acceptor, y axis donor # rda = np.array([i[::-1] for i in da[::-1]]) params = get_params(gk, pt_dd) logger.info(params) # cmap_options: hot, gist_heat, Orange (printer friendly) # remove the info about the Hbonding information about first residue, # which ACE, this make the final map easier to understand rda = np.delete(np.delete(rda, 0, 0), 0, 1) im = ax.pcolormesh(rda, **params) if 'clim' in pt_dd: im.set_clim(**pt_dd['clim']) else: im.set_clim(0, max_) logger.info('shape after removal of the 0th residue: {0}'.format( rda.shape)) ax.set_xlim([0, rda.shape[0]]) ax.set_ylim([0, rda.shape[1]]) ax.minorticks_on() decorate_ax(ax, pt_dd, gk) plt.colorbar(im, shrink=.5, orientation='vertical', anchor=(1.3, 0)) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def grped_distr(data, A, C, **kw): """ data structure of data, an OrderedDict data = { 'groupkey0': [[array of bn0, , array of psm0, array of pse0], [mean0, std0]], 'groupkey1': [[array of bn1, , array of psm1, array of pse1], [mean1, std1]], ... } """ if A.plot_type in ['grped_distr_ave']: for k in data.keys(): data[k] = pickle.loads(data[k]) logger.info('start plotting {0} for \n{1}'.format(A.plot_type, pprint.pformat(data.keys()))) # This is trying to avoid duplication in .xitconfig, but not very elegant if A.plot_type in ['grped_distr', 'grped_distr_ave']: _ = 'grped_distr' elif A.plot_type in ['grped_alx']: _ = 'grped_alx' pt_dd = U.get_pt_dd(C, A.property, _) dsets = grp_datasets(data, pt_dd) ncol, nrow = U.gen_rc(len(dsets.keys()), pt_dd) fig = plt.figure(figsize=pt_dd.get('figsize', (12,9))) if 'subplots_adjust' in pt_dd: fig.subplots_adjust(**pt_dd['subplots_adjust']) logger.info('Chosen # of cols: {0}, # of rows; {1}'.format(ncol, nrow)) for c, dsetk in enumerate(dsets.keys()): ax = fig.add_subplot(nrow, ncol, c+1) dset = dsets[dsetk] if 'text' in dset: ax.text(s=dset['text'], **pt_dd['text']) for kkey in dset['data']: # ind: individual da = dset['data'][kkey] params = get_params(kkey, pt_dd) if A.plot_type in ['grped_distr', 'grped_alx']: line = ax.plot(da[0], da[1], **params) # facecolor uses the same color as ax.plot if ('fill_between' not in pt_dd) or (pt_dd['fill_between'] == True): # the condition means that by default do fill_between # unless it is explicitly set to False ax.fill_between(da[0], da[1]-da[2], da[1]+da[2], where=None, facecolor=line[0].get_color(), alpha=.3) elif A.plot_type == 'grped_distr_ave': # the data slicing can be confusing, refer to plot.py to see how to # data is structured line = ax.plot(da[0][0], da[0][1], **params) # facecolor uses the same color as ax.plot ax.fill_between(da[0][0], da[0][1]-da[0][2], da[0][1]+da[0][2], where=None, facecolor=line[0].get_color(), alpha=.3) # now, plot the vertical bar showing the average value m = da[1][0] # mean e = da[1][1] # error ave_y = pt_dd.get('ave_y', [0,1]) ax.plot([m,m], ave_y, color=params.get('color')) ax.fill_betweenx(ave_y, [m-e, m-e], [m+e, m+e], where=None, facecolor=line[0].get_color(), alpha=.3) if pt_dd.get('gaussian_fit'): # maybe it's better to use p0 for curve_fit popt, pcov = curve_fit(gaussian, da[0], da[1]) _, mu, sigma = popt logger.info('mean of the fitted normal distribution: {0}'.format(mu)) new_ys = gaussian(da[0], *popt) # pearsonr creates different value from that by calc_r2 # corr, p_val = pearsonr(ys, new_ys) r2 = U.calc_r2(da[1], new_ys) ax.plot(da[0], new_ys, linewidth="4", color='black', label='r$^2$ = {0:.3f}'.format(r2)) # plot a vertical line if needed, e.g. showing the time of convergence if 'vline' in pt_dd: vl = pt_dd['vline'] x = vl['x'] if 'y' in vl: yb, ye = vl['y'] else: yb, ye = ax.get_ylim() ax.plot([x, x], [yb, ye], **vl.get('vline_params', {})) decorate_ax(ax, pt_dd, ncol, nrow, c) # specific case if (A.property == 'rg_c_alpha_wl' and dsetk == 'dset0' and A.plot_type == 'grped_alx' and sorted(dset['data'].keys()) == ['m300/sq1', 'w300/sq1']): print "DO something special" ax.set_xlim([0, 500]) ax.set_xticklabels([str(i) for i in xrange(0,600, 100)]) for tick in ax.xaxis.get_major_ticks(): tick.label1On = False tick.label2On = True # move the ticks to the top if 'legend_linewidth' in pt_dd: leg = ax.get_legend() lines = leg.get_lines() for _ in lines: _.set_linewidth(pt_dd['legend_linewidth']) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def grped_xy(data, A, C, **kw): pt_dd = U.get_pt_dd(C, '_'.join(A.properties), A.plotmp_type) dsets = grp_datasets(data, pt_dd) fig = plt.figure() ax = fig.add_subplot(111) xp, yp = A.properties if sorted([xp, yp]) == ['unv', 'upv']: # this is plot specific ax.plot([0,1], [0,1], '--') for dk in dsets.keys(): dset = dsets[dk] xda, yda = dset[xp], dset[yp] # da: data # denormx = [float(i) for i in pt_dd.get('denormx', [1] * len(xdata.keys()))] # denormy = [float(i) for i in pt_dd.get('denormy', [1] * len(xdata.keys()))] k1, k2 = xda.keys() # ONLY deal with two members in a group (e.g. w, m) x1, x2 = xda[k1], xda[k2] y1, y2 = yda[k1], yda[k2] # DEPRECATED! normalization should be done in plot.py, this is left # here for remembering the bad design # if 'denormx' in pt_dd: # dx1 = float(pt_dd['denormx'][k1]) # dx: denormx # dx2 = float(pt_dd['denormx'][k2]) # x1, x2 = x1 / dx1, x2 / dx2 # if 'denormy' in pt_dd: # dy1 = float(pt_dd['denormy'][k1]) # dy: denormy # dy2 = float(pt_dd['denormy'][k2]) # y1, y2 = y1 / dy1, y2 / dy2 params1, params2 = {}, {} if 'markers' in pt_dd: params1['marker'] = U.get_param(pt_dd['markers'], k1) params2['marker'] = U.get_param(pt_dd['markers'], k2) if 'colors' in pt_dd: params1['color'] = U.get_param(pt_dd['colors'], k1) params2['color'] = U.get_param(pt_dd['colors'], k2) ax.errorbar(x1[0], y1[0], xerr=x1[1], yerr=y1[1], **params1) ax.errorbar(x2[0], y2[0], xerr=x2[1], yerr=y2[1], **params2) ax.annotate("", # STRANGE! the order need to be reversed xy=(x2[0], y2[0]), xycoords='data', xytext=(x1[0], y1[0]), textcoords='data', arrowprops=dict(arrowstyle="->", #linestyle="dashed", # arrowstyle="fancy", color="black", alpha=1, shrinkA=10, shrinkB=10, # connectionstyle="arc3,rad=-0.3", connectionstyle="arc3", ), ) decorate_ax(ax, pt_dd) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))
def grped_xy(data, A, C, **kw): pt_dd = U.get_pt_dd(C, '_'.join(A.properties), A.plotmp_type) dsets = grp_datasets(data, pt_dd) fig = plt.figure() ax = fig.add_subplot(111) xp, yp = A.properties if sorted([xp, yp]) == ['unv', 'upv']: # this is plot specific ax.plot([0, 1], [0, 1], '--') for dk in dsets.keys(): dset = dsets[dk] xda, yda = dset[xp], dset[yp] # da: data # denormx = [float(i) for i in pt_dd.get('denormx', [1] * len(xdata.keys()))] # denormy = [float(i) for i in pt_dd.get('denormy', [1] * len(xdata.keys()))] k1, k2 = xda.keys( ) # ONLY deal with two members in a group (e.g. w, m) x1, x2 = xda[k1], xda[k2] y1, y2 = yda[k1], yda[k2] # DEPRECATED! normalization should be done in plot.py, this is left # here for remembering the bad design # if 'denormx' in pt_dd: # dx1 = float(pt_dd['denormx'][k1]) # dx: denormx # dx2 = float(pt_dd['denormx'][k2]) # x1, x2 = x1 / dx1, x2 / dx2 # if 'denormy' in pt_dd: # dy1 = float(pt_dd['denormy'][k1]) # dy: denormy # dy2 = float(pt_dd['denormy'][k2]) # y1, y2 = y1 / dy1, y2 / dy2 params1, params2 = {}, {} if 'markers' in pt_dd: params1['marker'] = U.get_param(pt_dd['markers'], k1) params2['marker'] = U.get_param(pt_dd['markers'], k2) if 'colors' in pt_dd: params1['color'] = U.get_param(pt_dd['colors'], k1) params2['color'] = U.get_param(pt_dd['colors'], k2) ax.errorbar(x1[0], y1[0], xerr=x1[1], yerr=y1[1], **params1) ax.errorbar(x2[0], y2[0], xerr=x2[1], yerr=y2[1], **params2) ax.annotate( "", # STRANGE! the order need to be reversed xy=(x2[0], y2[0]), xycoords='data', xytext=(x1[0], y1[0]), textcoords='data', arrowprops=dict( arrowstyle="->", #linestyle="dashed", # arrowstyle="fancy", color="black", alpha=1, shrinkA=10, shrinkB=10, # connectionstyle="arc3,rad=-0.3", connectionstyle="arc3", ), ) decorate_ax(ax, pt_dd) plt.savefig(U.gen_output_filename(A, C), **pt_dd.get('savefig', {}))