2018年3月19日 星期一

繪製等位線的方法:Python

繪製等位線的方法:Python
日期:2018/3/18
  感謝坤賢學長介紹了這個網站 https://python-graph-gallery.com/ ,我從網站上找到兩張很符合需求的圖
  1. https://python-graph-gallery.com/371-surface-plot/ 
  2. https://python-graph-gallery.com/371-surface-plot/ 
如何利用 numpy 套件產生各點電位值的寫法主要是參考這篇
最後成功畫出以下兩張圖
用高度及顏色表示電位值的立體圖
用顏色表示電位值的等高線圖

使用版本

Python 3.6.3,但是應該可以用在其它 3.X 版。

方法1:用高度及顏色表示電位值(electric_potential_3D.py


"""
 1.引用函式庫
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from matplotlib.ticker import LinearLocator, FormatStrFormatter
from mpl_toolkits.mplot3d import Axes3D
"""
 2.參數設定
"""
k = 8.988E9
x1, y1, q1 = -0.1, 0, 8E-6
x2, y2, q2 = 0.1, 0, -4E-6
xmin, xmax = -0.2, 0.2
ymin, ymax = -0.2, 0.2
num = 100
dx = (xmax - xmin)/num
dy = (ymax - ymin)/num
# 用 np.arange 製造數列, 用 np.meshgrid 將 x, y 組合成矩陣
x = np.arange(xmin, xmax, dx)
y = np.arange(ymin, ymax, dy)
X,Y = np.meshgrid(x, y)
# 將所有位置的電位預設為0, 設定最大值為 4E6
V = X*0
Vmax = 4E6
"""
 3.設定計算電位的函數, 計算每個位置的電位並存入矩陣
"""
def potential(x, y, q1, x1, y1, q2, x2, y2):
    result = 0
    r1 = np.sqrt((x - x1)**2 + (y - y1)**2)
    r2 = np.sqrt((x - x2)**2 + (y - y2)**2)
    if(r1 != 0 and r2 != 0):
        result = k*q1/r1 + k*q2/r2
    return result
for i in range(len(X[:, 0])):
    for j in range(len(Y[0, :])):
        x = X[i, j]
        y = Y[i, j]
        V[i, j] = potential(x, y, q1, x1, y1, q2, x2, y2)
        if(V[i, j] >= Vmax): V[i, j] = Vmax
        if(V[i, j] <= -Vmax): V[i, j] = -Vmax
"""
 4.設定繪圖選項
"""
# 自訂字體, 可以顯示中文
font = FontProperties(fname = 'C:\Windows\Fonts\simsun.ttc', size = '12')
# 開啟繪圖視窗
fig = plt.figure(figsize = (8, 6), dpi = 100)
# 設定為 3D 繪圖
ax = fig.gca(projection = '3d')
# 設定座標軸標籤
ax.set_xlabel('x(m)', fontproperties = font)
ax.set_ylabel('y(m)', fontproperties = font)
ax.set_zlabel('V(volt)', fontproperties = font)
# 設定z軸範圍
ax.set_zlim(-Vmax, Vmax)
# 將z軸分為10格
ax.zaxis.set_major_locator(LinearLocator(10))
# 設定z軸數值格式, %.e為科學計號, %.02f為顯示到小數點後2位的浮點數
ax.zaxis.set_major_formatter(FormatStrFormatter('%.e'))
# 畫出 3D 曲面, cmap 為數值及色階對應方式, linewidth 為線寬, antiliased = Fasle 可以加快繪圖速度 
surf = ax.plot_surface(X, Y, V, cmap = plt.cm.coolwarm, linewidth = 0.5, antialiased = False)
# 顯示數值及色階對應方式, shrink 設定 colorbar 長度為圖片高度的幾倍, 預設值 1.0, aspect 設定 colorbar 寬、高比, 預設值 20
fig.colorbar(surf, shrink = 0.5, aspect = 5)
# 儲存圖片
plt.savefig('electric_potential_3D_py.svg')
plt.savefig('electric_potential_3D_py.png')
# 顯示圖片
plt.show()

方法2:用顏色表示電位值(electric_potential_contour.py


"""
 1.引用函式庫
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
"""
 2.參數設定
"""
k = 8.988E9
x1, y1, q1 = -0.1, 0, 8E-6
x2, y2, q2 = 0.1, 0, -4E-6
xmin, xmax = -0.2, 0.2
ymin, ymax = -0.2, 0.2
num = 100
dx = (xmax - xmin)/num
dy = (ymax - ymin)/num
# 用 np.arange 製造數列, 用 np.meshgrid 將 x, y 組合成矩陣
x = np.arange(xmin, xmax, dx)
y = np.arange(ymin, ymax, dy)
X,Y = np.meshgrid(x, y)
# 將所有位置的電位預設為0, 設定最大值為 4E6
V = X*0
Vmax = 4E6
"""
 3.設定計算電位的函數, 計算每個位置的電位並存入矩陣
"""
def potential(x, y, q1, x1, y1, q2, x2, y2):
    result = 0
    r1 = np.sqrt((x - x1)**2 + (y - y1)**2)
    r2 = np.sqrt((x - x2)**2 + (y - y2)**2)
    if(r1 != 0 and r2 != 0):
        result = k*q1/r1 + k*q2/r2
    return result
for i in range(len(X[:, 0])):
    for j in range(len(Y[0, :])):
        x = X[i, j]
        y = Y[i, j]
        V[i, j] = potential(x, y, q1, x1, y1, q2, x2, y2)
        if(V[i, j] >= Vmax): V[i, j] = Vmax
        if(V[i, j] <= -Vmax): V[i, j] = -Vmax
"""
 4.設定繪圖選項
"""
# 自訂字體, 可以顯示中文
font = FontProperties(fname = 'C:\Windows\Fonts\simsun.ttc', size = '14')
font_title = FontProperties(fname = 'C:\Windows\Fonts\simsun.ttc', size = '20')
# 開啟繪圖視窗
fig = plt.figure(figsize = (8, 6), dpi = 100)
# 開啟圖片物件
ax = fig.gca()
# 設定圖片標題
ax.set_title('Electric Potential', fontproperties = font_title)
# 設定座標軸標籤
ax.set_xlabel('x(m)', fontproperties = font)
ax.set_ylabel('y(m)', fontproperties = font)
# 用顏色代表每個點的 V 數值,  shadiing 選項為 flat 或 gouraud, 用 flat 每個方塊本身顏色固定, 故用 gouraud
con = ax.pcolormesh(X, Y, V, shading='gouraud', cmap = plt.cm.coolwarm)
# 顯示數值及色階對應方式, shrink 設定 colorbar 長度為圖片高度的幾倍, 預設值 1.0, aspect 設定 colorbar 寬、高比, 預設值 20
fig.colorbar(con, shrink = 0.5, aspect = 5)
# 畫等高線
ax.contour(X, Y, V)
# 儲存圖片, 不要用 svg, 檔案太大
plt.savefig('electric_potential_contour_py.png')
# 顯示圖片
plt.show()

結語

matplotlib 套件的功能實在太強大,可以調整的選項很多,但也有點難上手。不過網站上有這麼多例子可以參考,只要先找到符合需求的圖再參考網站上的程式碼加以修改,應該就能畫出自己想要的圖。

沒有留言:

張貼留言