GnuPlot,Python绘图模板整理

 

本文转载自 https://yxli8023.github.io/2021/03/12/Gnu-Plot.html当需要大量通过程序计算,还要绘制图像才可以查看计算结果的时候, 利用Origin绘图显得非常耗时, 所以这里就想把自己通常用到的数据格式, 通过gnuplot来绘制结果, 这样可以在之后的计算研究过程中, 直接通过代码作图, 从而节省时间, 毕竟时间是最重要的东西.

本文转载自 https://yxli8023.github.io/2021/03/12/Gnu-Plot.html

当需要大量通过程序计算,还要绘制图像才可以查看计算结果的时候, 利用Origin绘图显得非常耗时, 所以这里就想把自己通常用到的数据格式, 通过gnuplot来绘制结果, 这样可以在之后的计算研究过程中, 直接通过代码作图, 从而节省时间, 毕竟时间是最重要的东西.

2D密度图

首先通过下面的fortran代码来展示出通过gnuplot来画密度图, 所欲要的数据格式是什么样的, 然后再利用gnuplot来绘图

program main 
implicit none
integer ne
ne = 100
call main1(ne)
stop
end
!=================================
subroutine main1(ne)
implicit none
integer i,j,k,ne
real r1,r2
open(10,file="test.dat")
do i = 1,ne
    do j = 1,ne
       write(10,*)i,j,sqrt(1.0*i) + 2.0*j
    end do
    write(10,*)
end do
close(10)
end subroutine

这里在绘图的时候, 需要在每隔一定的数据间隔后加一个空行, 才可以实现.

png

在程序计算的时候, 将数据保存成上面需要的形式之后, 就可以利用gnuplot来进行绘图

set encoding iso_8859_1
#set terminal  postscript enhanced color
#set output 'arc_r.eps'
#set terminal pngcairo truecolor enhanced  font ",50" size 1920, 1680
set terminal png truecolor enhanced font ",50" size 1920, 1680
set output 'density.png'
#set palette defined ( -10 "#194eff", 0 "white", 10 "red" )  # 密度图颜色设置
set palette defined ( -10 "blue", 0 "white", 10 "red" )
#set palette rgbformulae 33,13,10
unset ztics
unset key
set pm3d
set border lw 6
set size ratio -1
set view map   
set xtics
set ytics
#set xlabel "K_1 (1/{\305})"  # 坐标轴标签设置
set xlabel "X_1"
#set ylabel "K_2 (1/{\305})"
set ylabel "Y"
set ylabel offset 1, 0
set colorbox
set xrange [1: 30]
set yrange [1: 30]
set pm3d interpolate 4,4   # 设置插值,让图像变得更加平滑
splot 't3.dat' u 1:2:3 w pm3d

png

  • 升级版
     set encoding iso_8859_1
     #set terminal  postscript enhanced color
     #set output 'arc_r.eps'
     #set terminal pngcairo truecolor enhanced  font ",50" size 1920, 1680
     set terminal png truecolor enhanced font ",50" size 1920, 1680
     set output 'm01_oxy.png'
     #set palette defined ( -10 "#194eff", 0 "white", 10 "red" )
     set palette defined ( -10 "blue", 0 "white", 10 "red" )
     #set palette rgbformulae 33,13,10
     unset ztics
     unset key
     set pm3d
     #set border lw 6
     set size ratio -1
     set view map
     set xtics
     set ytics
     set xlabel "K_1 (1/{\305})" font 'Times,Bold' offset 0,1.5
     #set xlabel "X"
     set ylabel "K_2 (1/{\305})" font 'Times,Bold' offset 1.5,0
     #set xlabel "X"
     #set ylabel "Y"
     #set ylabel offset 1, 0
     #set xlabel offset 0, 1
     set ytics offset 1,0 font 'Times,Bold'
     set xtics offset 0,1 font 'Times,Bold'
     set mxtics 4
     set mytics 4
     set colorbox
     set cblabel 'cblabel' font 'Times,Bold'
     set cbtics offset -1,0  font 'Times,Bold'
     set xrange [1: 30]
     set yrange [1: 30]
     set pm3d interpolate 4,4
     splot 'ldos-diag01.dat' u 1:2:3 w pm3d
    

png

1d散点图

三点图没太多需要说明的, 就是最简单的一维数据点绘图

set encoding iso_8859_1
#set terminal  postscript enhanced color font ",30"  # Set for eps formation
#set output 'wcc.eps'
set terminal png truecolor enhanced font ",50" size 1920, 1680 # Set for png formation
set output 'eigval.png'
unset key 
set border lw 3 
set xtics offset 0, 0.0
set xtics format "%4.1f" nomirror out 
#set xlabel '{/symbol eta}' 
set xlabel 'k' 
set xlabel offset 0, -1.0 
set ytics 0.5 
unset xtics 
#set ytics format "%4.1f" nomirror out
set ytics format "%4.1f" 
set ylabel "E"
set ylabel offset 0.5, 0.0 
set xrange [3550: 3650]
set yrange [-1.5:1.5]
#plot for [i=4:     4] 'wcc.dat' u 1:i w p  pt 7  ps 1.1 lc 'red'
plot 'eigval.dat' u 1:2 w p pt 7 ps 4 lc 'red'

png

  • 升级版
     set encoding iso_8859_1
     #set terminal  postscript enhanced color
     #set output 'arc_r.eps'
     #set terminal pngcairo truecolor enhanced  font ",50" size 1920, 1680
     set terminal png truecolor enhanced font ",50" size 1920, 1680
     set output 'm01_val.png'
     unset key
     set xlabel "X" font "Times,Bold" offset 0,1.0
     set ylabel "Y" font "Times,Bold" offset 1.5,0
     set ytics offset 0.5,0 font "Times,Bold"
     set xtics offset 0,0.5 font "Times,Bold"
     set xrange [3540:3660]
     set yrange [-0.5:0.5]
     plot 'eigval-diag01.dat' u 1:2 ps 3.0 pt 7
    

png

矢量场图

先利用Fortran产生数据

   program main
   implicit none
   integer i1,i2,i3,num
   real r1,r2,r3
   open(10,file="vec.dat")
   do r1 = -3,3,0.5
      do r2 = -3,3,0.5
         write(10,999)r1,r2,r2,-r1
      end do
   end do
   close(10)
999format(8f11.5)
   stop
   end program main

再利用gnuplot进行绘图

set encoding iso_8859_1
set terminal  pngcairo truecolor enhanced lw 1.0 font "TimesNewRoman, 44" size 1980,1980
set output 'testure.png'
set xlabel 'K_1'
set ylabel 'K_2'
unset key
set pm3d
set border lw 6
set ytics offset 0.5,0 font "Times,Bold"
set xtics offset 0,0.5 font "Times,Bold"
set size ratio 1
set view map
unset colorbox
set xrange [-3:3]
set yrange [-3:3]
splot 'vec.dat' u 1:2:(0):3:4:(0)  w vec  head lw 1

png

绘图设置

set term pdfcairo lw 2 font "Times New Roman,8" # 设置输出pdf格式,使用字体为Times New Roman, 字体大小为8
set terminal postscript eps color solid linewidth 2 # 设置输出eps图片, color为彩图输出
set term pngcairo lw 2 font "AR PL UKai CN,14"  # 设置输出png图片
set output 'test.pdf' # 设置输出文件名
plot 'test.dat' u 1:4 w lp pt 5,'test.dat' u 1:3 w lp pt 7  # 绘图
set output # 输出

投影能带图

set encoding iso_8859_1
#set terminal  postscript enhanced color font "TimesNewRoman, 11" size 5, 4
set terminal  pngcairo truecolor enhanced lw 5.0 font "TimesNewRoman, 44" size 1920, 1680
set palette rgbformulae 22, 13, -31
# # set palette rgbformulae 7,5,15
set output 'C_pz.png'
set border
# unset colorbox
set title "C\\_pz" offset 0, -0.8 font "TimesNewRoman, 54"
set style data linespoints
unset ztics
unset key
# # set key outside top vertical center
# # set pointsize 0.3
set view 0,0
set xtics font "TimesNewRoman, 44"
set xtics offset 0, 0.3
set ytics font "TimesNewRoman, 40"
set ytics -10, 5, 10
set ylabel font "TimesNewRoman, 48"
set ylabel offset 1.0, 0
set xrange [0:5.4704]
set ylabel "Energy (eV)"
set yrange [-15:15]
set xtics ("G" 0.00000, "K" 1.695, "M" 3.938, "G" 5.407)
plot -10 with filledcurves y1=10 lc rgb "navy", \
'PBAND_C.dat' u ($1):($2):($5) w lines lw 1.5 lc palette

这个程序是我从使用gnuplot画投影能带图这篇博客中找到的,利用这个模板绘制了Graphene的能带

png

python同样也可以绘制相同的图片,不过相比较而言,找到的Python这个绘图模板可以同时对多个原子的投影轨道进行绘制

#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
@author: V. Wang, Jin-Cheng Liu, Nxu
@file: pband_plot.py
@time: 2018/12/18 20:57
A script to plot PBAND
modified some details by He Yong
"""

import numpy as np
import matplotlib as mpl
import os
mpl.use('Agg')  # silent mode
from matplotlib import pyplot as plt
import matplotlib.ticker as ticker
import sys

#------------------- rc.Params 1----------------------
plt.rcParams['xtick.direction'] = 'in'
plt.rcParams['ytick.direction'] = 'in'

#------------------- Data Read ----------------------

def getelementinfo():
    try:
        with open("POSCAR",'r') as reader:
            line_s=reader.readlines()
    except:
        print("No POSCAR found!")
    try:    
        element_s=line_s[5].rstrip('\r\n').rstrip('\n')
        elements=element_s.split()
    except:
        print("POSCAR element line is wrong!")

    data = {}
    for i in range(len(elements)):
        data[elements[i]]=np.loadtxt("PBAND_" + elements[i] + ".dat")
    return data,elements

def getHighSymmetryPoints():
    hsp = np.loadtxt("KLABELS", dtype=np.string_, skiprows=1, usecols=(0, 1))
    group_labels = hsp[:-1, 0].tolist()
    group_labels = [i.decode('utf-8', 'ignore') for i in group_labels]
    for index in range(len(group_labels)):
        if group_labels[index] == "GAMMA":
            group_labels[index] = u"Γ"
    return group_labels, hsp


def maxminnorm(a):
    amin, amax = a.min(), a.max()  # fin maximum minimum
    if amax == 0:
        return a
    else:
        a = (a - amin) / (amax - amin)  # (value-minimum)/(maximum-minimum)
        return a


def getPbandData(data, scaler):
    kpt = data[:, 0]  # kpath
    eng = data[:, 1]  # energy level
    wgt_s = data[:, 2] * scaler  # weight, 20 is enlargement factor
    #wgt_s = maxminnorm(wgt_s) * scaler  # Normlized

    wgt_py = data[:, 3] * scaler  # weight, 20 is enlargement factor
    #wgt_py = maxminnorm(wgt_py)*scaler
    wgt_pz = data[:, 4] * scaler  # weight, 20 is enlargement factor
    #wgt_pz = maxminnorm(wgt_pz)*scaler

    wgt_px = data[:, 5] * scaler  # weight, 20 is enlargement factor
    #wgt_px = maxminnorm(wgt_px)*scaler

    wgt_p = np.array(wgt_py) + np.array(wgt_px) + np.array(wgt_pz)
    #wgt_p = maxminnorm(wgt_p) * scaler  # Normlized


    wgt_dxy = data[:, 6] * scaler
    #wgt_dxy = maxminnorm(wgt_dxy) * scaler  # Normlized

    wgt_dyz = data[:, 7] * scaler
    #wgt_dyz = maxminnorm(wgt_dyz) * scaler
    wgt_dz2 = data[:, 8] * scaler
    #wgt_dz2 = maxminnorm(wgt_dz2) * scaler
    wgt_dxz = data[:, 9] * scaler
    #wgt_dxz = maxminnorm(wgt_dxz) * scaler
    wgt_dx2y2 = data[:, 10] * scaler
    #wgt_dx2y2 = maxminnorm(wgt_dx2y2) * scaler
    wgt_d = np.array(wgt_dxy) + np.array(wgt_dyz) + np.array(wgt_dz2) \
             + np.array(wgt_dxz) + np.array(wgt_dx2y2)
    #wgt_d = maxminnorm(wgt_d) * scaler  # Normlized

    #wgt_tot = maxminnorm(data[:, 11]) * scaler
    wgt_tot = data[:, 11] * scaler
    return kpt, eng, wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy,  \
            wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot

#------------------- Pband Plot ----------------------


class pbandplots(object):
    def __init__(self,lwd,op,scaler,energy_limits,font,dpi,figsize,corlor0):
        from matplotlib import pyplot as plt
        self.data,self.elements=getelementinfo()
        self.group_labels, self.hsp = getHighSymmetryPoints()    # HighSymmetryPoints_labels 
        self.x = [float(i) for i in self.hsp[:-1, 1].tolist()]   # HighSymmetryPoints_coordinate
        self.lwd=lwd ; self.op=op;self.scaler=scaler;self.energy_limits=energy_limits
        self.font=font;self.dpi=dpi;self.figsize=figsize
        self.corlor0=corlor0 
    def plotfigure(self,ax, kpt, eng, title):
        ax.plot(kpt, eng, color=self.corlor0, lw=self.lwd, linestyle='-', alpha=1)
        ax.yaxis.set_minor_locator(ticker.MultipleLocator(1.00))  # determine the minor locator of y-axis
        ax.set_ylim(self.energy_limits)
        ytick = np.arange(self.energy_limits[0], self.energy_limits[1], 2)  # determine the major loctor of y-axis
        ax.yaxis.set_major_locator(ticker.MultipleLocator(2.00))  # determine the major loctor of y-axis
        # a = int(len(ytick) / 2)
        # plt.yticks(np.insert(ytick, a, 0))
        ax.set_xticks(self.x)
        plt.yticks(fontsize=self.font['size']-2,fontname=self.font['family'])
        plt.ylabel(r'Energy (eV)', fontdict=self.font)
        # plt.suptitle(title)
        ax.set_xticklabels(self.group_labels, rotation=0, fontsize=self.font['size']-2,fontname=self.font['family'])
        ax.axhline(y=0, xmin=0, xmax=1, linestyle='--', linewidth=0.5, color='k') # determine the line style of E-fermi energy
        for i in self.x[1:-1]:
            ax.axvline(x=i, ymin=0, ymax=1, linestyle='--', linewidth=0.5, color='k') # determine the line style of HighSymmetry lines
        ax.set_xlim((self.x[0], self.x[-1]))
        return plt

    def plotPbandAllElementsspd(self):
        from matplotlib import pyplot as plt
        print("start plot PBAND for all Elements with s p d projection in one figure !...")
        colorcode = ['blue', 'black', 'red', 'green', 'yellow','purple','chartreuse','fuchsia','orangered','hotpink','violet','teal']  #if number of orbitals are more 3,one need increase the number of colors in "colorcode"
        markerorder=['o','v','p','*','>','s','1','2','3','4','x','+']
        fig = plt.figure(figsize=self.figsize)
        ax = fig.add_subplot(111)
        for elementorder in range(len(self.elements)):
            kpt, eng, wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy, wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot \
            = getPbandData(self.data[self.elements[elementorder]],self.scaler)
            if (np.array(wgt_d) == np.zeros_like(np.array(wgt_d))).all() and (np.array(wgt_p) == np.zeros_like(np.array(  wgt_p))).all():
               ax.scatter(kpt, eng, s=wgt_s, color=colorcode[3*elementorder], edgecolor=colorcode[3*elementorder], linewidths=0.2,\
               alpha=op,marker=markerorder[3*elementorder])
       
            elif (np.array(wgt_d) == np.zeros_like(np.array(wgt_d))).all() and not (np.array(wgt_p) == np.zeros_like(np.array(wgt_p))).all():
               ax.scatter(kpt, eng, s=wgt_s, color=colorcode[3*elementorder], edgecolor=colorcode[3*elementorder], linewidths=0.2,\
               alpha=op,marker=markerorder[3*elementorder])
               ax.scatter(kpt, eng, s=wgt_p,color=colorcode[3*elementorder+1], edgecolor=colorcode[3*elementorder+1], linewidths=0.2,\
               alpha=op - 0.4,marker=markerorder[3*elementorder+1])
            elif not (np.array(wgt_d) == np.zeros_like(np.array(wgt_d))).all() and not (np.array(wgt_p) == np.zeros_like(np.array(wgt_p))).all():
               ax.scatter(kpt, eng, s=wgt_s, color=colorcode[3*elementorder], edgecolor=colorcode[3*elementorder], linewidths=0.2,\
               alpha=op,marker=markerorder[3*elementorder])
               ax.scatter(kpt, eng, s=wgt_p,color=colorcode[3*elementorder+1], edgecolor=colorcode[3*elementorder+1], linewidths=0.2,\
               alpha=op - 0.4,marker=markerorder[3*elementorder+1])
               ax.scatter(kpt, eng, s=wgt_d, color=colorcode[3*elementorder+2], edgecolor=colorcode[3*elementorder+2],linewidths=0.2,\
               alpha=op - 0.6,marker=markerorder[3*elementorder+2])
       
       #del wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy, wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot
        legend_s=[]
        for leg in range(len(self.elements)):
            '''
            legend_s.append('$' + elements[leg] + '$'+'$(s)$')
            legend_s.append('$' + elements[leg] + '$'+'$(p)$')
            legend_s.append('$' + elements[leg] + '$'+'$(d)$')
            '''
            if (np.array(wgt_d) == np.zeros_like(np.array(wgt_d))).all() and (np.array(wgt_p) == np.zeros_like(np.array(  wgt_p))).all():
               legend_s.append('' + self.elements[leg] + ''+'_s')
            elif (np.array(wgt_d) == np.zeros_like(np.array(wgt_d))).all() and not (np.array(wgt_p) == np.zeros_like(np.array(wgt_p))).all():
               legend_s.append('' + self.elements[leg] + ''+'_s')
               legend_s.append('' + self.elements[leg] + ''+'_p')
            elif not (np.array(wgt_d) == np.zeros_like(np.array(wgt_d))).all() and not (np.array(wgt_p) == np.zeros_like(np.array(wgt_p))).all():
               legend_s.append('' + self.elements[leg] + ''+'_s')
               legend_s.append('' + self.elements[leg] + ''+'_p')
               legend_s.append('' + self.elements[leg] + ''+'_d')
        ax.legend(tuple(legend_s),loc='best', shadow=False, labelspacing=0.1)
        title0=" "
        for atom in range(len(self.elements)):
            title0=self.elements[atom] + title0
        plt = self.plotfigure(ax, kpt, eng, title0+'  orbital progection' )
   
        # plt.subplots_adjust(top=0.950,bottom=0.110,left=0.165,right=0.855,wspace=0)
        plt.savefig('PBND'+title0.rstrip('\r\n').rstrip()+'spd.png', bbox='tight', pad_inches=0.1, dpi=1000)
             #del ax, fig

    def plotPbandspd(self):
        from matplotlib import pyplot as plt
        print("start plot PBAND for each Elements with s p d projection...")
        for element in self.elements:
            print("plot ", element)
            fig = plt.figure(figsize=self.figsize)
            ax = fig.add_subplot(111)
            kpt, eng, wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy, wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot\
                = getPbandData(self.data[element],self.scaler)
            ax.scatter(kpt, eng, wgt_s, color='blue', edgecolor='blue', linewidths=0.2, alpha=self.op,marker='o')
            ax.scatter(kpt, eng, wgt_p, color='black', edgecolor='cyan', linewidths=0.2, alpha=self.op - 0.6,marker='v')
            ax.scatter(kpt, eng, wgt_d, color='red', edgecolor='red', linewidths=0.2, alpha=self.op - 0.85,marker='*')

            if (np.array(wgt_d) == np.zeros_like(np.array(wgt_d))).all() and (np.array(wgt_p) == np.zeros_like(np.array(wgt_p))).all():
                ax.legend(('s'), loc='best', shadow=False, labelspacing=0.1)
            elif (np.array(wgt_d) == np.zeros_like(np.array(wgt_d))).all() and not (np.array(wgt_p) == np.zeros_like(np.array(wgt_p))).all():
                ax.legend(('s', 'p'), loc='best', shadow=False, labelspacing=0.1)
            elif not (np.array(wgt_d) == np.zeros_like(np.array(wgt_d))).all() and not (np.array(wgt_p) == np.zeros_like(np.array(wgt_p))).all():
                ax.legend(('s', 'p', 'd'), loc='best', shadow=False, labelspacing=0.1)
            plt = self.plotfigure(ax, kpt, eng, element)
            # plt.subplots_adjust(top=0.950,bottom=0.110,left=0.165,right=0.855,wspace=0)
            plt.savefig('PBAND_' + element + '_spd.png', bbox_inches='tight', pad_inches=0.1, dpi=self.dpi)
            #del ax, fig

    def plotPbandAllElements(self):
        from matplotlib import pyplot as plt
        print("start plot PBAND including Elements...")
        #colorcode = ['blue', 'red', 'black', 'green', 'yellow']
        colorcode = ['blue', 'black', 'red', 'green', 'yellow']
        markerorder=['v', 'o', 'p', '*', '>']
        fig = plt.figure(figsize=self.figsize)
        ax = fig.add_subplot(111)

        for elementorder in range(len(self.elements)):
            #del wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy, wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot
            kpt, eng, wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy, wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot \
                = getPbandData(self.data[self.elements[elementorder]],self.scaler)
            ax.scatter(kpt, eng, wgt_tot, color=colorcode[elementorder], edgecolor=colorcode[elementorder], \
                       linewidths=0.2, alpha=self.op-elementorder*0.2,marker=markerorder[elementorder])

        if len(self.elements) == 5:
            ax.legend(('' + self.elements[0] + '', '' + self.elements[1] + '', '' + self.elements[2] + '', '' + self.elements[3] + '', '' + self.elements[4] + ''),\
                      loc='best', shadow=False, labelspacing=0.1)
        elif len(self.elements) == 4:
            ax.legend(('' + self.elements[0] + '', '' + self.elements[1] + '', '' + self.elements[2] + '', '' + self.elements[3] + ''),\
                      loc='best', shadow=False, labelspacing=0.1)
        elif len(self.elements) == 3:
            ax.legend(('' + self.elements[0]+'', '' + self.elements[1] + '', '' + self.elements[2] + ''),\
                      loc='best', shadow=False, labelspacing=0.1)
        elif len(self.elements) == 2:
            ax.legend(('' + self.elements[0] + '', '' + self.elements[1] + ''), \
                      loc='best', shadow=False, labelspacing=0.1)
        elif len(self.elements) == 1:
            ax.legend(('' + self.elements[0] + ''), \
                      loc='best', shadow=False, labelspacing=0.1)
        title0=" "
        for atom in range(len(self.elements)):
            title0=self.elements[atom] + title0 
        plt = self.plotfigure(ax, kpt, eng, title0)
        # plt = self.plotfigure(ax, kpt, eng, self.elements[elementorder])
        # plt.subplots_adjust(top=0.950,bottom=0.110,left=0.165,right=0.855,wspace=0)
        plt.savefig('Projected_Band.png', bbox_inches='tight', pad_inches=0.1, dpi=self.dpi)
        #del ax, fig

    def plotPbandEachElements(self):
        from matplotlib import pyplot as plt
        print("start plot PBAND including each Elements...")
        #colorcode = ['red','black','blue' , 'green', 'yellow']
        colorcode = ['blue', 'black', 'red', 'green', 'yellow']

        for elementorder in range(len(self.elements)):
            print("plot ", self.elements[elementorder])
            fig = plt.figure(figsize=self.figsize)
            ax = fig.add_subplot(111)
            #del wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy, wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot
            kpt, eng, wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy, wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot \
                = getPbandData(self.data[self.elements[elementorder]],self.scaler)
            ax.scatter(kpt, eng, wgt_tot, color=colorcode[elementorder], edgecolor=colorcode[elementorder], \
                       linewidths=0.2, alpha=self.op-elementorder*0.2, marker='v')
            #print(elements)
            #ax.legend(elements[elementorder], shadow=False, labelspacing=0.1)
            plt.legend(labels=['' + self.elements[elementorder] + ''],shadow=False, labelspacing=0.1, loc='best')
            plt = self.plotfigure(ax, kpt, eng, self.elements[elementorder])
            # plt.subplots_adjust(top=0.950,bottom=0.110,left=0.165,right=0.855,wspace=0)
            plt.savefig('PBAND_'+self.elements[elementorder]+'.png', bbox_inches='tight',pad_inches=0.1, dpi=self.dpi)
            #del ax, fig

    def plotPbandpxpypz(self):
        from matplotlib import pyplot as plt
        print("start plot PBAND including s pxpypz for each Elements...")
        #colorcode = ['blue', 'black', 'red', 'green', 'yellow']
        colorcode = ['blue', 'black', 'red', 'green', 'yellow']

        for elementorder in range(len(self.elements)):
            print("plot ", self.elements[elementorder])
            fig = plt.figure(figsize=self.figsize)
            ax = fig.add_subplot(111)
            #del wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy, wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot
            kpt, eng, wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy, wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot \
                = getPbandData(self.data[self.elements[elementorder]],self.scaler)
            ax.scatter(kpt, eng, wgt_s, color='blue', edgecolor='blue', alpha=self.op,marker='o')
            ax.scatter(kpt, eng, wgt_py, color='black', edgecolor='cyan', alpha=self.op - 0.1,marker='v')
            ax.scatter(kpt, eng, wgt_pz, color='red', edgecolor='red', alpha=self.op - 0.4,marker='p')
            ax.scatter(kpt, eng, wgt_px, color='magenta', edgecolor='magenta', alpha=self.op - 0.7,marker='*')
            ax.legend(('s', 'p_y', 'p_z', 'p_x'), loc='upper right', shadow=False, labelspacing=0.1)

            plt = self.plotfigure(ax, kpt, eng, self.elements[elementorder])
            # plt.subplots_adjust(top=0.950,bottom=0.110,left=0.165,right=0.855,wspace=0)
            plt.savefig('PBAND_'+self.elements[elementorder]+'_spxpypz.png', bbox_inches='tight',pad_inches=0.1, dpi=self.dpi)
            #del ax, fig
    def plottotalBands(self):
        from matplotlib import pyplot as plt
        print("start plot total BANDs ...")
        #colorcode = ['blue', 'black', 'red', 'green', 'yellow']
        colorcode = ['blue', 'black', 'red', 'green', 'yellow']
        markerorder=['o','v','p','*','>']
        fig = plt.figure(figsize=self.figsize)
        ax = fig.add_subplot(111)

        kpt, eng, wgt_s, wgt_py, wgt_pz, wgt_px, wgt_p, wgt_dxy, wgt_dyz, wgt_dz2, wgt_dxz, wgt_dx2y2, wgt_d, wgt_tot \
        = getPbandData(self.data[self.elements[0]],self.scaler) 
        title0=" "
        for atom in range(len(self.elements)):
            title0=self.elements[atom] + title0 
        plt = self.plotfigure(ax, kpt, eng, title0)
        # plt = self.plotfigure(ax, kpt, eng, self.elements[elementorder])
        # plt.subplots_adjust(top=0.950,bottom=0.110,left=0.165,right=0.855,wspace=0)
        plt.savefig('Total_Band.png', bbox_inches='tight', pad_inches=0.1, dpi=self.dpi)
        #del ax, fig

if __name__ == "__main__":
    
    #___________________________________SETUP____________________________________
    
        
    print("    ****************************************************************")
    print("    * This is a code used to plot kinds of bandstructure,written by*")
    print("    *   V.Wang,Jin-Cheng Liu,modfied by Nan Xu,Xue Fei Liu         *")
    print("    ****************************************************************")
    print( "\n")
    print("    ****************************************************************")
    print("    *     Type of bandstructures are obtained as below:            *") 
    print("    * 1).For total bandstructure of all atoms in one figure        *")
    print("    * 2).For projected bands of each element in separated figures  *")    
    print("    * 3).For total spd orbitals of total elements in one figure    *")
    print("    * 4).For s-pxpypz of each element in separated figures         *")
    print("    * 5).For all elements and correspond spd orbitals in one figure*")
    print("    * 6).For a total bandstructure                                 *")
    print("    ****************************************************************")
    print("                       (^o^)GOOD LUCK!(^o^)                         ")
    print( "\n")
    
    print( " Band plot initialization... ")
    print( "*******************************************************************")
    print("Please set the color and width of line in figure,input line=0.2")
    print(" and color = 'black' for choice 1->5,input line >= 1 and color =")
    print(" 'red','blue' or .... for choice 6")
    print( "********************************************************************")

    corlor0 = str(input("Input color = ? according to your choice number:"))
    lwd = float(input("Input line =? according to your choice number:"))
    print("*********************************************************************")
    print(  "Which kind of bandstructure do you need plot ?")
    print(  "Please type in a number to select a function: e.g.1, 2 ....,")
    print("*********************************************************************")

    
    op = 1  # Max alpha blending value, between 0 (transparent) and 1 (opaque).
    scaler = 60  # Scale factor for projected band
    energy_limits=(-10, 10)  # energy ranges for PBAND
    dpi=1000          # figure_resolution
    figsize=(5, 4)   #figure_inches
    font = {'family' : 'Times New Roman', 
        'color'  : 'black',
        'weight' : 'normal',
        'size' : 15.0,
        }       #FONT_setup
    pband_plots=pbandplots(lwd,op,scaler,energy_limits,font,dpi,figsize,corlor0)
	
    try:
        bandtype = int(input("Input number--->"))
    except ValueError:
        raise ValueError(" You have input wrong ! Please rerun this code !")
	
    if bandtype == 1:
        pband_plots.plotPbandAllElements()  # plot pband for all element in one figure
    elif bandtype == 2:
        pband_plots.plotPbandEachElements()  # plot pband for each element
    elif bandtype == 3:
        pband_plots.plotPbandspd()  # plot pband with different angular momentum        
    elif bandtype == 4:
        pband_plots.plotPbandpxpypz()  # plot pband with Magnetic angular momentum   
    elif bandtype == 5:
        pband_plots.plotPbandAllElementsspd() #plot pband of all enlenments and spd orbitals
    elif bandtype == 6:
        pband_plots.plottotalBands()	
    else :
        print(" You have input wrong ! Please rerun this code !" )
        sys.exit(0)     

png

Wannier90 plot

在通过紧束缚模型计算能带的时候,Wannier90虽然会自动给出一个绘制能带的脚本, 但是它并不会保存能带图, 只能立即查看,这是非常不方便的,这里就参考前面的模板来将这个自动产生的脚本进行修改,可执行图片保存,这对后续结果的整理是非常方便的.

set encoding iso_8859_1
set terminal  pngcairo truecolor enhanced lw 5.0 font "TimesNewRoman, 44" size 1920, 1680
#set style data dots
set nokey
set output 'band-wannier90.png'
set xrange [0: 3.40639]
set yrange [-20.85655 :  5.60054]
set arrow from  1.43966, -20.85655 to  1.43966,   5.60054 nohead
set arrow from  2.68656, -20.85655 to  2.68656,   5.60054 nohead
set xtics (" K "  0.00000," G "  1.43966," M "  2.68656," K "  3.40639)
plot -20 with filledcurves y1=20 lc rgb "plum", "wannier90_band.dat" u 1:2 w l lw 1.5 lc rgb "navy" 

png

Cylinder 能带图

在计算拓扑边界态的时候通常需要将一个方向开边界,另外一个方向取周期,此时就可以绘制cylinder geometry能带图,绘制代码如下

 set terminal png truecolor enhanced font ",50" size 3000, 1500
 set output 'cy01.png'
 set size 1, 1
 set multiplot layout 1, 2
 unset key
 set ytics 1.5 
 set xtics 0.5
 set xtics offset 0, 0.0
 set xtics format "%4.1f" nomirror out 
 set ytics format "%4.1f"
 set ylabel "E"
 set ylabel offset 0.5, 0.0 
 #set xlabel offset 0, -1.0 
 set xrange [-1:1]
 set yrange [-3:3]
 set xlabel 'k_y' 
 plot for [i=2:400] 'ox-sc01.dat' u 1:i w l lw 5 lc 'blue'
 set xlabel 'k_x' 
 plot for [i=2:400] 'oy-sc01.dat' u 1:i w l lw 5 lc 'blue'
 unset multiplot

结果如下图

png

产生数据的Fortran程序如下

!   Anticommute mass term 
!   tau*spin*orbit
    module pub
    implicit none
    integer yn,kn,ne,N,enn,hn
    real eng   ! energy
    parameter(yn = 50,hn =  8,kn = 50, ne = 50,N = yn*hn)
    real,parameter::pi = 3.1415926535
    complex,parameter::im = (0.,1.0)  
    complex Ham(N,N) 
    !--------------------------------
    character*12::fn1,fn2,fn3,fn4
    !--------------------------------
    real m0,mu,ax,ay,gamma,tx,ty,dx,dy,d0
    complex g1(hn,hn) ,g4(hn,hn),g2(hn,hn),g3(hn,hn),g5(hn,hn)
    complex am1(hn,hn),am2(hn,hn),am3(hn,hn),am4(hn,hn)
    complex am5(hn,hn),am6(hn,hn),am7(hn,hn),am8(hn,hn),am(hn,hn)
    real mm0,mmx,mmy
    !---------------------------------
    integer::lda = N
    integer,parameter::lwmax = 2*N + N**2
    real,allocatable::w(:)
    complex,allocatable::work(:)
    real,allocatable::rwork(:)
    integer,allocatable::iwork(:)
    integer lwork   
    integer lrwork    
    integer liwork   
    integer info
    end module pub
!================= PROGRAM START ============================
    program sol
    use pub
!====空间申请==================
    allocate(w(N))
    allocate(work(lwmax))
    allocate(rwork(1+5*N+2*N**2))
    allocate(iwork(3+5*N))
!======parameter value setting =====
    m0 = 1.5
    ! mu = 0.3
    tx = 1.0
    ty = 1.0
    ax = 1.0
    ay = 1.0
    ! dx = 0.5
    ! dy = -dx
    mm0 = 0.0
    mmx = 0.5
    mmy = -mmx
    call Pauli()
    ! am = am1
    ! call cylinder()
    call main1()
    ! call plot(1)
    stop 
    end program sol
!====================================================================================
    subroutine main1()
    use pub
    am = am1
    call cylinder(1)
    call plot(1)

    am = am2
    call cylinder(2)
    call plot(2)

    am = am3
    call cylinder(3)
    call plot(3)

    am = am5
    call cylinder(5)
    call plot(5)

    am = am6
    call cylinder(6)
    call plot(6)

    am = am7
    call cylinder(7)
    call plot(7)

    am = am8
    call cylinder(8)
    call plot(8)

    end subroutine main1
!=============================================================================================
    subroutine cylinder(m3)
    !  Calculate edge spectrum function
    use pub
    integer m1,m2,m3
    real kx,ky
    character*20::str1,str2,str3,str4,str5,str6
    str1 = "oy-sc"
    str2 = "ox-sc"
    write(str3,"(I2.2)")m3
    str4 = ".dat"
    str5 = trim(str1)//trim(str3)//trim(str4)
    str6 = trim(str2)//trim(str3)//trim(str4)
    open(30,file=str5)
    !-------------------------------------------------
    !   y-direction is open
    do m1 = -kn,kn
        kx = pi*m1/kn
        call openy(kx,0)
        write(30,999)kx/pi,(w(i),i = 1,N)
    end do
    close(30)
    !--------------------------------------------------
    !  x-direction is open
    open(31,file=str6)
    do m1 = -kn,kn
        ky = pi*m1/kn
        call openx(ky,0)
        write(31,999)ky/pi,(w(i),i=1,N)
    end do
    close(31)
999 format(802f11.5)
    return
    end subroutine cylinder
!======================== Pauli Matrix driect product============================
    subroutine Pauli()
    use pub
    !---------Kinetic energy
    g1(1,1) = 1
    g1(2,2) = -1
    g1(3,3) = 1
    g1(4,4) = -1
    g1(5,5) = -1
    g1(6,6) = 1
    g1(7,7) = -1
    g1(8,8) = 1
    !----------SOC-x
    g2(1,2) = 1
    g2(2,1) = 1
    g2(3,4) = -1
    g2(4,3) = -1
    g2(5,6) = 1
    g2(6,5) = 1
    g2(7,8) = -1
    g2(8,7) = -1
    !---------SOC-y
    g3(1,2) = -im
    g3(2,1) = im
    g3(3,4) = -im
    g3(4,3) = im
    g3(5,6) = im 
    g3(6,5) = -im
    g3(7,8) = im
    g3(8,7) = -im
    !-------------------SC pairing
    g4(1,7) = -1
    g4(2,8) = -1
    g4(3,5) = 1
    g4(4,6) = 1
    g4(5,3) = 1
    g4(6,4) = 1
    g4(7,1) = -1
    g4(8,2) = -1
    !------------------- Chemical potential
    g5(1,1) = 1
    g5(2,2) = 1
    g5(3,3) = 1
    g5(4,4) = 1
    g5(5,5) = -1
    g5(6,6) = -1
    g5(7,7) = -1
    g5(8,8) = -1
    !-------------------Anti Mass-------------------------------
    !x,y,i TRB
    am1(1,7) = -im
    am1(2,8) = -im
    am1(3,5) = im
    am1(4,6) = im
    am1(5,3) = -im
    am1(6,4) = -im
    am1(7,1) = im
    am1(8,2) = im
    !z,x,x TRB
    am2(1,4) = 1
    am2(2,3) = 1
    am2(3,2) = 1
    am2(4,1) = 1
    am2(5,8) = -1
    am2(6,7) = -1
    am2(7,6) = -1
    am2(8,5) = -1
    !x,x,i TRB
    am3(1,7) = 1
    am3(2,8) = 1
    am3(3,5) = 1
    am3(4,6) = 1
    am3(5,3) = 1
    am3(6,4) = 1
    am3(7,1) = 1
    am3(8,2) = 1
    !y,y,i---> SC Term

    !i,y,x  TRB
    am5(1,4) = -im
    am5(2,3) = -im
    am5(3,2) = im
    am5(4,1) = im
    am5(5,8) = -im
    am5(6,7) = -im
    am5(7,6) = im
    am5(8,5) = im
    !y,x,i  TRS
    am6(1,7) = -im
    am6(2,8) = -im
    am6(3,5) = -im
    am6(4,6) = -im
    am6(5,3) = im
    am6(6,4) = im
    am6(7,1) = im
    am6(8,2) = im
    !i,x,x TRB
    am7(1,4) = 1
    am7(2,3) = 1
    am7(3,2) = 1
    am7(4,1) = 1
    am7(5,8) = 1
    am7(6,7) = 1
    am7(7,6) = 1
    am7(8,5) = 1
    !z,x,y TRB
    am8(1,4) = -im
    am8(2,3) = im
    am8(3,2) = -im
    am8(4,1) = im
    am8(5,8) = im
    am8(6,7) = -im
    am8(7,6) = im
    am8(8,5) = -im
    return
    end subroutine Pauli
!==========================================================
    subroutine openx(ky,input)
    use pub
    real ky
    integer m,l,k,input
    Ham = 0
!========== Positive energy ========
    do k = 0,yn-1
        if (k == 0) then ! Only right block in first line
            do m = 1,hn
                do l = 1,hn
                    Ham(m,l) = (m0-ty*cos(ky))*g1(m,l) + ay*sin(ky)*g3(m,l) + (d0 + dy*cos(ky))*g4(m,l)
                    Ham(m,l) = Ham(m,l) + (mm0 + mmy*cos(ky))*am(m,l)

                    Ham(m,l + hn) = (-tx*g1(m,l) - im*ax*g2(m,l) - im*del*g4(m,l))/2 + dx/2.0*g4(m,l)
                    Ham(m,l + hn) = Ham(m,l + hn) + mmx/2.0*am(m,l)
                end do
            end do
        elseif ( k==yn-1 ) then ! Only left block in last line
            do m = 1,hn
                do l = 1,hn
                    Ham(k*hn + m,k*hn + l) = (m0-ty*cos(ky))*g1(m,l) + ay*sin(ky)*g3(m,l) + (d0 + dy*cos(ky))*g4(m,l)
                    Ham(k*hn + m,k*hn + l) = Ham(k*hn + m,k*hn + l) + (mm0 + mmy*cos(ky))*am(m,l)

                    Ham(k*hn + m,k*hn + l - hn) = -tx*g1(m,l)/2 + im*ax*g2(m,l)/2 + im*del*g4(m,l)/2.0 + dx/2.0*g4(m,l)
                    Ham(k*hn + m,k*hn + l - hn) = Ham(k*hn + m,k*hn + l - hn) + mmx/2.0*am(m,l)
                end do
            end do
        else
            do m = 1,hn
                do l = 1,hn ! k start from 1,matrix block from 2th row
                    Ham(k*hn + m,k*hn + l) = (m0 - ty*cos(ky))*g1(m,l) + ay*sin(ky)*g3(m,l) + (d0 + dy*cos(ky))*g4(m,l)
                    Ham(k*hn + m,k*hn + l) = Ham(k*hn + m,k*hn + l) + (mm0 + mmy*cos(ky))*am(m,l)

                    Ham(k*hn + m,k*hn + l + hn) = (-tx*g1(m,l) - im*ax*g2(m,l))/2 + dx/2.0*g4(m,l)
                    Ham(k*hn + m,k*hn + l + hn) = Ham(k*hn + m,k*hn + l + hn) + mmx/2.0*am(m,l)

                    Ham(k*hn + m,k*hn + l - hn) = -tx*g1(m,l)/2 + im*ax*g2(m,l)/2 + dx/2.0*g4(m,l)
                    Ham(k*hn + m,k*hn + l - hn) = Ham(k*hn + m,k*hn + l - hn) + mmx/2.0*am(m,l)
                end do
            end do
        end if
    end do
    !------------------------
    call isHermitian()
    call eigsol(input)
    return
    end subroutine openx
!==========================================================
    subroutine openy(kx,input)
    use pub
    real kx
    integer m,l,k,input
    Ham = 0
!========== Positive energy ========
    do k = 0,yn-1
        if (k == 0) then ! Only right block in first line
            do m = 1,hn
                do l = 1,hn
                    Ham(m,l) = (m0-tx*cos(kx))*g1(m,l) + ax*sin(kx)*g2(m,l) + (d0 + dx*cos(kx))*g4(m,l)
                    Ham(m,l) = Ham(m,l) + (mm0 + mmx*cos(kx))*am(m,l)

                    Ham(m,l + hn) = (-ty*g1(m,l) - im*ay*g3(m,l))/2 + dy/2.0*g4(m,l)
                    Ham(m,l + hn) = Ham(m,l + hn) + mmy/2.0*am(m,l)
                end do
            end do
        elseif ( k==yn-1 ) then ! Only left block in last line
            do m = 1,hn
                do l = 1,hn
                    Ham(k*hn + m,k*hn + l) = (m0-tx*cos(kx))*g1(m,l) + ax*sin(kx)*g2(m,l) + (d0 + dx*cos(kx))*g4(m,l)
                    Ham(k*hn + m,k*hn + l) = Ham(k*hn + m,k*hn + l) + (mm0 + mmx*cos(kx))*am(m,l)

                    Ham(k*hn + m,k*hn + l - hn) = -ty*g1(m,l)/2 + im*ay*g3(m,l)/2 + dy/2.0*g4(m,l)
                    Ham(k*hn + m,k*hn + l - hn) = Ham(k*hn + m,k*hn + l - hn) + mmy/2.0*am(m,l)
                end do
            end do
        else
            do m = 1,hn
                do l = 1,hn ! k start from 1,matrix block from 2th row
                    Ham(k*hn + m,k*hn + l) = (m0-tx*cos(kx))*g1(m,l) + ax*sin(kx)*g2(m,l) + (d0 + dx*cos(kx))*g4(m,l)
                    Ham(k*hn + m,k*hn + l) = Ham(k*hn + m,k*hn + l) + (mm0 + mmx*cos(kx))*am(m,l)

                    Ham(k*hn + m,k*hn + l + hn) = (-ty*g1(m,l) - im*ay*g3(m,l) )/2 + dy/2.0*g4(m,l)
                    Ham(k*hn + m,k*hn + l + hn) = Ham(k*hn + m,k*hn + l + hn) + mmy/2.0*am(m,l)

                    Ham(k*hn + m,k*hn + l - hn) = -ty*g1(m,l)/2 + im*ay*g3(m,l)/2 + dy/2.0*g4(m,l)
                    Ham(k*hn + m,k*hn + l - hn) = Ham(k*hn + m,k*hn + l - hn) + mmy/2.0*am(m,l)
                end do
            end do
        end if
    end do
    !---------------------------------
    call isHermitian()
    call eigsol(input)
    return
    end subroutine openy
!============================================================
    subroutine isHermitian()
    use pub
    integer i,j
    do i = 1,N
        do j = 1,N
            if (Ham(i,j) .ne. conjg(Ham(j,i)))then
                open(160,file = 'hermitian.dat')
                write(160,*)i,j
                write(160,*)Ham(i,j)
                write(160,*)Ham(j,i)
                write(160,*)"===================="
                write(*,*)"Hamiltonian is not hermitian"
                stop
            end if
        end do
    end do
    close(160)
    return
    end subroutine isHermitian
!================= Hermitain Matrices solve ==============
    subroutine eigsol(input)
    use pub
    integer m
    character*20::str1,str2,str3,str4
    str1 = "eigval"
    str3 = ".dat"
    write(str2,"(I4.4)")input
    str4 = trim(str1)//trim(str2)//trim(str3)
    lwork = -1
    liwork = -1
    lrwork = -1
    call cheevd('V','U',N,Ham,lda,w,work,lwork,rwork,lrwork,iwork,liwork,info)
    lwork = min(2*N+N**2, int( work( 1 ) ) )
    lrwork = min(1+5*N+2*N**2, int( rwork( 1 ) ) )
    liwork = min(3+5*N, iwork( 1 ) )
    call cheevd('V','U',N,Ham,lda,w,work,lwork,rwork,lrwork,iwork,liwork,info)
    if( info .GT. 0 ) then
        open(110,file="mes.dat",status="unknown")
        write(110,*)'The algorithm failed to compute eigenvalues.'
        close(110)
    end if
    return
    end subroutine eigsol
!==========================================================================
    subroutine plot(m3)
    use pub
    character*20::str1,str2,str3,str4,str5,str6
    integer m3
    str1 = "half"
    write(str2,"(I2.2)")m3
    str3 = ".gnu"
    str4 = trim(str1)//trim(str2)//trim(str3)
    open(20,file=str4)
    write(20,*)'set terminal png truecolor enhanced font ",50" size 3000, 1500'
    write(20,*)"set output 'cy"//trim(str2)//".png'"
    write(20,*)"set size 1, 1"
    write(20,*)"set multiplot layout 1, 2"
    write(20,*)"unset key"
    write(20,*)"set ytics 1.5 "
    write(20,*)"set xtics 0.5"
    write(20,*)"set xtics offset 0, 0.0"
    write(20,*)'set xtics format "%4.1f" nomirror out '
    write(20,*)'set ytics format "%4.1f"'
    write(20,*)'set ylabel "E"'
    write(20,*)"set ylabel offset 0.5, 0.0 "
    write(20,*)"#set xlabel offset 0, -1.0 "
    write(20,*)"set xrange [-1:1]"
    write(20,*)"set yrange [-3:3]"
    write(20,*)"set xlabel 'k_y' "
    write(20,*)"plot for [i=2:400] 'ox-sc"//trim(str2)//".dat' u 1:i w l lw 5 lc 'blue'"
    write(20,*)"set xlabel 'k_x' "
    write(20,*)"plot for [i=2:400] 'oy-sc"//trim(str2)//".dat' u 1:i w l lw 5 lc 'blue'"
    write(20,*)"unset multiplot"
    close(20)
    end subroutine plot

这个程序可以产生一系列的绘图文件.gnu**以及绘图数据.dat**,可以通过一个shell脚本来批量执行

#!/bin/sh  
#============ get the file name ===========  
Folder_A=$(pwd) 
for file_a in ${Folder_A}/*.gnu
do 
	gnuplot $file_a  
done

这个脚本可以执行这个当前文件夹下面所有的.gnu文件。

线条权重染色

png

set encoding iso_8859_1
#set terminal  postscript enhanced color
#set output 'c1.eps'
#set terminal  pngcairo truecolor enhanced  font ",60" size 1920, 1680
set terminal  png truecolor enhanced  font ",60" size 1920, 1920
set output 'c1.png'
set palette defined ( 0  "green", 5 "yellow", 10 "red" )
set style data linespoints
unset ztics
unset key
set pointsize 0.8
set border lw 3 
set view 0,0
#set xtics font ",36"
#set ytics font ",36"
#set ylabel font ",36"
set size ratio 1
#set xtics offset 0, -1
set ylabel offset -1, 0 
set xrange [-1:1]
set ylabel "Energy (eV)"
set yrange [-3:3]
rgb(r,g,b) = int(r)*65536 + int(g)*256 + int(b)
plot 'c1.dat' u 1:2:(rgb(255,$3, 80)) w lp lw 2 pt 7  ps 1 lc rgb variable # RGB颜色绘图
# (a) 
# plot the top and bottom surface's weight together
#plot 'c1.dat' u 1:2:($3+$4) w lp lw 2 pt 7  ps 1 lc palette
# (b) 
# plot top and bottom surface's weight with red and blue respectively
set palette defined ( -1  "green",-0.0001 "red" , 0 "blue", 0.00001 "red", 1 "red" )
#plot 'c1.dat' u 1:2:($4-$3) w lp lw 5  lc palette
#plot 'c1.dat' u 1:2 w lp lw 5  lc 'blue'

产生数据的代码如下

!   Author: YuXuanLi
!   Email:yxli406@gmail.com
    module pub
    implicit none
    integer yn,kn,hnn
    parameter(yn = 50,kn = 60,hnn = 2)
    integer,parameter::N = yn*hnn
    real,parameter::pi = 3.1415926535
    complex,parameter::im = (0.,1.0)  
    complex::Ham(N,N) = 0
    complex g1(hnn,hnn),g2(hnn,hnn),g3(hnn,hnn)
    real m0,tx,ty,lamx,lamy
    !--------------------------------------
    integer::lda = N
    integer,parameter::lwmax=2*N+N**2
    real,allocatable::w(:)
    complex,allocatable::work(:)
    real,allocatable::rwork(:)
    integer,allocatable::iwork(:)
    integer lwork   
    integer lrwork    
    integer liwork   
    integer info
    end module pub
!============================================================
    program sol
    use pub
    allocate(w(N))
    allocate(work(lwmax))
    allocate(rwork(1+5*N+2*N**2))
    allocate(iwork(3+5*N))
    !------------------------------------
    m0 = 0.5
    tx = 1.0
    ty = -1.0
    lamx = 1.0
    lamy = 1.0
    ! call main1()
    call main2()
    call plot()
    stop
    end program sol
!============================================================
    subroutine main1()
    use pub
    integer m1
    real k
    open(3,file="openx-m1.dat")
    open(4,file="openy-m1.dat")
    do m1 = -kn,kn
        k = pi*m1/kn
        call openx(k)
        write(3,999)k/pi,(w(i),i = 1,N)
        call openy(k)
        write(4,999)k/pi,(w(i),i = 1,N)
    end do
    close(3)
    close(4)
999 format(201f11.6)
    end subroutine main1
!============================================================
    subroutine main2()
    use pub
    integer m1,m2
    real k
    open(3,file="c1.dat")
    open(4,file="c2.dat")
    ! write(3,*)"kx","E","W1","W2"
    ! write(4,*)"kx","E","W1","W2"
    do m1 = -kn,kn
        k = pi*m1/kn
        call openx(k)
        do m2 = 1,N
            ! write(3,*)k/pi,w(m2),sin(1.0*(N/2-m2)),cos(1.0*m2)
            write(3,*)k/pi,w(m2),N/2-m2,m2
        end do
        write(3,*)" "
        call openy(k)
        do m2 = 1,N
            ! write(4,*)k/pi,w(m2),sin(1.0*(N/2-m2)),cos(1.0*m2)
            write(4,*)k/pi,w(m2),N/2-m2,m2
        end do
        write(4,*)" "
    end do
    close(3)
    close(4)
    end subroutine main2
!============================================================
    subroutine openx(ky)
    use pub
    real ky
    call pauli()
    Ham = 0
    !========== Positive energy ========
    do k = 0,yn-1
        if (k == 0) then ! Only right block in first line
            do m = 1,hnn
                do l = 1,hnn
                    Ham(m,l) = lamy*sin(ky)*g2(m,l) + (m0 + ty*cos(ky))*g3(m,l)

                    Ham(m,l + hnn) = tx/2.0*g3(m,l) + lamx/(2*im)*g1(m,l)
                end do
            end do
        elseif ( k==yn-1 ) then ! Only left block in last line
            do m = 1,hnn
                do l = 1,hnn
                    Ham(k*hnn + m,k*hnn + l) = lamy*sin(ky)*g2(m,l) + (m0 + ty*cos(ky))*g3(m,l)

                    Ham(k*hnn + m,k*hnn + l - hnn) = tx/2.0*g3(m,l) - lamx/(2*im)*g1(m,l)
                end do
            end do
        else
            do m = 1,hnn
                do l = 1,hnn ! k start from 1,matrix block from 2th row
                    Ham(k*hnn + m,k*hnn + l) = lamy*sin(ky)*g2(m,l) + (m0 + ty*cos(ky))*g3(m,l)

                    Ham(k*hnn + m,k*hnn + l + hnn) = tx/2.0*g3(m,l) + lamx/(2*im)*g1(m,l)
                    Ham(k*hnn + m,k*hnn + l - hnn) = tx/2.0*g3(m,l) - lamx/(2*im)*g1(m,l)
                end do
            end do
        end if
    end do
    !------------------------
    call isHermitian()
    call eigsol()
    return
    end subroutine openx
!============================================================
    subroutine openy(kx)
    use pub
    real kx
    call pauli()
    Ham = 0
    !========== Positive energy ========
    do k = 0,yn-1
        if (k == 0) then ! Only right block in first line
            do m = 1,hnn
                do l = 1,hnn
                    Ham(m,l) = lamx*sin(kx)*g1(m,l) + (m0 + tx*cos(kx))*g3(m,l) 

                    Ham(m,l + hnn) = lamy/(2*im)*g2(m,l) + ty/2.0*g3(m,l)
                end do
            end do
        elseif ( k==yn-1 ) then ! Only left block in last line
            do m = 1,hnn
                do l = 1,hnn
                    Ham(k*hnn + m,k*hnn + l) = lamx*sin(kx)*g1(m,l) + (m0 + tx*cos(kx))*g3(m,l)

                    Ham(k*hnn + m,k*hnn + l - hnn) = -lamy/(2*im)*g2(m,l) + ty/2.0*g3(m,l)
                end do
            end do
        else
            do m = 1,hnn
                do l = 1,hnn ! k start from 1,matrix block from 2th row
                    Ham(k*hnn + m,k*hnn + l) = lamx*sin(kx)*g1(m,l) + (m0 + tx*cos(kx))*g3(m,l)

                    Ham(k*hnn + m,k*hnn + l + hnn) = lamy/(2*im)*g2(m,l) + ty/2.0*g3(m,l)
                    Ham(k*hnn + m,k*hnn + l - hnn) = -lamy/(2*im)*g2(m,l) + ty/2.0*g3(m,l)
                end do
            end do
        end if
    end do
    !------------------------
    call isHermitian()
    call eigsol()
    return
    end subroutine openy
!============================================================
    subroutine pauli()
    use pub
    g1(1,hnn) = 1
    g1(2,1) = 1
    !-----------------
    g2(1,hnn) = -im
    g2(2,1) = im
    !---------------
    g3(1,1) = 1
    g3(2,2) = -1
    end subroutine pauli
!============================================================
    subroutine isHermitian()
    use pub
    integer i,j
    do i = 1,N
        do j = 1,N
            if (Ham(i,j) .ne. conjg(Ham(j,i)))then
                open(16,file = 'hermitian.dat')
                write(16,*)i,j
                write(16,*)Ham(i,j)
                write(16,*)Ham(j,i)
                write(16,*)"===================="
                write(*,*)"Ham isn't Hermitian"
                stop
            end if
        end do
    end do
    close(16)
    return
    end subroutine isHermitian
!================= 矩阵本征值求解 ==============
    subroutine eigSol()
    use pub
    integer m
    lwork = -1
    liwork = -1
    lrwork = -1
    call cheevd('V','Upper',N,Ham,lda,w,work,lwork &
        ,rwork,lrwork,iwork,liwork,info)
    lwork = min(2*N+N**2, int( work( 1 ) ) )
    lrwork = min(1+5*N+2*N**2, int( rwork( 1 ) ) )
    liwork = min(3+5*N, iwork( 1 ) )
    call cheevd('V','Upper',N,Ham,lda,w,work,lwork &
        ,rwork,lrwork,iwork,liwork,info)
    if( info .GT. 0 ) then
        open(11,file="mes.dat",status="unknown")
        write(11,*)'The algorithm failed to compute eigenvalues.'
        close(11)
    end if
    return
    end subroutine eigSol
!=====================================================================
    subroutine plot()
    use pub
    open(20,file="plot.gnu")
    write(20,111)"set encoding iso_8859_1"
    write(20,111)"#set terminal  postscript enhanced color"
    write(20,111)"#set output 'c1.eps'"
    write(20,111)'#set terminal  pngcairo truecolor enhanced  font ",60" size 1920, 1680'
    write(20,111)'set terminal  png truecolor enhanced  font ",60" size 1920, 1920'
    write(20,111)"set output 'c1.png'"
    write(20,111)'set palette defined ( 0  "green", 5 "yellow", 10 "red" )'
    write(20,111)"set style data linespoints"
    write(20,111)"unset ztics"
    write(20,111)"unset key"
    write(20,111)"set pointsize 0.8"
    write(20,111)"set border lw 3 "
    write(20,111)"set view 0,0"
    write(20,111)'#set xtics font ",36"'
    write(20,111)'#set ytics font ",36"'
    write(20,111)'#set ylabel font ",36"'
    write(20,111)'set size ratio 1'
    write(20,111)"#set xtics offset 0, -1"
    write(20,111)"set ylabel offset -1, 0 "
    write(20,111)"set xrange [-1:1]"
    write(20,111)'set ylabel "Energy (eV)"'
    write(20,111)"set yrange [-3:3]"
    write(20,111)"rgb(r,g,b) = int(r)*65536 + int(g)*256 + int(b)"
    write(20,111)"plot 'c1.dat' u 1:2:(rgb(255,$3, 3)) w lp lw 2 pt 7  ps 1 lc rgb variable"
    write(20,111)"# (a) "
    write(20,111)"# plot the top and bottom surface's weight together"
    write(20,111)"#plot 'c1.dat' u 1:2:($3+$4) w lp lw 2 pt 7  ps 1 lc palette"
    write(20,111)"# (b) "
    write(20,111)"# plot top and bottom surface's weight with red and blue respectively"
    write(20,111)'set palette defined ( -1  "green",-0.0001 "red" , 0 "blue", 0.00001 "red", 1 "red" )'
    write(20,111)"#plot 'c1.dat' u 1:2:($4-$3) w lp lw 5  lc palette"
    write(20,111)"#plot 'c1.dat' u 1:2 w lp lw 5  lc 'blue'"
    close(20)
111 format(A85)
    return
    end subroutine plot

上面fortran程序可以通过ifort -mkl filename.f90进行编译执行.产生的gnuplot绘图文件也可以通过上一节的绘图脚本来执行.

绘制两条曲线做对比

# 绘制VASP计算能带图与Wannier90拟合能带图
set style data dots
set encoding iso_8859_1
set terminal png truecolor enhanced font ",50" size 1920, 1680
set size 0.9,1
set output 'wannier90_band.png'
#set nokey
set key font "Times,24,Bold"
set key Right at 5,5
set xrange [0: 4.27065]
set yrange [-5 : 5]
#set arrow from  0.84341,  -6.29553 to  0.84341,  14.22923 nohead
#set arrow from  2.46594,  -6.29553 to  2.46594,  14.22923 nohead
#set arrow from  3.42724,  -6.29553 to  3.42724,  14.22923 nohead
#set ytics offset -1,0 font 'Times,Bold'
#set xtics offset 0,-0.1 font 'Times,Bold'
set ytics font 'Times,Bold'
set xtics font 'Times,Bold'
set xtics ("G"  0.00000,"Z"  0.84341,"F"  2.46594,"G"  3.42724,"L"  4.27065)
#plot "wannier90_band.dat" w p  pt 7  ps 1.1 lc 'red',"BAND.dat" w p pt 7 ps 1.1 lc 'blue'
plot "wannier90_band.dat" w l  lw 5.0 lt 7 lc 'red' title "wannier","BAND.dat" w l lw 5.0 lt 7  lc 'blue' title "VASP"

这里需要使用VASP计算得到的能带数据和wannier90得到的能带数据来一起绘制,这么做也是为了比较做wannier的时候,做的到底好不好,通常情况下二者在费米面附近应该是要拟合的非常好才可以认为是wannier化比较成功。

1000000