背景
在分析态密度(DOS)時,常常用p4vasp這個軟體來讀取vasprun.xml,進而獲得需要的各元素或軌道對應的圖形。然後,利用p4vasp的export功能将資料輸出畫圖。具體操作參見
https://www.bigbrosci.com/2018/02/08/ex39/
注:本例中的資料來源也是該博文,感謝原作者的分享
然而,在将資料輸出為dat格式後,發現一個問題,即:p4vasp把所有的資料都由上到下排在兩列中,畫圖時面臨着隻有一個x, 一個y的情況,畫出來的圖如下:

而軟體中的樣子(我們想畫成的樣子)起碼有顔色差別:
觀察了資料後發現,每組資料是301行,之後有一個空行,然後再接301行,如此反複。當然資料量少可以手動剪切粘貼,但是資料很多的時候就會很繁瑣。是以,想着利用python中的pandas功能來将這些資料每302行(含最後一個空行)為一組,取出,放在新的兩列,然後再進行畫圖。 整理好思路,我們先把dat檔案放到excel轉為csv格式(記得分列),然後運作Python程式(py檔案和csv在一個檔案夾即可)
代碼如下:
# -*- coding: utf-8 -*-
"""
Created on Sat Dec 12 20:15:08 2020
@author: fya
"""
#觀察資料,301行後有一個空行。
import pandas as pd
df0=pd.read_csv('testRu.csv',header=None) #記得更改為自己的csv檔案名
l=len(df0) #擷取長度
l=l+1 #把最後一行空行也算上,要不然後面除以302會有錯誤
print(l)
print(df0.head())
df=df0.iloc[0:301,:].reset_index(drop=True) #前301行資料為第一組,0:301是取從第0行到第300行,第301不取。reset_index(drop=True) 是為了去除原有的index,重新從0生成index
print(df.tail())
df_values=locals()
l=int(l/302) #用除法後要變為int,不然預設float,到後面range部分會出錯
print(l)
for i in range(2,l+1): #range括号左含右不含
l1=302*i-302
l2=302*i-1
df_values['df'+str(i)]=df0.iloc[l1:l2,:].reset_index(drop=True) #随着i的不同,每301行都取出,index不受原始資料影響,都是從0開始
df=pd.concat([df,df_values['df'+str(i)]],axis=1,join='outer') #将取出的資料橫着排列,axis=1,形成新的df,然後與下一個i産生的新的列繼續合并直到結束
print(df)
df.to_csv('dos.csv',header=None,index=None) #不要column和index,以免畫圖時出錯
print('Done!')
用Python分好組是如下圖這樣的:
放入origin,設定對應的x,y,畫圖如下:
方法2
此方法無需再轉存為csv檔案,可以直接用dat檔案,需要注意讀入資料後沒有空行
# -*- coding: utf-8 -*-
"""
Created on Sat Dec 12 20:15:08 2020
@author: fya
"""
import pandas as pd
df0=pd.read_table('testRu.dat',sep='\s+',header=None,engine='python') #直接讀取dat檔案,讀取後無空行
l=len(df0) #擷取長度
#l=l+1 #把最後一行空行也算上
print(l) # 得到值:903
print(df0.head())
df=df0.iloc[0:301,:].reset_index(drop=True) #前301行資料為第一組(0-300行,第301不取),reset_index(drop=True) 是為了去除原有的index,重新從0生成index
print(df.tail())
df_values=locals()
l=int(l/301) #用除法後要變為int,不然預設float,到後面range部分會出錯
print(l)
for i in range(2,l+1): #range括号左含右不含
l1=301*(i-1)
l2=301*i
df_values['df'+str(i)]=df0.iloc[l1:l2,:].reset_index(drop=True) #随着i的不同,每301行都取出,index不受原始資料影響,都是從0開始
df=pd.concat([df,df_values['df'+str(i)]],axis=1,join='outer') #将取出的資料橫着排列,axis=1,形成新的df,然後與下一個i産生的新的列繼續合并直到結束
print(df)
df.to_csv('dos.dat',header=None,index=None)
print('Done!')
此法輸出dat檔案,拖到origin直接畫圖,得到和方法一同樣的結果