天天看點

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

最近在寫文章需要繪制一些一維的能量曲線(energy profile)和抽象的二維和三維的網格來表示晶體用來描述自己的算法,于是自己在之前的腳本的基礎上進行了整改寫成了隻提供接口的Python庫,基 本思想就是封裝了matplotlib中相關接口,友善快速搭建和定制自己的能量曲線和網格結構, 代碼托管在GitHub上并上傳至PyPI。對于研究晶體材料的同學如果想通過python來繪制簡單的晶格圖像可以參考一下。

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式
基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

首先還是介紹一下這個程式的用途,目前主要是提供三個主要的子產品來繪制三方面的内容:

catplot提供了豐富的接口用來定制所需要的任何二維網格并進行周期性擴充,如下圖是一個通過當個重複單元擴充出來的抽象(100)晶面的二維網格結構:

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

同理隻不過這次是在三維畫布中進行繪制并進行重複單元的周期性擴充,擴充的效果如下圖:

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式
基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

實作過程基本是通過對matplotlib提供的繪圖元件和接口進一步封裝成可以快速搭建上面三個類型圖像的元件。

energy profile可以了解成在勢能面(Potential Energy Surface)上沿着某個特定的方向(反應坐标方向)上能量的變化,

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

插值方法

為了能将能量最高點沿着橫坐标任意位置移動,我先将頂點的兩邊用二次函數進行插值,擷取兩個不同的二次函數形式,然後根據二次函數的形式在左右兩邊插上5個點,為了能讓分開插值的兩部分看起來連續,在将上面的10個新插的點和之前的3個點進行一次spline插值即可。

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式
基于matplotlib的2D/3D抽象網格和能量曲線繪制程式
基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

晶格中的原子和鍵在catplot中被抽象成圖中的node和edge,這樣我們就可以通過建立圖中的node和edge的方式搭建我們網格的重複單元,之後可以通過重複單元的擴充方法來将其擴充成nxn或者nxnxn的網格。

實作的基本方法就是通過matplotlib提供的Line2D, Arrow和scatter相關的接口來将相應node和edge的資料添加到maptlotlib的二維或者三維畫布中然後進行繪制和顯示。下面給分别給出兩個繪制正交網格的繪制方法:

建立nodes和edges

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

好了,現在我們就建立一個重複單元中的所需的所有元素,可以繪制一下看看效果了

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式
基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

OK, 重複單元已經搭建成功,可以以他為機關進行擴充了, 下面我們将其沿着x和y軸方向各進行5次重複擴充。

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

來看看效果:

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式
基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

是不是很直覺和簡單呢?

繪制三維網格,catplot中我都寫了與二維繪制中相對應的類和接口,這裡就不贅述了,可以參考項目中的examples: https://github.com/PytLab/catplot/tree/master/examples/grid_3d_examples/expand_3d_supercell.ipynb

怎麼可能,雖然所有的坐标都是在分數坐标系中定義的,但是在SuperCell類中我添加了分數坐标到笛卡爾坐标的轉化,進而可以使得catplot繪制任意的網格。來個例子就知道了:

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

來我們看看這時候的重複單元是什麼樣子:

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

然後我們再将其進行一次3x3的擴充看看

基于matplotlib的2D/3D抽象網格和能量曲線繪制程式
基于matplotlib的2D/3D抽象網格和能量曲線繪制程式

是以基本上現在所有類型的晶格都可以通過CatPlot來繪制了。

原文釋出時間為:2017-05-05

本文作者:PytLab