Day 4. Matplotlib繪圖
最近修的課剛好有需要用到函數的繪圖,就乾脆先把matplotlib搞定了。
這篇又是一篇弄得比想像中還要久的文。 曾經聽說matplotlib的用法和matlab很像,所以可以整理很快。 但我錯了,他們很像,但matplotlib在某些地方實在讓人有點困擾。
P.S. 當然也有可能是因為我堅持不用ipython的關係...(?
如果只是單純的要繪圖,然後加上一些簡單的資訊,可以這麼做:
import numpy as np
import matplotlib.pyplot as plt
# 要繪製的data:
x = np.linspace(0,1,100) # x的值從0到1, 共100個點.
y = np.sin(x**2) # y = sin(x^2)
# 類似matlab的方式,把圖畫出來、添加title, x, y軸資訊
plt.plot(x,y)
plt.title('$ y = \sin(x^2) $') #直接支援LaTeX超棒ㄝㄝ
plt.xlabel('x')
plt.ylabel('y')
plt.grid() #格線這樣畫
plt.show()
畫出來的畫面大致上長這樣:
plt.plot完畢以後圖還不會馬上出現,要執行show以後才會出現。 不過這有兩個問題:
- show完以後,如果在互動介面底下會block住,必須等到圖關閉才能繼續。
- 萬一發現圖畫錯以後,show完以後預設會重新開一個figure handle.
第一個問題代表,如果發現圖畫錯了,不能直接回指令列底下改。 第二個問題代表,關掉視窗後,重新再plot一次後完,show出來會發現剛剛的那些title, label都不見了。因為現在是一個新的figure了,前一個figure的資訊等於不見了。
這兩個問題可以用plt.ion (interactive mode on)一起解決。 在interactive模式下,plot完以後不用show, 圖就會先跑出來了。
如果要更細部的了解,可以分開取得figure、figure上的axes(座標)來了解。
# 一個完全乾淨、空白的figure:
fig = plt.figure()
--
# 增新一個axes(座標軸),以供繪圖和放置資訊:
axs = fig.add_subplot(1,1,1) # 1x1的座標軸
--
# 增新很多個axes,以供繪圖和放置資訊:
fig.delaxes( fig.gca() ) # 順便示範,把剛剛1x1的座標軸刪掉
axs1 = fig.add_subplot(2,2,1)
axs3 = fig.add_subplot(2,2,3)
axs4 = fig.add_subplot(2,2,4)
如圖,從左上到右下,分別是subplot 1, 3, 4:
分別對subplot 1, 4繪製資料,然後axs4.grid()開啟格線:
--
其他更多關於figure和subplot的事情:
fig1 = plt.figure() # 等價於fig1 = plt.figure(1)
fig2 = plt.figure() # 等價於fig2 = plt.figure(2)
# 一般的情況下,axes是"hold on"的, 也就是資料不會被覆蓋掉。
# hold on: 好處是一次要輸出一堆函數,可以把圖疊加上去。
# hold off: 可以更新圖的內容,可是全部的資訊會被洗掉(title, legend等)
# 如果要保留這些資訊,可以單獨抓出圖的內容,直接修改:
x = np.linspace(0,1,100)
y = np.sin(x)
axes = fig2.add_subplot(1,1,1)
axes.set_title('y = sin(x)')
line, = axes.plot(x,y) # 這裡回傳的line就是畫在圖上的資料
# 當發現畫錯想修改,可以對line修改:
line.set_ydata(np.cos(x))
fig2.savefig('./sample.png') #將圖片輸出成檔案.
--
參考資料
- matplotlib官方資料,不免俗一定要附的官方資料。裡面有相當多的範例。
- matplotlib入門(日),目前看到解釋比較詳盡又不會太囉唆的教學,不過是日文w
- Plotting in a non-blocking way with Matplotlib
- python数字图像处理(5):图像的绘制
第四篇主要在講本篇沒有提到的plt.imshow, 不過看到裡頭的用法我才真正搞清楚subplot。裡頭也解釋了一些參數的用途,可以看看。
備註
雖然講完繪圖了,不過matlab很常用取得好幾張frame, 連續播放輸出成gif或是影片檔,但這裡沒有介紹到。
明天沒意外的話應該會把它補充完, 順便用之前寫的,一支計算常微分方程的matlab程式來做demo. 也就是終於會講到數值計算的內容。
P.S, 老實我也不是說特別想提科學計算。 一開始會說可能會從科學計算開始提,只是因為比較熟而已w。 畢竟不是所有人都會用到,應該會覺得比較無聊吧(?