1. 程式人生 > >基於 matplotlib 的 2D/3D 抽象網格和能量曲線繪製程式

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

前言

最近在寫文章需要繪製一些一維的能量曲線(energy profile)和抽象的二維和三維的網格來表示晶體用來描述自己的演算法,於是自己在之前的指令碼的基礎上進行了整改寫成了只提供介面的Python庫,基本思想就是封裝了matplotlib中相關介面,方便快速搭建和定製自己的能量曲線和網格結構, 程式碼託管在GitHub上並上傳至PyPI。對於研究晶體材料的同學如果想通過python來繪製簡單的晶格影象可以參考一下。

正文

首先還是介紹一下這個程式的用途,目前主要是提供三個主要的模組來繪製三方面的內容:

1. 繪製抽象的二維網格結構

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

2. 繪製抽象的三維網格結構

同理只不過這次是在三維畫布中進行繪製並進行重複單元的週期性擴充套件,擴充套件的效果如下圖:

3. 通過插值演算法實現繪製”順滑”的energy profile

實現過程基本是通過對matplotlib提供的繪圖元件和介面進一步封裝成可以快速搭建上面三個型別影象的元件。

採用二次插值結合樣條插值方法繪製 energy profile

energy profile可以理解成在勢能面(Potential Energy Surface)上沿著某個特定的方向(反應座標方向)上能量的變化,

Python
12345678910111213141516 # 從catplot中匯入繪製所需的元件: 畫布 和 線fromcatplot.ep_components.ep_canvas importEPCanvasfromcatplot.ep_components.ep_lines importElementaryLine# 建立一個用於繪製energy profile的畫布canvas=EPCanvas()# 建立一條能量曲線,提供的三個值分別是三個狀態下的能量數值line=ElementaryLine([0.0,1.2
,0.8])# 將這條線新增到畫布中canvas.add_line(line)# 繪製canvas.draw()canvas.figure.show()

插值方法

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

Python
1234567891011121314 # 頂點兩側進行二次插值的演算法defquadratic_connect_interp(x1,y1,x2,y2):A=np.matrix([[x1**2,x1,1],[x2**2,x2,1],[2*x2,1,0]])b=np.matrix([[y1],[y2],[0]])x=A.I*bx.shape=(1,-1)a,b,c=x.tolist()[0]poly_func=lambdax:a*x**2+b*x+creturnpoly_func

豐富的介面

除了上面最簡單的例子,catplot還提供了豐富的介面來定製和操作energy profile,比如拼接,合併,平移,新增陰影、改變顏色, 輔助線, 修改畫布大小,匯出插值資料等等。具體的例子參考: https://github.com/PytLab/catplot/tree/master/examples

繪製二維和三維抽象網格

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

實現的基本方法就是通過matplotlib提供的Line2D, Arrow和scatter相關的介面來將相應node和edge的資料新增到maptlotlib的二維或者三維畫布中然後進行繪製和顯示。下面給分別給出兩個繪製正交網格的繪製方法:

繪製5×5的二維網格

建立nodes和edges

Python
123456789101112131415161718192021222324252627282930313233 fromcatplot.grid_components.nodes importNode2Dfromcatplot.grid_components.edges importEdge2Dnodes,edges=[],[]# 建立重複單元中的nodes和edgetop=Node2D([0.0,0.0],size=800,color="#2A6A9C")t1=Node2D([0.0,1.0])t2=Node2D([1.0,0.0])nodes.append(top)# 連結這三個node的edgese1=Edge2D(top,t1,width=4)e2=Edge2D(top,t2,width=4)edges.extend([e1,e2])# 中間的nodesbridge1=Node2D([0.0,0.5],style="s",size=600,color="#5A5A5A",alpha=0.6)bridge2=Node2D([0.5,0.0],style="s",size=600,color="#5A5A5A",alpha=0.6)b1=bridge1.clone([0.5,0.5])b2=bridge2.clone([0.5,0.5])nodes.extend([bridge1,bridge2])# 連線他們的edgese1=Edge2D(bridge1,b1)e2=Edge2D(bridge1,bridge2)e3=Edge2D(bridge2,b2)e4=Edge2D(b1,b2)edges.extend([e1,e2,e3,e4])# 正中間的nodeh=Node2D([0.5,0.5],style="h",size=700,color="#5A5A5A",alpha=0.3)nodes.append(h)

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

Python
1234567891011 fromcatplot.grid_components.grid_canvas importGrid2DCanvasfromcatplot.grid_components.supercell importSuperCell2Dcanvas=Grid2DCanvas()# 將上面的元素放到supercell中,後面我們將一supercell為單位進行展開supercell=SuperCell2D(nodes,edges)# 繪製效果canvas.add_supercell(supercell)canvas.draw()canvas.figure

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

Python
12 # 很簡單,就一行程式碼expanded_supercell=supercell.expand(5,5)

來看看效果:

Python
1234 canvas_big=Grid2DCanvas(figsize=(30,20),dpi=60)# 定製畫布大小canvas_big.add_supercell(expanded_supercell)canvas_big.draw()canvas_big.figure

是不是很直觀和簡單呢?

繪製三維網格

是不是隻能畫正交的網格?

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

Python
123456789 # 建立nodes和edges的程式碼與上面的部分完全相同...# 但是我們在定義supercell的時候可以修改cell_vectors引數來是重複單元發生形變supercell=SuperCell2D(nodes,edges,cell_vectors=[[1.0,0.0],[0.5,1.0]])canvas.add_supercell(supercell)canvas.draw()canvas.figure.show()

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

然後我們再將其進行一次3×3的擴充套件看看

Python
12345 expanded_supercell=supercell.expand(3,3)canvas_big=Grid2DCanvas(figsize=(30,20),dpi=60)canvas_big.add_supercell(expanded_supercell)canvas_big.draw()canvas_big.figure.show()

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

總結

本來catplot這個庫最初是自己用matplotlib來繪圖的小指令碼,由於現在寫論文的情況下需要靈活的繪製網格圖,所以進行了重寫,現在寫成了一個封裝了matplotlib的python庫方便使用者可以快速搭建自己想要的網格圖和繪製漂亮的energy profile。程式碼和具體使用的notebook格式的例子均開源並放到了github上 (https://github.com/PytLab/catplot ),歡迎有需要的童鞋參考和使用。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

相關推薦

基於 matplotlib2D/3D 抽象網格能量曲線繪製程式

前言 最近在寫文章需要繪製一些一維的能量曲線(energy profile)和抽象的二維和三維的網格來表示晶體用來描述自己的演算法,於是自己在之前的指令碼的基礎上進行了整改寫成了只提供介面的Python庫,基本思想就是封裝了matplotlib中相關介面,方便快速搭建和定製自己

基於 Python 的自動文字提取:抽象生成法的比較

我們將現有的 提取方法(Extractive)(如LexRank,LSA,Luhn和Gensim現有的TextRank摘要模組)與含有51個文章摘要對的Opinosis資料集進行比較。我們還嘗試使用Tensorflow的文字摘要演算法進行抽象技術(Abstractive),但由於其極高的硬體需求(7000 G

Windons10 python3.6 機器學習線性迴歸 matplotlib出現影象中文亂碼使用sk_learn輸出ValueError: Expected 2D array, got 1D

Windons10 python3.6 機器學習線性迴歸 matplotlib出現影象中文亂碼和使用sk_learn輸出ValueError: Expected 2D array, got 1D array instead:問題解決 話不多說,大家來就是解決問題的,本人也是遇到問題才四處搜尋

2D 3D轉化動畫

day 9.10   2D、3D轉化和動畫   一、2D轉化 屬性:transform:translate()/scale()/rotate()/skew()/ 1)取值:translate(x水平方向,y垂直方向)平移  將元素按指定的方向平移移動,相當於定位中的rela

基於 HTML5 Canvas 的簡易 2D 3D 編輯器

不管在任何領域,只要能讓非程式設計師能通過拖拽來實現 2D 和 3D 的設計圖就是很牛的,今天我們不需要 3dMaxs 等設計軟體,直接用 HT 就能自己寫出一個 2D 3D 編輯器,實現這個功能我覺得成就感還是爆棚的,哈哈!只要你會想,能做,就能根據這個編輯器

單影象三維重建、2D3D風格遷移3D DeepDream

作者:Longway Date:2020-04-25 來源:單影象三維重建、2D到3D風格遷移和3D DeepDream 專案網址:http://hiroharu-kato.com/projects_en/neural_renderer.html 程式碼網址:https://github.com/h

Java抽象接口

總結 println 權限 區別 變量 實例 nds 集合 出現 抽象類   在面向對象的領域一切都是對象,同時所有的對象都是通過類來描述的,但是並不是所有的類都是來描述對象的。 如果一個類沒有足夠的信息來描述一個具體的對象,而需要其他具體的類來支撐它,那麽這樣的類我們稱它

C#.NET裏面抽象接口有什麽區別

end 吃飯 動物 虛方法 根據 自定義 private this sse 1.面向接口編程和面向對象編程是什麽關系 首先,面向接口編程和面向對象編程並不是平級的,它並不是比面向對象編程更先進的一種獨立的編程思想,而是附屬於面向對象思想體系,屬於其一部分。或者說,

java 抽象接口的差別

rac static start 靜態方法 ane 沒有 類型 text 子類 ?? 語法層面上: 1)抽象類能夠提供成員方法的實現細節。而接口中僅僅能存在public abstract 方法。   2)抽象類中的成員變量能夠是各種類型的。而接口中的成員

抽象接口

表示 ons 紅色 存在 但是 iter oid spa iterator 抽象類的格式,abstract void fun(); 在類之中,只要存在抽象方法,就要在class前面加上abstract 表示這是個抽象類, 抽象類可以沒有方法體。 接口 六個接口 Conl

抽象接口的聯系與區別

語法 .html 註意 角度 sed 軟件 方法 基本 類結構 抽象類和接口聯系與區別 關鍵字: 抽象類與接口的區別 abstract class和interface是Java語言中對於抽象類定義進行支持的兩種機制,正是由於這兩種機制的存在,才賦予了Java強大的面向對象能

抽象接口的一點認識

數據共享 父類 標識 常量 詳細 class 抽象層 span 必須 假設一個非抽象子類繼承一個抽象父類,它必須實現父類中的抽象方法,假設子類也是抽象類,那麽則不必實現父類中的抽象方法。 假設一個類實現了一個接口。那麽必須實現接口中的全部方法。可是子類是抽象類則不用。

抽象普通類的區別

prot trac 不能 cte 區別 pri pro 包含 方法 包含抽象方法的類稱為抽象類,但並不意味著抽象類中只能有抽象方法,它和普通類一樣,同樣可以擁有成員變量和普通的成員方法。註意,抽象類和普通類的主要有三點區別: 1)抽象方法必須為public或者protect

5.4-全棧Java筆記:面向對象進階之對象的轉型 | FINAL關鍵字 |抽象方法抽象

java對象的轉型(casting)引用變量只能調用它編譯類型的方法,不能調用它運行類型的方法。這時,我們就需要進行類型的強制轉換!【示例1】對象的轉型public class TestCasting { public static void main(String[] args) {

Java面向對象—抽象接口

main 連接數 其他 先來 聲明 print 一句話 戰鬥 like 本文引用海子的一篇文章:http://www.cnblogs.com/dolphin0520/p/3811437.html 一.抽象類   在了解抽象類之前,先來了解一下抽象方法。抽象方法是一種特殊的方

php 抽象接口的區別

function 實現 fun 容易 php pri 區別 函數 高效 在學習PHP面向對象時,都會在抽象類與接口上迷惑,作用差不多為什麽還那麽容易混淆,何不留一去一? 但是事實上兩者的區別還是很大的,如果能夠很好地運用PHP的兩個方法,面向對象的程序設計將會更加合理、清晰

面向對象 (三)抽象接口

trac bstr 報錯 clas abstract nbsp 繼承 默認 定義 一、抽象類 抽象類相當於一個提綱,用於表明對問題領域進行分析、設計中得出的抽象概念,是對一系列看上去不同,但是本質上相同的具體概念的抽象,然後對繼承抽象類的子類做出限制。 抽象類用關鍵詞 ab

Java學習筆記—抽象接口

compute nal java語言 通過 多個 靜態代碼塊 容易 如果 span 1.抽象類 在Java語言中使用abstrac關鍵字來定義抽象類和抽象方法,抽象方法沒有定義,方法名後面直接跟一個分號,而不是花括號。 public abstract class Empl

Java中抽象接口的區別

pre data 區分 信息 展示 關於 面向 得出 lose 在Java語言中, abstract class 和interface 是支持抽象類定義的兩種機制。正是由於這兩種機制的存在,才賦予了Java強大的 面向對象能力。abstract class和interfac

抽象抽象方法

bst 內容 func 聲明 function 必須 abstract 實例 學習 今天的學習內容:   抽象類和抽象方法     abstract class className{}     abstract public function funName():約束子類必