def plot(argv): """ Handles commands argv[0] in ("plot", "show") """ import getopt from pathtools import unpickle_path from pts.tools.tab2plot import colormap # from numpy import linspace #, empty, transpose # from numpy import array # # Only position arguments so far. The first, argv[0], is the name # of the method, usually just "plot": # cmd = argv[0] # skip argv[1], it just tells that this precious function has been selected. opts, args = getopt.getopt(argv[2:], "", []) # print "opts=", opts # print "args=", args import matplotlib if cmd == "plot": # do not expect X11 to be available, use a different backend: matplotlib.use("Agg") from matplotlib import pyplot as plt def plot_energy(energies, color): # energy profile: plt.title("Energy profile", fontsize="large") plt.ylabel("Energy [eV]") plt.xlabel("Path point [arb. u.]") plt.plot(range(1, len(energies) + 1), energies, "o--", color=color) plt.xlim((1, len(energies))) def plot_energy_with_cubic_spline(geometries, energies, gradients, tangents, abscissas, color): """ Plot the energy profile indicating the slope of the energy at the vertices. Tangents are usually normalized, if at all, quite differently from the convention used here -- one unit of "path length" between neyboring images. To avoid visual mismatch between finite difference (E[i+1] - E[i]) / 1.0 and differential slope dE / ds = dot(g, t) at the nodes we invent a local re-normalization of the tangents. """ # energy profile: from numpy import dot, linspace, sqrt, array, shape, empty from pts.func import CubicSpline plt.title("Energy profile", fontsize="large") plt.ylabel("Energy [eV]") plt.xlabel("Path point [arb. u.]") if abscissas == None: # this will hold distances vectors between path points: xdeltas = empty(shape(geometries)) xdeltas[0] = geometries[1] - geometries[0] xdeltas[-1] = geometries[-1] - geometries[-2] xdeltas[1:-1] = (geometries[2:] - geometries[:-2]) / 2.0 # this is the measure of the real separatioin between images, # each will correspond to one unit on the graph: scales = array([sqrt(dot(x, x)) for x in xdeltas]) # re-normalize tangents: tangents = array( [s * t / sqrt(dot(t, t)) for s, t in zip(scales, tangents)]) abscissas = range(1, len(energies) + 1) else: # If the distances in s are explicitely given, expect also the tangents to be # right tangents = array(tangents) abscissas = array(abscissas) # projection of the gradient on the new tangents, dE / ds: slopes = [dot(g, t) for g, t in zip(gradients, tangents)] # cubic spline spline = CubicSpline(abscissas, energies, slopes) # spline will be plotted with that many points: line = linspace(abscissas[0], abscissas[-1], 100) plt.plot(abscissas, energies, "o", line, map(spline, line), "-", color=color) plt.xlim((abscissas[0], abscissas[-1])) # number of curves on the same graph: N = len(args) # # This is the main loop over the input files: # for i, name in enumerate(args): geometries, energies, gradients, tangents, abscissas, symbols, trafo = unpickle_path( name) # v2 # tuple is printed in one line: # print tuple(energies) # energy profile: if tangents is not None: plot_energy_with_cubic_spline(geometries, energies, gradients, tangents, abscissas, colormap(i, N)) else: plot_energy(energies, colormap(i, N)) if cmd == "show": # Display the plot, needs X11: plt.show() if cmd == "plot": # Save in vecor format, allows post-processing: plt.savefig("plot.svg")
def visualize_path(filenames, data_ase, other_input, values, path_look, for_plot, hold, file_range=[0, sys.maxint]): """ Does the actual plotting of a path function. If hold = True the actual plot is not done. This allows to use the function together with some other functions changing the plot. """ from pts.tools.path2tab import carts_to_int from pts.tools.tab2plot import setup_plot, plot_data, prepare_plot, colormap from pts.ui.read_COS import read_geos_from_file from pts.tools.path2tab import extract_data import numpy as np from copy import copy from sys import stderr # Expand the output, we need it further. ase, format_ts = data_ase num, ts_estimates, refs = path_look reference, reference_data = refs withs, allval, special_vals, appender, special_opt = values diff, symm, symshift = special_opt num_i, logscale, title, xlab, xran, ylab, yran, names_of_lines, outputfile = for_plot cell, tomove, howmove = appender # plot environment setup_plot(title=title, x_label=xlab, y_label=ylab, log=logscale) # extract which options to take optraw, num_opts, xnum_opts, optx = makeoption(num_i, diff, symm, symshift, withs) # num_opts_raw = copy(num_opts) opt = copy(optraw) if special_vals != []: for s_val in special_vals: # use the options for x and plot the data gotten from # the file directly opt = opt + " t %i" % (num_opts + 1) num_opts = num_opts + 1 n = len(filenames) * (num_opts - 1) if not reference == []: for ref in reference: # Reference point (geometry, energy) to compare the rest # data to it. geometry is supposed to be in a ASE readable # format, energy in a separate file. atom_ref, y_ref = read_geos_from_file([ref], format=format_ts) # Reference data for the geometries. The Abscissa is # supposed to be on 0.5 reference_int_geos = np.array( carts_to_int(y_ref, [0.5], allval, cell, tomove, howmove, withs)) reference_int_geos = reference_int_geos.T reference_int_geos = reference_int_geos.tolist() # optref = optraw num_opts_ref = num_opts if special_vals != []: # From the special vals only the energies can be # displaced. Therefore special treatment is required. for s_val in special_vals: if s_val.startswith("en") and not reference_data == None: # optref = optraw + " t %i" % (num_opts_raw + 1) reference_data = np.loadtxt(reference_data) reference_int_geos.append([reference_data.tolist()]) else: num_opts_ref = num_opts_ref - 1 if num_opts_ref > 1: colors = [colormap(j, n) for j in range(0, num_opts)] prepare_plot(None, None, None, "_nolegend_", reference_int_geos, "Reference", opt, colors) # For each file prepare the plot for i, filename in enumerate(filenames): if i < file_range[0] or i > file_range[1]: continue # Extract the data for beads, path if availabe and TS # estimates if requested (else None). beads, path, ts_ests_geos = extract_data(filename, data_ase, other_input, values, ts_estimates, num, i) if ts_ests_geos == []: print >> stderr, "WARNING: No transition state found for file", filename ts_ests_geos = None # The name belonging to filename. name_p = str(i + 1) if names_of_lines[i] != []: name_p = names_of_lines[i] # prepare plot from the tables containing the path and bead def choose_color(j): return colormap(i * (num_opts - 1) + j, n) # data only if there are enough for x AND y values colors = map(choose_color, range(0, num_opts)) if num_opts > 1: if ase: prepare_plot(None, None, None, "_nolegend_", beads, name_p, opt, colors) else: prepare_plot(path, name_p, beads, "_nolegend_", ts_ests_geos, "_nolegend_", opt, colors) # now plot plot_data(hold=hold, xrange=xran, yrange=yran, savefile=outputfile)
def choose_color(j): return colormap(i * (num_opts - 1) + j, n)
def choose_color(j): return colormap(i * (num_opts - 1 + len(special_val)) + j, n)
def visualize_dimer(log_file, values, dimer_special, for_plot, hold, file_range = [0, sys.maxint]): """ this function might be called by another program. It contains the main body of plotting a progress path. if hold = True the plot will be prepared but not plotted (so that afterwards other plots can be added). For hold = False the plot will be done. """ from pts.tools.tab2plot import setup_plot,prepare_plot, plot_data, colormap from pts.tools.path2plot import makeoption from pts.tools.path2tab import beads_to_int from pts.tools.dimer2xyz import read_from_pickle_log num_i, logscale, title, xlab, xran, ylab, yran, names_of_lines, outputfile = for_plot withs, allval, special_val, appender, special_opt = values diff, __, __ = special_opt cell, tomove, howmove = appender # These two are extra values only for the progress tools arrow_len, vec_angle_raw = dimer_special decrease = [0, 0] #default values of interesting parameters vec_angle = interestingdirection() #FIXME: interestingdirection class is a bit unhandy. Maybe exchange it soon. for raw in vec_angle_raw: m1, m2 = raw value = "vec" # For both vectors find the code and whether the first or last # points of the other variables have to be removed in order to have # all vectors of the same length. for mi in m1, m2: vec_angle.set_name(mi) range_v = vec_angle.get_range() for i, j in enumerate(range_v): if not j == 0: decrease[i] = j value += vec_angle.get_string() if value[3:5] == value[5:]: decrease[0] = -1 special_val.append(value) if arrow_len == None: arrow = False else: arrow = True if "step" in special_val: # There will be one value less for the step, as it is the difference to the last # one. decrease[1] = 1 # plot environment setup_plot(title = title, x_label = xlab, y_label = ylab, log = logscale) # extract which options to take opt, num_opts, xnum_opts, optx = makeoption(num_i, diff, [], [], withs) # decide how many color are used n = len(log_file) * (num_opts - 1 + len(special_val)) for i, geo_file in enumerate(log_file): if i < file_range[0] or i > file_range[1]: continue # extract refinement process information from log.pickle file obj, geos, modes, curv, energy, grad = read_from_pickle_log(geo_file) # initial and final point to plot used because arrays to be plotted may have # different lengths ifplot = [0, len(geos)] ifplot = [ip - dec for ip, dec in zip(ifplot, decrease)] x = list(range(0,len(geos)))[ifplot[0]: ifplot[1]] # internal coordinates for plotting beads = beads_to_int(geos[ifplot[0]: ifplot[1]], x, obj, \ allval, cell, tomove, howmove, withs) beads = np.asarray(beads) beads = beads.T # name of the plot name_p = str(i + 1) if names_of_lines[i] != []: name_p = names_of_lines[i] # make plot only when there are enough points if num_opts > 1: def choose_color(j): return colormap(i * (num_opts - 1 + len(special_val)) + j, n) # data only if there are enough for x AND y values colors = map(choose_color, range(0, num_opts)) prepare_plot( None, None, None, None, beads, name_p, opt, colors) if arrow: for j in range(ifplot[0], ifplot[1]): # for each bead we plotted, a line is added to the center point # indicating the dimer mode direction projected in internal coordinates assert(arrow_len > 0) # use finite difference method to extract the projection of modes arrows = beads_to_int([geos[j] - modes[j] * arrow_len, geos[j] + modes[j] * arrow_len], \ [x[j]] * 2, obj, allval, cell, tomove, howmove, withs) arrows = np.asarray(arrows) arrows = arrows.T #arrows = rescale(arrows, arrow_len) prepare_plot(arrows, "_nolegend_", None, None, None, None, opt, colors) if special_val != []: # Two kinds of dictionary store share the same interface for j, s_val in enumerate(special_val): # use the options for x and plot the data gotten from # the file directly optlog = optx + " t %i" % (xnum_opts + 1) log_points = beads log_points = log_points[:xnum_opts + 1,:] log_points = log_points.tolist() if s_val.startswith("en"): log_points.append(energy[ifplot[0]: ifplot[1]]) elif s_val.startswith("gr"): val = s_val[3:] log_points.append(grads_dimer(modes, grad[ifplot[0]: ifplot[1]], val)) elif s_val.startswith("curv"): log_points.append(curv) elif s_val.startswith("step"): log_points.append(stepsize(geos[ifplot[0]: ifplot[1]+1])) elif s_val.startswith("vec"): val = s_val[3:] log_points.append(array_angles(*vec_angle(val, modes, geos, grad, ifplot))) log_points = np.asarray(log_points) prepare_plot( None, None, None, None, log_points, \ s_val + " " + name_p, optlog, [colormap(i * (num_opts - 1 + len(special_val)) + j, n)]) # finally make the picture visible plot_data(hold = hold, xrange = xran, yrange = yran, savefile = outputfile)
def plot(argv): """ Handles commands argv[0] in ("plot", "show") """ import getopt from pathtools import unpickle_path from pts.tools.tab2plot import colormap # from numpy import linspace #, empty, transpose # from numpy import array # # Only position arguments so far. The first, argv[0], is the name # of the method, usually just "plot": # cmd = argv[0] # skip argv[1], it just tells that this precious function has been selected. opts, args = getopt.getopt(argv[2:], "", []) # print "opts=", opts # print "args=", args import matplotlib if cmd == "plot": # do not expect X11 to be available, use a different backend: matplotlib.use("Agg") from matplotlib import pyplot as plt def plot_energy(energies, color): # energy profile: plt.title("Energy profile", fontsize="large") plt.ylabel("Energy [eV]") plt.xlabel("Path point [arb. u.]") plt.plot(range(1, len(energies)+1), energies, "o--", color=color) plt.xlim((1, len(energies))) def plot_energy_with_cubic_spline(geometries, energies, gradients, tangents, abscissas, color): """ Plot the energy profile indicating the slope of the energy at the vertices. Tangents are usually normalized, if at all, quite differently from the convention used here -- one unit of "path length" between neyboring images. To avoid visual mismatch between finite difference (E[i+1] - E[i]) / 1.0 and differential slope dE / ds = dot(g, t) at the nodes we invent a local re-normalization of the tangents. """ # energy profile: from numpy import dot, linspace, sqrt, array, shape, empty from pts.func import CubicSpline plt.title("Energy profile", fontsize="large") plt.ylabel("Energy [eV]") plt.xlabel("Path point [arb. u.]") if abscissas == None: # this will hold distances vectors between path points: xdeltas = empty(shape(geometries)) xdeltas[0] = geometries[1] - geometries[0] xdeltas[-1] = geometries[-1] - geometries[-2] xdeltas[1:-1] = (geometries[2:] - geometries[:-2]) / 2.0 # this is the measure of the real separatioin between images, # each will correspond to one unit on the graph: scales = array([sqrt(dot(x, x)) for x in xdeltas]) # re-normalize tangents: tangents = array([s * t / sqrt(dot(t, t)) for s, t in zip(scales, tangents)]) abscissas = range(1, len(energies)+1) else: # If the distances in s are explicitely given, expect also the tangents to be # right tangents = array(tangents) abscissas = array(abscissas) # projection of the gradient on the new tangents, dE / ds: slopes = [dot(g, t) for g, t in zip(gradients, tangents)] # cubic spline spline = CubicSpline(abscissas, energies, slopes) # spline will be plotted with that many points: line = linspace(abscissas[0], abscissas[-1], 100) plt.plot( abscissas, energies, "o", line, map(spline, line), "-", color = color) plt.xlim((abscissas[0], abscissas[-1])) # number of curves on the same graph: N = len(args) # # This is the main loop over the input files: # for i, name in enumerate(args): geometries, energies, gradients, tangents, abscissas, symbols, trafo = unpickle_path(name) # v2 # tuple is printed in one line: # print tuple(energies) # energy profile: if tangents is not None: plot_energy_with_cubic_spline(geometries, energies, gradients, tangents, abscissas, colormap(i, N)) else: plot_energy(energies, colormap(i, N)) if cmd == "show": # Display the plot, needs X11: plt.show() if cmd == "plot": # Save in vecor format, allows post-processing: plt.savefig("plot.svg")
def visualize_path(filenames, data_ase, other_input, values, path_look, for_plot, hold, file_range = [0, sys.maxint]): """ Does the actual plotting of a path function. If hold = True the actual plot is not done. This allows to use the function together with some other functions changing the plot. """ from pts.tools.path2tab import carts_to_int from pts.tools.tab2plot import setup_plot, plot_data, prepare_plot, colormap from pts.ui.read_COS import read_geos_from_file from pts.tools.path2tab import extract_data import numpy as np from copy import copy from sys import stderr # Expand the output, we need it further. ase, format_ts = data_ase num, ts_estimates, refs = path_look reference, reference_data = refs withs, allval, special_vals, appender, special_opt = values diff, symm, symshift = special_opt num_i, logscale, title, xlab, xran, ylab, yran, names_of_lines, outputfile = for_plot cell, tomove, howmove = appender # plot environment setup_plot(title = title, x_label = xlab, y_label = ylab, log = logscale) # extract which options to take optraw, num_opts, xnum_opts, optx = makeoption(num_i, diff, symm, symshift, withs) # num_opts_raw = copy(num_opts) opt = copy(optraw) if special_vals != []: for s_val in special_vals: # use the options for x and plot the data gotten from # the file directly opt = opt + " t %i" % (num_opts + 1) num_opts = num_opts + 1 n = len(filenames) * (num_opts - 1) if not reference == []: for ref in reference: # Reference point (geometry, energy) to compare the rest # data to it. geometry is supposed to be in a ASE readable # format, energy in a separate file. atom_ref, y_ref = read_geos_from_file([ref], format=format_ts) # Reference data for the geometries. The Abscissa is # supposed to be on 0.5 reference_int_geos = np.array(carts_to_int(y_ref, [0.5], allval, cell, tomove, howmove, withs)) reference_int_geos = reference_int_geos.T reference_int_geos = reference_int_geos.tolist() # optref = optraw num_opts_ref = num_opts if special_vals != []: # From the special vals only the energies can be # displaced. Therefore special treatment is required. for s_val in special_vals: if s_val.startswith("en") and not reference_data == None: # optref = optraw + " t %i" % (num_opts_raw + 1) reference_data = np.loadtxt(reference_data) reference_int_geos.append([reference_data.tolist()]) else: num_opts_ref = num_opts_ref - 1 if num_opts_ref > 1: colors = [colormap(j, n) for j in range(0, num_opts)] prepare_plot( None, None, None, "_nolegend_", reference_int_geos, "Reference", opt, colors ) # For each file prepare the plot for i, filename in enumerate(filenames): if i < file_range[0] or i > file_range[1]: continue # Extract the data for beads, path if availabe and TS # estimates if requested (else None). beads, path, ts_ests_geos = extract_data(filename, data_ase, other_input, values, ts_estimates, num, i) if ts_ests_geos == []: print >> stderr, "WARNING: No transition state found for file", filename ts_ests_geos = None # The name belonging to filename. name_p = str(i + 1) if names_of_lines[i] != []: name_p = names_of_lines[i] # prepare plot from the tables containing the path and bead def choose_color(j): return colormap(i * (num_opts - 1) + j, n) # data only if there are enough for x AND y values colors = map(choose_color, range(0, num_opts)) if num_opts > 1: if ase: prepare_plot( None, None, None, "_nolegend_", beads, name_p, opt, colors) else: prepare_plot( path, name_p, beads, "_nolegend_", ts_ests_geos, "_nolegend_", opt, colors) # now plot plot_data(hold = hold, xrange = xran, yrange = yran, savefile = outputfile )