背景
在分析态密度(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直接画图,得到和方法一同样的结果