#!/usr/bin/env python # Copyright (C) 2011 Atsushi Togo # All rights reserved. # # This file is part of phonopy. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name of the phonopy project nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # PDOS plot (pdosplot) # # Usage: # pdosplot -i "1 2, 4 5" -o "pdos.pdf" # # The axis resolved PDOS is summed up with the successive # indices separated by ",". In this example, indices 1 and # 2, 3 and 4 are summed respectively, and then they are # ploted respectively. # # The indices are defined like: # 1 2 3 : X Y Z of the 1st atom, # 4 5 6 : X Y Z of the 2nd atom, # ... import numpy as np import matplotlib.pyplot as plt # Parse options from optparse import OptionParser parser = OptionParser() parser.set_defaults( output_filename = None, factor = 1.0, legend_labels = None, xlabel = None, ylabel = None, show_legend = False, pdos_indices = None, ymax = None, ymin = None, title = None, f_max = None, f_min = None ) parser.add_option("--factor", dest="factor", type="float", help="Factor is multiplied with DOS.") parser.add_option("-l", "--legend", dest="show_legend", action="store_true", help="Show legend") parser.add_option("--legend_labels", dest="legend_labels", action="store", type="string", help="Set legend labels") parser.add_option("--xlabel", dest="xlabel", action="store", type="string", help="Set x label") parser.add_option("--ylabel", dest="ylabel", action="store", type="string", help="Set y label") parser.add_option("-i", "--indices", dest="pdos_indices", action="store", type="string", help="Indices like 1 2, 3 4 5 6...") parser.add_option("-o", "--output", dest="output_filename", action="store", type="string", help="Output filename") parser.add_option("-t", "--title", dest="title", action="store", type="string", help="Title of plot") parser.add_option("--ymax", dest="ymax", type="float", help="Maximum value of y axis") parser.add_option("--ymin", dest="ymin", type="float", help="Minimum value of y axis") parser.add_option("--fmax", dest="f_max", type="float", help="Maximum frequency plotted") parser.add_option("--fmin", dest="f_min", type="float", help="Minimum frequency plotted") (options, args) = parser.parse_args() # Read data file frequencies = [] dos = [] filename = "partial_dos.dat" if len(args) > 0 : filename = args[0] for line in open( filename ): if line.strip().split()[0] == '#' or line.strip().split() == '': continue tmp_array = [ float(x) for x in line.split() ] frequencies.append( tmp_array.pop(0) ) dos.append( tmp_array ) frequencies = np.array(frequencies) dos = np.array(dos).transpose() # Extract indices indices = [] if options.pdos_indices == None: indices.append( range( 1, dos.shape[0]+1 ) ) else: for v in options.pdos_indices.split(','): indices.append([ int(x) for x in v.split() ]) # Set plot range in frequency axis if options.f_max == None: max_freq = max( frequencies ) else: max_freq = options.f_max if options.f_min == None: min_freq = min( frequencies ) else: min_freq = options.f_min min_i = 0 max_i = len( frequencies ) for i, f in enumerate( frequencies ): if f > max_freq + ( frequencies[1] - frequencies[0] ) / 10: max_i = i + 1 break for i, f in enumerate( frequencies ): if f > min_freq - ( frequencies[1] - frequencies[0] ) / 10: min_i = i break # Plot plots = [] for nums in indices: pdos = np.zeros( frequencies.shape[0], dtype=float ) for v in nums: pdos += dos[v-1] plots.append( plt.plot( frequencies[min_i:max_i], pdos[min_i:max_i] * options.factor ) ) plt.grid(True) plt.xlim( min_freq, max_freq ) if ( not options.ymin == None ) and ( not options.ymax == None ): plt.ylim( options.ymin, options.ymax ) elif options.ymin == None and ( not options.ymax == None ): plt.ylim( ymax=options.ymax ) elif ( not options.ymin == None ) and options.ymax == None: plt.ylim( ymin=options.ymin ) if options.xlabel == None: plt.xlabel('Frequency') else: plt.xlabel( options.xlabel ) if options.ylabel == None: plt.ylabel('Partial density of states') else: plt.ylabel( options.ylabel ) if options.show_legend: if not options.legend_labels == None: if len( options.legend_labels.split() ) == len( plots ): labels = options.legend_labels.split() else: print "Number of labels is not same as number of plots." labels = indices else: labels = indices plt.legend(labels, loc='upper left' ) if not options.title == None: plt.title( options.title ) if not options.output_filename == None: plt.rcParams['pdf.fonttype'] = 42 plt.rcParams['font.family'] = 'serif' plt.savefig(options.output_filename) else: plt.show()