如何用python繪製溫度分布圖(matplotlib繪圖)
一.前言
以前在研究所,在處理一個2D空間的溫度分布情形時,我總是會用Origin來做溫度分布圖,我找了Origin官網的文章來說明

(參考網站: Origin官網的文章 )
附圖是該網站的範例圖面,可以很清楚看到,整個北美洲的溫度分布情形。
再由溫度的Scale Bar來判讀,大概靠近底部的地方,溫度會是在60度左右,靠近北方則是10~20度之間。
這很清楚的表達該區域的溫度分布。
近期我在工作上碰到一個問題,我有一個X-Y位置及其對應的溫度值的資料,當時我在excel找了老半天,都無法像Origin那樣做出一個2D平面的溫度分布圖。
接著我就想,除了Origin之外,能否也可以用Python來繪製溫度分布圖呢?
二.簡單的繪製分布圖
首先,這種”分布圖”,在Origin叫做”contour”,剛好Python裡的matplotlib也有contour的指令,起初在網路上找關於此類文章,例如:
1.怎么用Python画这种温度分布图
2.Python Matplotlib Tips
3.绘制轴线或Matplotlib轮廓图的原点
4.matplotlib.pyplot contourf()函式的使用
很可惜的是,他們的該點資料都是X和Y的函數,ex: Z= X+Y*2 這個意思。
這樣子根本無法達到我的”輸入某個位置的資料”的概念,因為該點的溫度值不可能可以構成X和Y的函數麻。
上述這幾個網站的方法是這樣子的,將X和Y個切成很細的位子點,接著將Z令成X和Y的函數,這樣子就有超多的位子點資料。然後將它plot出來。
我的應用則可能只知道某9個點的溫度值而已,要怎麼把9個點溫度值給切碎分給X和Y呢?
後來真的是我想太多了,如果點資料不夠多,那就不要把X和Y切細阿。廢話不多說,馬上看我寫的程式碼。
#舉例 僅有3*3的位置點資料
import matplotlib.pyplot as plt
x = [0,2,3] #X位置
y = [0,3,6] #Y位置
temp = [[5,15,30],[10,20,50],[20,30,40]] #該點資料
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1) #生成Scale bar
c = ax.contourf(x, y, temp,cmap='Spectral_r')
cb = fig.colorbar(c)
cb.set_label('Temperature')
plt.xlabel('position(mm)')
plt.ylabel('position(mm)')
plt.show()
輸出結果:

看看是不是非常簡單,短短的程式碼就可以畫出輪廓圖囉。
三.讀取CSV檔案繪製溫度分布圖
假設我有一個CSV檔案,數據資料如下
0 0 10
0 3 20
0 6 40
2 0 15
2 3 20
2 6 55
3 0 20
3 3 30
3 6 45
第一行表示X位置、第二行是Y位置、第三行則是溫度
那我如何從這CSV讀取資料然後繪製溫度分布圖呢?程式碼如下:
#讀取CSV繪製溫度分布圖
#注意!必須是個X*Y的矩陣資料才可以
import matplotlib.pyplot as plt
import csv
with open('data.csv',encoding="utf-8-sig") as csvFile: #CSV讀取
csvReader = csv.reader(csvFile)
x,y,z,a,b,c=[],[],[],[],[],[]
for row in csvReader:
if not a is row[0]:
x.append(row[0])
c.append(z)
z=[]
if not row[1] in y:
y.append(row[1])
z.append(row[2])
a=row[0]
b=row[1]
del c[0]
c.append(z)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1) #生成Scale bar
c = ax.contourf(x, y, c,cmap='Spectral_r')
cb = fig.colorbar(c)
cb.set_label('Temperature')
plt.xlabel('position(mm)')
plt.ylabel('position(mm)')
plt.show()
輸出結果:

是不是很簡單呢!不過這裡有些限制,點資料必須是個X*Y的矩陣。
您好,我使用”三.讀取CSV檔案繪製溫度分布圖”裡面的語法但輸入我自己較多行(3*43萬)的數據但失敗了,為什麼呢?
我也沒有看懂您打開CSV後的內容,可以為我解釋一下嗎?謝謝.
李 您好:
抱歉這麼久才回覆,其實我自己有一段時間沒碰程式了,又再花一點時間重溫一下。
針對你的問題,我自己測試更多筆數據時,發現此程式碼有些限制:
1.數據必須要是方陣矩陣
意思是x=[0,2,3] y=[0,3,6] 時可以
但是x=[0,2,3] y=[0,3,6,8] 會plot失敗,原因為matplotlib.pyplot的限制。
可解決的辦法是將x和y兩個數值的數量要相同,但有可能情況是,假設x=10時,剛好y=10沒有數據,這時看看是否用內插法,把(10,10)時Z值給求出來。
2. 第一列x要依照數字大小排列
因為程式碼的
"if not a is row[0]:
x.append(row[0])
c.append(z)
z=[] ”
是將z值丟到c這個集合裡,並將z=[]
所以假設您的data長這樣時:
0 0 10
2 0 20
3 0 30
0 1 40
2 1 50
3 1 60
會發生錯誤,應要排列成:
0 0 10
0 1 40
2 0 20
2 1 50
3 0 30
3 1 60
第二個問題是
with open(‘data.csv’,encoding=”utf-8-sig”) as csvFile: #CSV讀取
csvReader = csv.reader(csvFile)
x,y,z,a,b,c=[],[],[],[],[],[]
for row in csvReader:
if not a is row[0]: #當a值不等於當前第一列的值時
x.append(row[0]) #x集合加入第一列的值
c.append(z) #將z集合丟到c集合裡 (c會是是個充滿集合的集合)
z=[] #z=[],重置
if not row[1] in y: #當第二列數值沒有在y集合裡時
y.append(row[1]) #y集合加入第二列的值
z.append(row[2]) #z集合新增第三列的值
a=row[0] #將a=第一列的值
b=row[1] #將b=第二列的值
del c[0] #將c[0]時空集合給刪掉
c.append(z) #將最後一個z集合給c集合
這樣有了解嗎?
謝謝!