p4vasp分析态密度输出pdos数据后用Python分列

背景


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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值