2020年4月30日 星期四

momo 會員日買書三本

今天 momo 會員日最後一天, 部分書打 69 折, 買了如下三本 :

# 演算法:最強彩色圖鑑 + Python程式實作-王者歸來(全彩印刷) $680 => $474
不會C也是資安高手:用Python和駭客大戰三百回合 $680 => $474
強化學習(RL):使用PyTorch徹底精通 $780 => $546

原價 2140 優惠後 1494 元, 相當於打 69 折.




這次用剛開卡的 momo 卡付錢, 有首刷禮 :

https://www.momoshop.com.tw/edm/cmmedm.jsp?lpn=O4DhcJcCleD&n=1




書越買越多, 要努力來消化才行.

你以為我很喜歡當恐龍嗎

今天同事們在辦公室你一言我一語評論剛出爐的殺警案判決, 照這些人以前的慣性, 我用屁股去想都知道他們要說甚麼 :
  1. 又是恐龍法官
  2. 把這些壞蛋通通槍斃
我很不喜歡在辦公室談政治 (你有沒有想過不同立場的人的感受) 或喇滴賽 (公司花錢請你幹嘛), 但聽到恐龍法官一詞實在忍不住簡單回嘴 : 法官是依據專業鑑定報告與刑法法條來判決, 如果法官不採信委託的鑑定結果而是依民意風向判決, 那就是枉法裁判, 是會被監察院彈劾的.

呂秋遠的臉書說得很清楚 :

殺警案兇嫌獲判無罪!呂秋遠揭「癥結點」:不該只罵法官

我國刑法第 19 條 :

"行為時因精神障礙或其他心智缺陷,致不能辨識其行為違法或欠缺依其辨
識而行為之能力者,不罰
行為時因前項之原因,致其辨識行為違法或依其辨識而行為之能力,顯著
減低者,得減輕其刑
前二項規定,於因故意或過失自行招致者,不適用之。"

法律就這樣規定, 你還罵法官是恐龍? 有人說裝瘋賣傻就能躲死, 但精神狀態鑑定是非常專業的東西, 法官不懂, 外送小弟不懂, 我這工程師也不懂, 你懂個屁啊罵法官是恐龍? 問題在於這社會到底怎麼看瘋子? 沒瘋的你知道發瘋是怎麼一回事嗎? 瘋子在這世上沒有存在價值要全部抓去槍斃? 如果你弟你媽是瘋子這樣也沒關係嗎? 甚麼都抓去槍斃, 可憐哪.

被殺的警察很可憐,  但俗語說 "強驚勇, 勇驚雄, 雄驚無天良, 無天良上驚神經無正常", 遇到精神病除了無奈還是無奈, 除非我們逆歷史潮流回到漢朝劉邦時代約法三章的殺人者死, 管你是不是精神病, 反正殺人就要償命, 那就麻煩你去請願, 叫立法委員修法拿掉刑法 19 條, 要不然別再沒根據就隨便罵法官是恐龍了.

刑法 19 的立法宗旨在於刑罰的基本原理是要人為自己犯的錯負責任, 精神錯亂的人腦子有問題, 連家人都可能遇害這是要怎樣來負責 (也是槍斃? 可憐哪). 但我覺得五年的矯正治療是不是太短了? 五年後要怎麼處理? 精神鑑定是委託多家機構進行嗎? 更大層面來看, 要如何讓精神病人獲得妥善追蹤治療, 避免發生悲劇危害社會安全, 這才是正事吧!

買 iPhone SE 256GB

前天晚上在看電視時, 水某發現她的 ASUS 手機背蓋居然翹起來, 露出裡面的鋰聚合物電池包, 我拿過來檢查發現鋰電池外皮膨起, 應該是劣化產生氣體, 把背蓋都撐起來, 看來該換手機了, 前陣子新聞說蘋果出新手機 iPhone SE, 價格約 15000 左右, 所以昨晚就去自由路的中華電信看手機, 展示櫃有 iPhone SE, iPhone 11/Pro/Max 四款, 最後敲定買 iPhone SE, 最主要是有 Home 鍵, 且價格親民, 128GB 的搭 699 方案 11000 元, 256GB 的則是 15000, 想說 iPhone 不能外插卡, 那就買 256GB 的, 但只能先付 2000 元訂金, 大概要五月中才會到貨. 

iPhone SE 與 11 的 CPU 都是 A13 仿生晶片, 螢幕都是視網膜 IPS (但 11 是 liquid), 主要差別在鏡頭與電池, SE 為 1200 萬畫素單鏡頭, 而 11 則是 1200 萬畫素廣角與超廣角 (有夜拍與慢動作); SE 的前鏡頭是 700 萬畫素, 11 則是 1200 萬畫素. 電池部分 SE 電池為 iPhone 8 的 1800 mAh; 而 11 則是 3000 mAh, 所以續航力來說 11 較優, 參考 :

iPhone SE vs. iPhone 11 comparison: Which Apple phone to buy in 2020

去年底水某生日前就在嚷嚷要換手機, 但想到 iPhone 動輒 2 萬多就熄火了. 這次衝著 SE 的親民價格終於能下手了.

2020年4月29日 星期三

AWSome day 2020 上課

下午 1300 參加 AWS 線上課程, 大部分上回上認證課程已學過, 當作是複習, 不過機器學習部分則未曾上過, 所以就特別認真聽, 例如 Poly 就讓我印象深刻. 與認證課程不同的是, 今天講師有帶實作, 雖然時間太短只做簡單示範, 但教學效果不錯, 我都給五顆星非常滿意.

AWS 有 Line 群組, 在手機點下列網址加入即可 :

https://lin.ee/35x9NaR

或者掃 QR 碼 :





好療癒的土撥鼠吃播

今天在 Youtube 上看到這個土撥鼠吃東西的影片, 錄影者在家門口安裝了攝影機, 擺上水果, 根莖類蔬菜, 堅果等, 土撥鼠就會前來進食, 看牠們吃得那麼起勁真的好療癒啊!

https://www.youtube.com/watch?v=TrZLUelGsoc




土撥鼠是松鼠科囓齒目旱獺屬的草食動物, 此頻道擁有近五萬名訂閱者, 都是土撥鼠免費演出的 "吃播", 頻道主有做一個簡介 :

https://www.youtube.com/watch?v=061wPy9MGok




全部影片列表如下 :

https://www.youtube.com/user/jeffpermar

能吃就是福, 我吃吃吃 .... 真是太可愛了!

2020年4月27日 星期一

好書 : Python For Linguists

今天在劍橋大學網站看到一本專為語言學家編寫的 Python 書籍 :

Python for Linguists




作者是亞利桑那州立大學語言學教授 Michael Hammond, 乃句法類型學 (syntactic typology) 與計算語言學專家. 觀此書目錄, 大部分是在介紹一般的 Python Basics, 但範例多以語言學為主, 比較突出的是有專章介紹正規表示法與文本處理, NLTK 則列在附錄, 雖然沒有很驚豔, 但卻是極少以 Python 為名的語言學書籍.

2020年4月26日 星期日

2020 年第 17 周記事

不知不覺今年已過了 17 周, 來到四月底了, 氣候漸漸炎熱, 本周我已開始穿短袖了. 希望氣溫升高也能加速讓疫情消失, 今天又迎來零確診, 期待下周都能保持這樣的好消息.

今天在全聯看到金黃色的南瓜, 雖然不大顆, 但黃澄澄的外皮非常漂亮, 中國進口一顆要 62 元, 我為了取得種子就買一顆 (也不知道會不會發芽), 看看味道有何不同 :





這三周來追的韓劇 "天氣好的話我會去找你" 本周完結篇, 沈明如把過去誤踩油門撞死對姐姐家暴的姊夫這件事寫成了小說, 穆海媛在看過手稿知道真相後無法面對阿姨, 便向恩燮告別回到首爾, 因為原先過完冬天再回去的時間也到了, 恩燮知道後將書店暫停營業幾天, 又跑回山上的房子去獨處 ... 但明明思念對方, 但兩個人卻都沒有打電話, 人就很奇怪哩, 都在期待對方主動. 回到首爾的海媛去應徵了幾個音樂教室, 似乎都沒有機會, 最後還是回到惠泉來, 後續作者就不用交代了 ... 我覺得這部濃厚文藝氣息的戲前面與中間都很不錯, 結尾反而平淡了些, 讓我有 "蛤? 結束了嗎?" 之感, 不過恩燮將繡字圍巾拿給媽媽那段讓人眼眶濕潤的說 ....

本周我都在專心學習 Matplotlib, 一邊測試一邊將結果寫成筆記, 希望下周可以全部完成, 然後就可以調轉方向, 順勢解決 Numpy 與 Pandas, 這樣資料科學的工具就算完備了, 可以向 Scikit-learn 進軍了, 總之, 今年必須把機器學習擺平才行, 估計明年會再繼續忙 AWS, 趁這空檔趕快把馬步都蹲好吧, 不斷學習才不會老 (心態).

2020年4月25日 星期六

市圖還書 3 本 (大氣中醫, 紫微斗數主星篇)

今天下午接到圖書館通知, 下面三本書已逾期 100 多天未還, 我想怎麼可能, 我每周都上圖書館還書, 也沒收到逾期 email, 一定是搞錯了! 經過核對資料發現原來是去年底借書證驗證時, 館員說可以用身分證借書, 我說我以前都不知道, 就幫我用身分證借了這 3 本書, 但我卻忘了這件事, 而 email 可能沒登錄, 也不會收到逾期通知, 借太多書所以也沒發現原來這三本已很久沒還, 趕緊找出來拿去還唄 !
  1. 大氣中醫 : 內氣流轉, 諸疾自平!
  2. 大漲的訊號 :全球最大主權基金經理人的股票K線獨門獲利密技
  3. 紫微斗數 : 主星篇 / 筆記本.
借書被催還真是沒面子啊!

網紅酒鬼小莉的農村生活

昨晚無意中在 Youtube 看到網紅酒鬼小莉的農村生活視頻, 從釀桃花醉, 葡萄酒到煮排骨滷棒菜等等, 把平淡的鄉居生活弄得多采多姿, 成為擁有超過' 34 萬訂閱追蹤粉絲的 Youtuber :

农村姑娘用1500斤桃子,自酿桃花醉,有想喝的吗?




本名許莉霞的小莉家鄉在浙江紹興的山村裡, 大學畢業後曾在外資公司工作, 但結婚生了兩個小孩後決定舉家回鄉定居務農, 看到網路自媒體興盛, 便將自家釀酒等農務過程拍成影片變身為 Youtuber, 吸引許多粉絲下單採購自釀酒等農產品, 參考:

对话酒鬼小莉:有215万人看她酿桃花醉,1万人买她小店的桂花酒

透過網路自媒體行銷農產品非常熱門, 但像小莉這樣內容豐富的卻不多, 所以我也訂閱小莉的頻道, 追蹤她的農村生活動態 (我也是假日農夫啊). 像小莉這樣既能照顧家庭又能在鄉村拓展事業支撐家庭經濟的生活模式真是不錯. 看她將孩子的生活也融入影片中, 感到非常親切, 因為近 20 年前小狐狸們在鄉下也是過著這種農村生活, 炕土窯, 撿紅豆, 撿毛豆, 採草莓 ... 真令人懷念啊!

2020年4月23日 星期四

考慮停訂今周刊

今天在報橘看到這一篇文章 :

# 黨國藝人徘徊藝能界

這讓我想到訂閱多年的今周刊幾乎每期都有這位王某人專欄, 我都是直接跳過去, 因為沒啥營養, 費眼力兼浪費時間 (請問總編, 這個專欄的目的是甚麼?).

看了這篇後更增反感, 如果今周刊到期前還是看得到這個專欄, 那我就不會續訂了, 就像以前訂商業周刊常看到假中立的黃齊元的文章一樣, 我的動作就是停止訂閱.

我對這人的反感其實最早來自聽央吉瑪的歌之後找到下面這篇文章 :

當央吉瑪遇上王偉忠





我喜歡央吉瑪純淨的聲音還有做自己的自信 :

"人生太短, 來不及模仿別人, 我永遠不放棄做自己"

多有智慧的一句話啊!

我認同作者的看法, 教父? .... 呵呵.

2020年4月22日 星期三

Python 學習筆記 : Matplotlib 資料視覺化 (一) 基本篇

最近在測試 SciPy 時深深覺得 Matplotlib 這個繪圖套件蠻重要的, 所謂一圖勝千言, 資料只是冰冷的數據, 圖形化 (visualization) 才能讓人秒懂數據所傳達的意義. 我過去在測試機器學習時只學了幾招簡單的 Matplotlib 就趕鴨子上架, 基礎實在太薄弱, 所以想在深入 SciPy 前先對 Matplotlib 做個較完整的測試, 這樣比較不會心虛. 其實我從 2019 年初即想要學 Matplotlib, 但一直都分心去做別的事, 頗感無奈. Python 資料科學三劍客 Numpy, Pandas, 與 Matplotlib 是機器學習最重要的先修課程, 這三個不熟會阻礙機器學習的修練進程, 必須盡快搞定才行.

Matplotlib 是一套類似 MATLAB 的 Python 物件導向繪圖函數套件, 最初開發者是已故美國神經生物學家 John D. Hunter,  他在 2003 年做博士後研究時為了要顯示癲癇患者的腦皮層電圖  (electrocorticography) 而開發, 在此之前他原先使用 MATLAB (商業軟體), 但因為無法應付檔案格式轉換與多重資料來源等需求, 最後選擇用 Python 語言基於 Numpy 與 SciPy 套件自行開發, 並以 BSD 授權開放原始碼. 2008 年 NASA 的鳳凰號火星探測器與第一個黑洞照片之影像處理均使用了 Matplotlib. Hunter 博士於 2012 年因大腸癌逝世, Python 軟體基金會於當年頒發了第一座最高榮譽的傑出服務獎座給 Hunter, 以表彰其對 Python 社群的巨大貢獻, 參考 :

https://matplotlib.org/
https://zh.wikipedia.org/wiki/Matplotlib
https://www.python.org/community/awards/psf-distinguished-awards/

資料視覺化由於只是個圖形化技術常常會被忽視, 但其實它非常重要, 因為不適當或不正確的呈現方式可能會將原本做得非常棒的資料分析都搞砸了. Matplotlib 可以繪製出效果媲美 MATLAB 之多種格式精美圖形 (包括 2D 與 3D), 而且也被封裝到 Pandas 裡面, 可以快速且方便地繪製 Series 與 DataFrame 物件之圖形, 因為它具有如下特點, 所以近年來 Matplotlib 隨著 Python 的普及而被廣泛使用, 特別是科學與工程界 :
  • 用法簡單且可控制圖形中的元件
  • 可產生具有互動性 (interactive) 的圖形
  • 文字與數學運算式以 LaTeX 格式顯示
  • 可輸出為 PNG, PDF, SVG, 以及 EPS 等格式
Matplotlib 設計的初衷是在使用介面與語法上盡量貼近 MATLAB, 而且繼承了 MATLAB 最受歡迎的互動性 (即透過一道道指令來控制圖形的漸進發展), 這樣就可讓大部分熟悉 MATLAB 的使用者幾乎都能無痛轉移到 Matplotlib.

Matplotlib 的原始碼寄存於 GitHub, 參見 :

https://github.com/matplotlib/matplotlib

本系列測試參考書目如下 :

# Python 資料運算與分析實戰 (旗標, 中久喜健司)
# 王者歸來-Python 在大數據科學計算上的最佳實作 (佳魁, 張若愚)
# Python 資料科學與人工智慧應用實務 (旗標, 陳允傑)
# Python 入門邁向高手之路王者歸來 (深石, 洪錦魁)
# Python 程式設計學習經典 (碁峰, 黃立政)
# 一步到位-Python 程式設計 (旗標, 陳惠貞)
# Matplotlib Plotting Cookbook (Packt, 2014)
Python資料科學學習手冊 (Oreilly, 2017) 第四章
Matplotlib 3.0 Cookbook (Packt, 2019)
# Python Data Analytics 2nd Ed. (Apress, 2018) 第七章
Python for Data Analysis 2nd Ed. (Oreilly, 2018) 第九章
# Python Data Analytics and Visualization (Packt, 2017)  第四章
# Matplotlib for Python Developers 2nd Ed. (Packt, 2018)
# Practical Python Data Visualization (Apress, 2021)

更多 Python 筆記參考 :

Python 學習筆記索引 


一. 安裝 Matplotlib 套件 : 

Matplotlib 套件主要是在 Numpy 基礎上建立起來的, 因此須先安裝 Numpy 後再安裝 matplotlib. 在命令列視窗中用 pip 指令即可安裝 :

pip3 install matplotlib 

若之前已安裝過, 則可以加上 -U 參數更新為最新版 :

pip3 install matplotlib -U 

D:\>pip3 install matplotlib -U
Collecting matplotlib
  Downloading matplotlib-3.2.1-cp37-cp37m-win_amd64.whl (9.2 MB)
Requirement already satisfied, skipping upgrade: python-dateutil>=2.1 in c:\python37\lib\site-packages (from matplotlib) (2.7.5)
Requirement already satisfied, skipping upgrade: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in c:\python37\lib\site-packages (from matplotlib) (2.3.1)
Requirement already satisfied, skipping upgrade: numpy>=1.11 in c:\python37\lib\site-packages (from matplotlib) (1.16.0)
Requirement already satisfied, skipping upgrade: cycler>=0.10 in c:\python37\lib\site-packages (from matplotlib) (0.10.0)
Requirement already satisfied, skipping upgrade: kiwisolver>=1.0.1 in c:\python37\lib\site-packages (from matplotlib) (1.0.1)
Requirement already satisfied, skipping upgrade: six>=1.5 in c:\python37\lib\site-packages (from python-dateutil>=2.1->matplotlib) (1.12.0)
Requirement already satisfied, skipping upgrade: setuptools in c:\python37\lib\site-packages (from kiwisolver>=1.0.1->matplotlib) (40.9.0)
Installing collected packages: matplotlib
  Attempting uninstall: matplotlib
    Found existing installation: matplotlib 3.0.2
    Uninstalling matplotlib-3.0.2:
      Successfully uninstalled matplotlib-3.0.2
Successfully installed matplotlib-3.2.1

可見已從原先的 3.0.2 升版為 3.2.1 版.


二. Matplotlib 基本繪圖 : 

Matplotlib 提供三種繪圖方式 :
  • 使用 pyplot 模組 (類似 MATLAB)
  • 使用 pylab 模組 (與 MATLAB 介面相同)
  • 使用物件導向方式
因為 Matplotlib 是物件導向繪圖函式庫, 使用者可直接操控 Matplotlib 底層的 Figure (單一的繪圖容器) 與 Axes 物件 (具有邊界, 刻度, 與標籤之方形繪圖區) 物件來繪圖, 使用者對於圖形有完全的操控能力, 由於具有靈活性與可客製化優點, 通常用於複雜度高的大型程式開發, 雖然比 pyplot 要麻煩些, 但使用物件導向方式來繪圖其實主要也只是在呼叫 Figure 與 Axes 物件的各種方法而已.

pylab 模組的使用介面與知名版權軟體 MATLAB 極為相似, 主要是為了讓 MATLAB 使用者可無縫接軌, 而且語法簡潔, 例如圓周率就用 pi, 繪圖是呼叫 plot() 函數等. 但是由於 pylab 使用 star import 方式將 Numpy 與 pyplot 合併到單一的命名空間中 (這樣使用者就不需要自行 import), 並將部分 Python 內建函數例如 sum() 與 all() 等以 Numpy 的函數取代, 這可能產生命名空間汙染問題. 使用 pylab 只是遷就 MATLAB 的方便性, 反而背離了 Matplotlib 的物件導向精神, 故不建議使用 pylab.

pyplot 模組則是將 Matplotlab 的物件導向函式庫再包裝成類似 MATLAB 的函數式 API, 將許多繪圖物件的複雜結構隱藏起來, 並透過有限狀態機 (state machine) 來追蹤目前圖表與子圖的狀態, 我們只要呼叫 pyplot 所提供函數即可透過簡單的設定實現快速繪圖, 非常適合用一般的資料圖形化繪圖 (但不適合用在大型程式設計), 因為使用 pyplot 繪製最簡單的資料圖形只需要 2~3 個指令而已, 與 MATLAB 相似度高, 又沒有 pylab 命名空間可能被汙染之問題.

參考 :

理解matplotlib、pylab与pyplot之间的关系 
matplotlib的常用的两种方式以及pylab
pylab是matplotlib的一个模块吗,跟pyplot又是什么关系呢?

如果使用 Jupyter Notebook, 請先輸入下列指令 :

%matplotlib inline 

使用 pyplot 繪圖首先要匯入 matplotlib.pyplot 模組 :

import matplotlib.pyplot as plt   

通常都為 pyplot 取 plt 這個別名來簡化打字, 別名可任取, 不過, 如同 numpy 用 np 與 pandas 用 pd 一樣, 取 plt 只是慣例. 如果有要用到 Numpy 或 Matplotlib 本身 (例如設定中文時會用到), 再另外匯入即可 (matplotlib 的別名通常取 mpl) :

import matplotlib as mpl
import numpy as np 

接著呼叫 pyplot.plot() 函數並傳入要顯示的資料, 然後呼叫 pyplot.show() 方法即可顯示圖形, 預設是繪製一個折線圖 (line chart), 透過樣式設定也可以繪製散佈圖 (scatter chart) :

plt.plot(data)
plt.show()

注意, plt.show() 會開啟一個事件迴圈並檢視作用中的繪圖物件, 然後開啟一個或多個交談式繪圖視窗. plt.show() 都是放在程式最後面, 它應該只被呼叫一次, 多次呼叫 plt.show() 可能會導致非預期的結果. 其次, 若使用 Jupyter Notebook, 則不需要呼叫 plt.show() 即可在頁面上繪圖. 

下面以過去一周的每日平均溫度為例, 將溫度數據以串列傳給 pyplot() 即可繪圖 :


範例 1 : 繪製一周平均溫度變化圖 [GitHub 原始碼]

import matplotlib.pyplot as plt
plt.plot([25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9])   #傳入串列數據
plt.show()

可見使用 pyplot 繪圖非常簡單, 只要三行指令就可以了, 結果如下 :




以下是在 Python shell 中的操作 :

>>> import matplotlib.pyplot as plt
>>> temperature=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]
>>> plt.plot(temperature)
[<matplotlib.lines.Line2D object at 0x000001A00EBBF780>]
>>> plt.show()   

可見呼叫 plot() 會傳回一個 Line2D 物件.

如果是在 Jupyter Lab 或 Notebook 環境中, 只要呼叫 pyplot.plot() 即輸出圖形了, 不需要呼叫 show(), 下面是在 Jupyter 官網測試網頁測試的結果 :

https://jupyter.org/try




如果呼叫 plot() 方法時只傳入一個參數, 則此參數會被 Matplotlib 認為是 Y 軸資料, 並以其索引  (0 起始) 當作 X 軸資料, 即 [0, 1, 2, 3, .... N-1], N 為元素個數. 這種情況下 Matplotlib 會以 plot() 的參數預設值繪製出一個沒有標題 (title), 沒有座標軸標籤 (axis label), 也沒有圖例 (legend) 與格線的藍色折線圖, 雖然很陽春, 但都可以透過 plot() 參數與 pyplot 模組的其他函數來設定.


1. 用樣式字串設定圖形樣式 :

其實 plot() 函數可以傳入多個參數, 其中包括圖形樣式字串, 格式如下 :

plot([x1], y1, [樣式字串1], [x2], y2, [樣式字串2], ..., [關鍵字參數]) 

除了必要參數 y1 外, 其餘均為選擇性參數, 都有預設值, 除樣式字串外都是關鍵字參數 (keyword argument), 可指定關鍵字與以設定, 常用的呼叫格式例如 :

plot(y)                                         #以預設線條樣式 (藍色折線) 繪製 y 軸資料
plot(x, y)                                     #以預設線條樣式 (藍色折線) 繪製 x, y 軸資料
plot(x1, y1, x1, y2)                     #以預設線條樣式 (藍色折線) 繪製兩條 x, y 軸資料
plot(y, 'ro')                                  #以指定樣式 'ro' (紅色原點) 繪製 x, y 軸資料
plot(x, y, 'g--')                             #以指定樣式 (綠色虛線) 繪製 x, y 軸資料
plot(x1, y1, 'ro', x1, y2, 'g--')      #以指定樣式繪製兩條 x, y 軸資料
plot(x, y, 'r.', linewidth=2)          #以指定樣式 (紅色點線) 與指定線寬繪製 x, y 軸資料

參考 :

https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.pyplot.plot.html

上面範例中未傳入 X 軸資料, Matplotlib 自動以 Y 軸資料的索引當作 X 軸資料, 下面的範例則傳入 X 軸資料 (星期字串之縮寫) 並指定用紅色圓點繪製, 例如 :


範例 2 : 指定繪圖樣式 [GitHub 原始碼]

import matplotlib.pyplot as plt
temperature=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]
week=['Sun','Mon','Tue','Wen','Thu','Fri','Sat']             #X 軸資料
plt.plot(week,temperature,'ro')                                     #指定紅色圓點樣式
plt.show()



可見 X 軸刻度已經變成所傳入之星期字串了, 且資料以紅色圓點繪製 (沒有連線). 樣式字串用來控制資料點標記符號, 連線型式, 以及它們的顏色, 由下表中的格式字元組合而成 :


 資料點標記 說明
 "." 圓點 (point, 預設)
 "," 像素 (pixel)
 "*" 星號 (star)
 "+" 加號 (plus)
 "x" 乘號 (x)
 "o" 圓點 (circle)
 "s" 方形 (square)
 "p" 五角形 (pentagon)
 "D" 鑽石形 (diamond)
 "d" 細鑽石形 (thin_diamond)
 "h" 六角形1 (hexagon1)
 "H" 六角形2 (hexagon2)
 "^" 上三角形 (triangle_up)
 "v" 下三角形 (triangle_down)
 "<" 左三角形 (triangle_left)
 ">" 右三角形 (triangle_right)
 "|" 垂直線 (vline)
 "_" 底線 (hline)
 "1" 下三叉 (tri_down)
 "2" 上三叉 (tri_up)
 "3" 左三叉 (tri_left)
 "4" 右三叉 (tri_right)

 連線型式 說明
 "-" 或 "solid" 實線 (solid line, 預設)
 "--" 或 "dashed" 短線虛線 (dashed line)
 ":" 或 "dotted" 點虛線 (dotted)
 "-:" 或 "dash-dotted" 短線點虛線 (dash-dotted line)

 顏色 說明
 "r" 紅色 red
 "g" 綠色 green
 "b" 藍色 blue (預設)
 "c" 青色 cyan
 "m" 洋紅色 magenta
 "y" 黃色 yellow
 "k" 黑色 black
 "w" 白色 white


這些樣式可以任意組合, 例如 'g--+' 表示資料點標記符號為加號 '+', 連線為短虛線 '--', 顏色為綠色. 注意, 顏色樣式是一起套用到資料點標記與連線上. 例如 :


範例 2-1 : 資料點標記 (markers) [GitHub 原始碼]

import matplotlib.pyplot as plt

markers=['.', ',', '*', '+', 'x', 'o', 's', 'p', 'D', 'd', 'h',
         'H', '^', 'v', '<', '>', '|', '_', '1', '2', '3', '4']
x=range(len(markers))
for i in x:
    plt.plot(i, i, markers[i])
plt.show()

此程式將全部資料點標記 markers 字元放在串列中, 然後在繪製 y=x 線條時逐一指定不同的標記符號, 結果如下 : 



 
注意, 第二個標記 ',' 是一個 pixel 的小點, 所以看起來不明顯. 

下面範例是連線型式的測試 :


範例 2-2 : 連線型式 (line styles) [GitHub 原始碼]

import numpy as np
import matplotlib.pyplot as plt

x=np.arange(5)
y=x
plt.plot(x, y, '-')                # 實線
plt.plot(x, y + 1 , '--')       # 短線虛線
plt.plot(x, y + 2, '-.')        # 短線點虛線
plt.plot(x, y + 3, ':')         # 點虛線
plt.show()

此例分別以四種連線型式繪製 y=x 線, 結果如下 : 




由下至上為實線, 短線虛線, 短線點虛線, 以及點虛線. 


2. 繪製多個圖形 : 

可傳入多組 x, y 軸數據在同一張圖上繪製多個圖形, 例如比較上週與本周氣溫變化 :


範例 3 : 繪製兩組資料之圖形 [GitHub 原始碼]

import matplotlib.pyplot as plt
week=['Sun','Mon','Tue','Wen','Thu','Fri','Sat']              #X 軸
this_week=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]     #本周氣溫
last_week=[22.2, 25.2, 26.6, 22.8, 20.1, 24.3, 28.9]     #上周氣溫
plt.plot(week,this_week,'r--o',week, last_week,'b-s')    #繪製兩組資料
plt.show() 

此例有本周與上周兩組氣溫資料 this_week 與 last_week 當 Y 軸, 分別用紅圓點標記短虛線樣式 'r--o' 與方形藍色標記實線樣式 'b-s' 繪製, 它們共用相同的 X 軸資料, 結果如下 :




此例中使用 plot(x1, y1, x2, y2) 呼叫方式一次繪製兩組資料, 其實也可以每組資料分別呼叫 plot(x, y) 分兩次來繪製, 亦即 plt.plot(week,this_week,'r--o',week, last_week,'b-s') 可以拆成如下兩次呼叫, 結果一樣 :

plt.plot(week,this_week,'r--o')
plt.plot(week, last_week,'b-s')


3. 用參數設定圖形樣式 : 

事實上除了使用樣式字串設定資料點標記符號, 連線的形式與兩者的顏色外, 還可以使用 plot() 函數的選擇性參數來設定圖面元素的樣式, 且其操控項目比樣式字串更豐富, 如下表所示 :


 plot() 的選擇性參數 說明
 alpha 透明度 (0 透明~1 不透明)
 color 連線的顏色, 例如 'red', '#ff0000', (1, 0, 0)
 linestyle 連線樣式, 例如 'solid', 'dashed', 'dashdot', 'dotted'
 linewidth 連線寬度 (整數, 單位 px)
 marker 資料點標記符號類型, 例如 'o' 圓形, 's' 方形, 'p' 五角形等
 markersize 資料點標記符號大小 (整數, 單位 px)
 markerfacecolor 資料點標記符號顏色, 例如 'green', '#00ff00', (0, 1, 0)
 markeredgecolor 資料點標記符號周圍顏色, 例如 'blue', '#0000ff', (0, 0, 1)
 markeredgewidth 資料點標記符號邊緣寬度 (整數, 單位 px)


可見使用選擇性參數還多出了顏色透明度, 連線寬度, 資料點標記符號的大小, 邊緣寬度與顏色等樣式的微調. 顏色參數 color, markerfacecolor, 與 markeredgecolor 可用文字, 16 進位字串, 或者 (R, G, B) 數值元組, 每個顏色值為 0~1, 例如 (0, 0, 1) 表示藍色. 16 進位顏色代碼參考 :

命名顏色代碼
https://wiki.tcl-lang.org/page/Colors+with+Names

上面範例 3 可以用參數改寫為如下範例 3-1 :


範例 3-1 : 使用參數設定樣式 (1) [GitHub 原始碼]

import matplotlib.pyplot as plt
week=['Sun','Mon','Tue','Wen','Thu','Fri','Sat']         #X 軸
this_week=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]     #本周氣溫
last_week=[22.2, 25.2, 26.6, 22.8, 20.1, 24.3, 28.9]     #上周氣溫
plt.plot(week,this_week, color='red', marker='o', linestyle='dashed') #繪製第一組資料
plt.plot(week,last_week, color='b', marker='s', linestyle='solid')    #繪製第二組資料
plt.show()

繪圖結果與上面範例 3 使用樣式字串者完全一樣.

下面範例 3-2 測試了更多參數 :


範例 3-2 : 使用參數設定樣式 (2) [GitHub 原始碼]

import matplotlib.pyplot as plt
week=['Sun','Mon','Tue','Wen','Thu','Fri','Sat']         #X 軸
this_week=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]     #本周氣溫
last_week=[22.2, 25.2, 26.6, 22.8, 20.1, 24.3, 28.9]     #上周氣溫
plt.plot(week,this_week,
         color='black',
         marker='p',
         linestyle='dotted',
         linewidth=1) #繪製第一組資料
plt.plot(week,last_week,
         alpha=0.5,
         color='magenta',
         marker='s',
         markersize=8,
         markerfacecolor='green',
         markeredgecolor='yellow',
         linestyle='solid')    #繪製第二組資料
plt.show()

結果如下 :




可見第二組資料不論是資料點或連線都因為 alpha=0.5 之設定變成半透明.


4. 設定標題 (title) 與座標軸標籤 (xlabel, ylabel) : 

以上所繪製的圖形預設都沒有標題 (title), 以及座標軸標籤 (axis label), 所傳達的資訊並不完整, 這可以分別呼叫 pyplot 的 title(), 以及 xlable() 與 ylabel() 函數來設定, 參考 : 


例如 :


範例 4-1 : 添加標題與軸標籤 [GitHub 原始碼]

import matplotlib.pyplot as plt
week=['Sun','Mon','Tue','Wen','Thu','Fri','Sat']             #X 軸
this_week=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]    #本周氣溫
last_week=[22.2, 25.2, 26.6, 22.8, 20.1, 24.3, 28.9]    #上周氣溫
plt.plot(week,this_week,'r--o',week, last_week,'b-s')   #繪製兩組資料
plt.title('Temperature Comparison')                             #設定圖形標題
plt.xlabel('Week day')                                                   #設定 X 軸標籤
plt.ylabel('Celsius')                                                       #設定 Y 軸標籤
plt.show()

結果如下 :




可見坐標軸標籤與標題都有了, 其大小與顏色都是預設值 (黑色), 如果要修改字型大小與顏色, 可在呼叫 title(), xlabel(), 以及 ylabel() 時傳入 fontsize, fontname (字串, 例如 'Times New Roman') 與 color (字串, 數值, 或元組) 等參數, 如下面範例所示 :


範例 4-2 : 設定標題與軸標籤大小與顏色 [GitHub 原始碼]

import matplotlib.pyplot as plt
week=['Sun','Mon','Tue','Wen','Thu','Fri','Sat']        #X 軸
this_week=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]    #本周氣溫
last_week=[22.2, 25.2, 26.6, 22.8, 20.1, 24.3, 28.9]    #上周氣溫
plt.plot(week,this_week,'r--o',week, last_week,'b-s')   #繪製兩組資料
plt.title('Temperature Comparison', fontsize=16, color='blue') #設定圖形標題
plt.xlabel('Week day', fontsize=14, color='blue')       #設定 X 軸標籤
plt.ylabel('Celsius', fontsize=14, color='blue')        #設定 Y 軸標籤
plt.show()

此例標題大小設為 16, 坐標軸標籤大小設為 14, 顏色均為藍色, 結果如下 :




顏色 color 參數也可以使用 '#ffdd0e, 0~1 數值, 或 0~1 數值組成之 (r, g, b) 元組.

雖然座標軸標籤與圖形標題都有了, 但還缺一個圖例 (legend) 來說明每個圖形是甚麼數據.


5. 設定圖例 (legend) :

添加圖例可呼叫 pyplot 的 legend() 函數來達成, 並配合在呼叫 plot() 時傳入 label 參數為每個圖形設定圖例標籤, 不過這樣就不能呼叫 plot(x1, y1, x2, y2) 來一次繪製這兩組資料了, 必須拆開分別呼叫 plot(x, y) 分兩次繪製, 這樣才能分別為各組資料設定 label 參數, 參考 : 


例如 :


範例 5-1 : 設定圖例標籤與位置 (1) [GitHub 原始碼]

import matplotlib.pyplot as plt
week=['Sun','Mon','Tue','Wen','Thu','Fri','Sat']              #X 軸
this_week=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]     #本周氣溫
last_week=[22.2, 25.2, 26.6, 22.8, 20.1, 24.3, 28.9]     #上周氣溫
plt.plot(week,this_week,'r--o',label='this week')           #指定資料之圖例標籤
plt.plot(week, last_week,'b-s',label='last week')            #指定資料之圖例標籤
plt.legend()                                                                    #顯示圖例
plt.title('Temperature Comparison')                               #設定圖形標題
plt.xlabel('Week day')                                                    #設定 X 軸名稱
plt.ylabel('Celsius')                                                        #設定 Y 軸名稱
plt.show()
此例在呼叫 plot() 時傳入 label 參數字串, 這就是在圖例中顯示的字串, 結果如下 :




可見圖例預設會顯示在左上角, 但可以在呼叫 legend() 函數時傳入 loc 參數 (字串或整數) 來指定圖例擺放的位置, 可用的位置字串如下表 :


 圖例 loc 參數 數值 說明
 'best' 0 自動挑選最佳位置
 'upper right' 1 右上角
 'upper left' 2 左上角
 'lower left' 3 左下角
 'lower right' 4 右下角
 'right' 5 右邊
 'center left' 6 左邊中間
 'center right' 7 右邊中間
 'lower center' 8 下方中間
 'upper center' 9 上方中間
 'center' 10 中間


此外, 圖例標籤除了可在呼叫 plot() 函數時傳入 label 參數字串來設定外, 也可以在呼叫 legend() 時傳入一個表示圖例標籤的字串串列來設定, 這樣做的話每一組資料要分別呼叫 plot (x, y) 函數來繪圖, 而串列中的元素順序就對應呼叫 plot() 之順序, 例如 :


範例 5-2 : 設定圖例標籤與位置 (2) [GitHub 原始碼]

import matplotlib.pyplot as plt
week=['Sun','Mon','Tue','Wen','Thu','Fri','Sat']                #X 軸
this_week=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]      #本周氣溫
last_week=[22.2, 25.2, 26.6, 22.8, 20.1, 24.3, 28.9]      #上周氣溫
plt.plot(week, last_week,'b-s')
plt.plot(week,this_week,'r--o')
plt.legend(['last_week', 'this_week'], loc='lower left')    #設定圖例標籤與位置
plt.title('Temperature Comparison')     #設定圖形標題
plt.xlabel('Week day')                          #設定 X 軸標籤
plt.ylabel('Celsius')                              #設定 Y 軸標籤
plt.show()

此例呼叫 legend() 時所傳入的圖例標籤串列依序對應前面的兩個 plot() 呼叫, 結果如下 :




可見傳入 loc='lower left' 可將圖例位置設為左下角.


6. 繪製函數圖形 :

以上的範例使用串列所提供的列舉資料繪圖, 但 Matplotlib 的強項是搭配 Numpy 進行函數繪圖, 事實上傳入 plot() 的 X, Y 軸串列資料都會被 Matplotlib 轉成 Numpy 的 ndarray 陣列後再進行繪圖. 關於 Numpy 陣列基本操作參考 :

Python 學習筆記 : Numpy 測試 (一) : 建立陣列

下面範例利用 Numpy 的 arange() 與 linspace() 函數繪製函數圖形, 這兩個函數的介面如下 :


 np 建立陣列方法 說明
 arange(e) 建立元素值為 0, 1, 2 ... (e-1) 的陣列
 arange(b, e) 建立元素值為 b, b+1, b+2 ... (e-1) 的陣列
 arange(b, e, s) 建立元素值為 b, b+s, b+2s ... (e-1) 的陣列 (步階為 s)
 linspace(b, e) 建立 50 個等差數列元素之陣列 (含 e), 公差為 (e-b)/49
 linspace(b, e, n) 建立 n 個等差數列元素之陣列 (含 e), 公差為 (e-b)/(n-1) 


下面是繪製代數函數 (即多項式方程式) 的範例 :


範例 6-1 : 繪製代數函數圖形 [GitHub 原始碼]

import numpy as np
import matplotlib.pyplot as plt
x=np.arange(0,10)                    #X 軸
y1=x                                          #Y軸1=x
y2=x**2                                    #Y軸2=x**2
plt.plot(x, y1, 'r--o', label='x')          #指定資料之圖例標籤
plt.plot(x, y2, 'b-s', label='x**2')     #指定資料之圖例標籤
plt.legend()                                #顯示圖例
plt.title('functions')                    #設定圖形標題
plt.xlabel('X')                             #設定 X 軸標籤
plt.ylabel('Y')                             #設定 Y 軸標籤
plt.show()

此例繪製兩個函數 : y=x (線性函數) 與 y=x**2 (平方函數), X 軸是以 numpy.arange() 函數產生的 0~10 之等差數列陣列 (ndarray 物件), 也可以用 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 串列代替, 不過傳入 plot() 後會被轉成 Numpy 的 ndarray 陣列. 結果如下 :




下面則是繪製超越函數 (即非代數函數), 以正弦 sin(x) 與餘弦 cos(x) 為例 :


範例 6-2 : 繪製超越函數圖形 [GitHub 原始碼]

import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(0,10,100)            #X 軸
y1=np.sin(x)                              #Y軸1=sin(x)
y2=np.cos(x)                             #Y軸2=cos(x)
plt.plot(x, y1, '-r', label='sin(x)')    #指定資料之圖例標籤
plt.plot(x, y2, ':b', label='cos(x)')    #指定資料之圖例標籤
plt.legend()                               #顯示圖例
plt.title('functions')                   #設定圖形標題
plt.xlabel('X')                           #設定 X 軸標籤
plt.ylabel('Y')                           #設定 Y 軸標籤
plt.show()

此例利用 Numpy 的 linspace() 函數產生 [0, 10] 之間的 100 個均距數值陣列 (含 0 與 100) 當作 X 軸, 繪製三角函數 sin(x) 與 cos(x) 的圖形, 結果如下 :





7. 設定坐標軸範圍 :

由上面範例中可知, Matplotlib 預設會給 X, Y 軸留一些適當的邊限餘裕 (margin), 如果不想要這些餘裕可呼叫 axis() 並傳入一個四元素串列 [xmin, xmax, ymin, ymax] (或元組) 來設定圖形的 viewport (顯示範圍) :

plt.axis([xmin, xmax, ymin, ymax])    

如果呼叫 axis() 時沒有傳入參數, 則會傳回一個表示 X, Y 軸範圍的四元素元組 (getter) :

plt.axis()   #傳回 (xmin, xmax, ymin, ymax)

參考 :


如下面範例所示 :


範例 7-1 : 用 axis() 設定坐標軸範圍 [GitHub 原始碼]

import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(0,10,100)                  #X 軸
y1=np.sin(x)                             #Y軸1=sin(x)
y2=np.cos(x)                             #Y軸2=cos(x)
plt.plot(x, y1, '-r', label='sin(x)')    #指定資料之圖例標籤
plt.plot(x, y2, ':b', label='cos(x)')    #指定資料之圖例標籤
plt.axis([0, 10, -1, 1])                 #設定坐標軸範圍
print(plt.axis())                        #顯示坐標軸範圍
plt.legend()                             #顯示圖例
plt.title('functions')                   #設定圖形標題
plt.xlabel('X')                          #設定 X 軸標籤
plt.ylabel('Y')                          #設定 Y 軸標籤
plt.show()

此例 X 軸範圍設定與 x 變數範圍一樣即可, 而 Y 軸則因 sin(x) 與 cos(x) 值域範圍為 [-1, 1], 故傳入 [0, 10, -1, 1] 時圖框剛好與圖形密接而無餘裕, 結果如下 :




呼叫 axis() 會傳回一個元組 :

(0.0, 10.0, -1.0, 1.0)

設定坐標軸範圍除了呼叫 axis() 一次設定 X, Y 軸範圍外, 還可以呼叫 xlim() 與 ylim() 並傳入二元素的串列 (或元組) 分別設定 X, Y 軸座標範圍 :

plt.xlim([xmin, xmax])
plt.ylim([ymin, ymax])


範例 7-2 : 用 axis() 設定坐標軸範圍 [GitHub 原始碼]

import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(0,10,100)                  #X 軸
y1=np.sin(x)                             #Y軸1=sin(x)
y2=np.cos(x)                             #Y軸2=cos(x)
plt.plot(x, y1, '-r', label='sin(x)')    #指定資料之圖例標籤
plt.plot(x, y2, ':b', label='cos(x)')    #指定資料之圖例標籤
plt.xlim([0, 10])                        #設定X坐標軸範圍
plt.ylim([-1, 1])                        #設定Y坐標軸範圍
print(plt.xlim())                        #顯示X坐標軸範圍
print(plt.ylim())                        #顯示Y坐標軸範圍
plt.legend()                             #顯示圖例
plt.title('functions')                   #設定圖形標題
plt.xlabel('X')                          #設定 X 軸標籤
plt.ylabel('Y')                          #設定 Y 軸標籤
plt.show()

此例用 xlim([xmin, xmax]) 與 ylim([ymin, ymax]) 設定 X, Y 軸範圍, 結果與上面範例相同, 呼叫 xlim() 與 ylim() 則傳回兩個元組 :

(0.0, 10.0)
(-1.0, 1.0)


8. 設定坐標軸刻度 : 

由上面的範例可知, Matplotlib 會自動為 X, Y 坐標軸打上適當的刻度 (ticks), 如果想要自訂刻度可以透過呼叫 xticks(seq, labels) 與 yticks(seq, labels) 來設定 :

xticks(seq, labels) : 以序列物件 seq 與對應之標籤 labels 設定 X 軸座標之刻度
yticks(seq, labels) : 以序列物件 seq 與對應之標籤 labels 設定 X 軸座標之刻度

其中序列物件 seq 可以是元組或串列, 參考 : 

https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.yticks.html

例如上面範例 6-1 的 X 軸座標刻度是顯示 [0, 2, 4, 6, 8], 如果要改為 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 可將此序列傳入 xticks(), 如下列範例所示 :


範例 8-1 : 用 xticks() 使 X 坐標軸刻度標示更精細 [GitHub 原始碼]

import numpy as np
import matplotlib.pyplot as plt
x=np.arange(0,10)                    #X 軸
y1=x                                    #Y軸1=x
y2=x**2                              #Y軸2=x**2
plt.plot(x, y1, 'r--o', label='x')   #指定資料之圖例標籤
plt.plot(x, y2, 'b:d', label='x**2') #指定資料之圖例標籤
plt.xticks(x)                        #設定 X 軸刻度讀數
plt.legend()                         #顯示圖例
plt.title('functions')             #設定圖形標題
plt.xlabel('X')                      #設定 X 軸標籤
plt.ylabel('Y')                      #設定 Y 軸標籤
plt.show()

此例僅用 X 軸資料設定 X 軸座標之刻度 (因 Y 軸 OK 不需要改), 結果如下 :




可見 X 軸刻度已經改變為間隔 1 了.

除了使刻度標示更精細外, 調整刻度標示最主要的目的還是改善資料的視覺傳達效果. 例如下面這個範例是比較台股兩個主要 ETF 台灣五十 (0050) 與台灣高股息 (0056) 的殖利率變化, 更能清楚了解調整座標軸刻度的必要性.


範例 8-2 : ETF 殖利率比較 (1) [GitHub 原始碼]

import numpy as np
import matplotlib.pyplot as plt
x=(2015, 2016, 2017, 2018, 2019)      #X 軸
y1=(4.33, 5.67, 3.78, 5.62, 6.7)      #Y軸1=0056殖利率
y2=(3.01, 1.28, 6.1, 7.1, 7.22)       #Y軸2=0050殖利率
plt.plot(x, y1, 'r--o', label='0056')  #指定資料之圖例標籤
plt.plot(x, y2, 'b:d', label='0050')   #指定資料之圖例標籤
plt.legend()                                    #顯示圖例
plt.title('ETF Dividend Yield')       #設定圖形標題
plt.xlabel('Year')                             #設定 X 軸標籤
plt.ylabel('Dividend yield(%)')       #設定 Y 軸標籤
plt.show()

此例中的 x 是以數值元組表示的近五年年份, 作為 X 軸資料; Y 軸資料部分, y1 是近五年 0056 的殖利率數據; y2 則是 0050 的殖利率, 資料來源為 Goodinfo (台灣股市資訊網), 參考 :

https://goodinfo.tw/StockInfo/StockDividendPolicy.asp?STOCK_ID=0050&SHOW_ROTC=
https://goodinfo.tw/StockInfo/StockDividendPolicy.asp?STOCK_ID=0056&SHOW_ROTC=

結果如下 :



可見由於 X 軸資料是數值 tuple, 使得年份的 X 軸刻度被 Matplotlib 自動當作是浮點數處理, 與一般年份以整數表示的習慣不符; 其次, Y 軸數據是浮點數, 但刻度標示卻只有整數, 如果能精細到 0.5 會比較好, 應該用 xticks() 與 yticks() 予以調整, 如下面範例所示 :


範例 8-3 : ETF 殖利率比較 (2) : 調整 X/Y 軸刻度 [GitHub 原始碼]

import numpy as np
import matplotlib.pyplot as plt
x=(2015, 2016, 2017, 2018, 2019)      #X 軸
y1=(4.33, 5.67, 3.78, 5.62, 6.7)      #Y軸1=0056殖利率
y2=(3.01, 1.28, 6.1, 7.1, 7.22)       #Y軸2=0050殖利率
plt.plot(x, y1, 'r--o', label='0056') #指定資料之圖例標籤
plt.plot(x, y2, 'b:d', label='0050')  #指定資料之圖例標籤
plt.xticks(x)                                   #設定 X 軸刻度讀數
plt.yticks(np.arange(1, 8, 0.5))      #設定 Y 軸刻度讀數
plt.legend()                                    #顯示圖例
plt.title('ETF Dividend Yield')       #設定圖形標題
plt.xlabel('Year')                             #設定 X 軸標籤
plt.ylabel('Dividend yield(%)')       #設定 Y 軸標籤
plt.show()

此例以 X 軸資料傳給 xticks() 設定座標軸刻度標示, 以 Numpy 的 arange() 函數產生 1~8 間隔 0.5 的浮點數陣列傳給 yticks() 設定 Y 軸刻度標示, 結果如下 :




經過調整後的座標軸刻度就比較合理清楚了. 如果不想顯示座標軸刻度, 只要將一個空串列傳入 plt.xticks() 與 plt.yticks() 即可, 但這種應用場合並不多見. 

坐標軸刻度的樣式除了可在 plt.xticks() 與 plt.yticks() 中個別設定外, 也可以用 plt.tick_params() 函式統一設定, 常用語法如下 :

plt.tick_params(axis [, labelsize, color, labelcolor, width, length])    

其中必要參數 axis 指定要套用的座標軸 ('x', 'y', 'both'), 備選參數 labelsize 是刻度標籤的大小 (單位 pixel), color 是刻度的顏色 (注意, 這是刻度短線顏色, 不是標籤顏色), labelcolor 是刻度標籤的顏色, width 與 length 分別是刻度短線的厚度與長度 (單位 pixel), 更多參數參考 :



範例 8-4 : 用 plt.tick_params() 設定刻度標籤樣式 [GitHub 原始碼]

import numpy as np
import matplotlib.pyplot as plt
x=(2015, 2016, 2017, 2018, 2019)      #X 軸
y1=(4.33, 5.67, 3.78, 5.62, 6.7)           #Y軸1=0056殖利率
y2=(3.01, 1.28, 6.1, 7.1, 7.22)             #Y軸2=0050殖利率
plt.plot(x, y1, 'r--o', label='0056')        #指定資料之圖例標籤
plt.plot(x, y2, 'b:d', label='0050')         #指定資料之圖例標籤
plt.xticks(x)                                          #設定 X 軸刻度讀數
plt.yticks(np.arange(1, 8, 0.5))             #設定 Y 軸刻度讀數
plt.tick_params(axis='both',   
                labelsize='12',   
                color='blue',  
                labelcolor='blue')                  #設定刻度參數
plt.legend()                                            #顯示圖例
plt.title('ETF Dividend Yield')              #設定圖形標題
plt.xlabel('Year')                                    #設定 X 軸標籤
plt.ylabel('Dividend yield(%)')             #設定 Y 軸標籤
plt.show()

此處是在上例的基礎上添加 plt.tick_params() 以設定刻度與其標籤之樣式, 主要是將 X/Y 軸刻度與標籤顏色均設為藍色, 字型大小設為 12 DPI, 結果如下 : 




可見刻度與其標籤顏色都變成藍色了. 

坐標軸刻度還可以利用 rotation 參數加以旋轉, 這在 X/Y 軸標籤文字太長時特別有用 (例如時間序列使用日期或時間當刻度時), 因為過長的刻度標籤會互相重疊而影響可讀性, 例如下面的範例由於 X 軸標籤適日期, 預設作為水平刻度會彼此重疊 : 


範例 8-5 : 軸標籤文字太長導致的重疊問題 [GitHub 原始碼]

import matplotlib.pyplot as plt
x=['2022-02-25','2022-02-26','2022-02-27','2022-02-28',
   '2022-03-01','2022-03-02','2022-03-03']                #X 軸(日期)
temp=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]         #氣溫
humid=[56, 63, 75, 72, 66, 59, 77]                            #濕度
plt.plot(x,temp,'r--o',x, humid,'b-s')                           #繪製兩組資料
plt.title('Temperature & Humidity')                           #設定圖形標題
plt.xlabel('day')                                                          #設定 X 軸標籤
plt.ylabel('Temperature & Humidity')                       #設定 Y 軸標籤
plt.show()

結果如下 : 




可見若沒有呼叫 plt.xticks() 的話, 標籤預設會被拿來當 X 軸刻度文字, 此例由於 X 軸標籤是日期, 長度太長使得前後重疊. 解決方法是在呼叫 plt.xticks() 時傳入 rotation 參數指定旋轉角度使其適當地旋轉, 例如 : 


範例 8-6 : 呼叫 plt.xticks() 以 rotation 參數旋轉刻度標籤 [GitHub 原始碼]

import matplotlib.pyplot as plt
x=['2022-02-25','2022-02-26','2022-02-27','2022-02-28',
   '2022-03-01','2022-03-02','2022-03-03']              #X 軸(日期)
temp=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]      #氣溫
humid=[56, 63, 75, 72, 66, 59, 77]                         #濕度
plt.plot(x,temp,'r--o',x, humid,'b-s')                        #繪製兩組資料
plt.title('Temperature & Humidity')                        #設定圖形標題
plt.xlabel('day')                                                       #設定 X 軸標籤
plt.ylabel('Temperature & Humidity')                    #設定 Y 軸標籤
plt.xticks(x, rotation=20)                                     #旋轉 20 度 
plt.show()

此例呼叫 plt.xticks() 並傳入 rotation 參數指定將 X 軸刻度標籤旋轉 20 度, 結果如下 : 




可見旋轉之後就沒有刻度標籤重疊的問題了. 不過如果旋轉角度過大, 部分文字會被截掉, 這是因為超出畫布的預設大小的緣故, 必須使用物件導向方式利用畫布容器 Figure 物件來調整大小.  


2020年4月19日 星期日

2020 年第 16 周記事

本周剛慶幸連續幾天零確診, 結果因為敦睦艦隊染疫, 今天竟然暴升至 18 人確診! 真的高興不起來. 早上我去全聯買東西, 聽到全聯廣播說慶祝零確診, 咖啡一杯 12 元優惠, 本來想買一杯, 但又要重新排隊就算了. 回家途中邊騎邊想, 這幾天各行各業都在慶祝, 實在讓我心慌慌, 因為這會鬆懈大家的心防, 我們現在沒有本錢在慶祝甚麼, 只有疫情在全世界都平息下來才能慶祝!

早上照例打電話給豆腐嫂預定豆腐 (她會留邊邊最大塊的給我), 打了兩通都沒接也沒回電, 到了市集高橋邊的豆腐攤, 卻看到她兒子跟第一次見到的媳婦在顧攤, 一看到我就說, 叔叔, 有幫你留, 我知道你會來. 我問說你媽怎沒來, 他說她要退休了, 蛤? 上周來買豆腐也沒說啊? 怪的是後面補了一句 : 下周要把她的手機停掉, 奇怪, 內情應該不單純. 離開前我跟他要了手機號碼, 我說那以後訂豆腐要找你啦!

早上去種子行買 30 株大陸妹, 20 株小松油菜, 以及 4 株茄子 (我應該是要買絲瓜的, 但跟老闆娘聊天分心講錯了), 下午都種下去了, 本周有點青黃不接, 還好昨日岳母搭我便車回鄉下, 進去岳父農舍採三顆木瓜, 還有一大把連藤的大陸種地瓜葉, 那長而粗的莖以及厚實的大葉子, 這就是我找尋已久的品種, 回到家天還很亮, 趕緊將莖葉摘下, 剩下的藤切斷後種在菜園裡, 等這品種長成後, 要把阿運伯母給我的品種移除, 因為那葉子太老.





下午種完菜後本想去跑步, 但想到還有芒果沒套袋, 在過一個星期會太晚, 還是趕緊套完為好. 路邊的四棵今年結果率不佳, 大約只有 30 顆左右, 太高的套不到就算了. 套完路邊轉到後院, 發現那邊也有 20 多顆, 紅杏出牆到隔壁的我也翻牆過去套, 原來四季芒果都在隔壁農舍那邊. 一包100 張剩下 20 張左右, 估計今年芒果大約就是 100 個左右.

下午在切換筆電的無線網路時, 發現附近居然有 MicroPython 網路信號, 害我嚇了一跳 :




這個鄉下地方有人在玩 ESP32 物聯網? 難道是隔壁農舍的外地人老闆? 怎麼可能! 後來才想到應該是前年放在舊豬舍的小型氣候監測站, 因為鉛酸電池已劣化, 所以早已停工甚久, 我也沒時間改裝成 18650 電池, 大概下午太陽大, 電池又有電了, ESP32 啟動了就發射出 WiFi 訊號. 最近時間都花在學 Matplotlib, 好想能快點回來玩 ESP32.

2020年4月18日 星期六

下載臉書影片的方法

今天在臉書看到楊桃文化分享的炒豬肝不柴的密技 :

https://www.facebook.com/ytower01/videos/1149324408741885/

想下載保存該怎麼做呢? 我找到下面這篇, 完全不用安裝任何軟體就能辦到 :

一鍵下載 Facebook影片!免安裝APP、HD 高畫質

原來只要點這篇文章文章的網址列, 原先顯示的 facebook.com/blablabla ... 馬上會在前面補上 http://www 變成 http://www.facebook.com/blablabla..., 這時將其中的 www 改成 mbasic, 會開啟內容相同但版面不同的網頁 :

https://mbasic.facebook.com/watch/?v=1149324408741885






點這新網頁中的影片, 它會開啟另一個網頁專門播放此影片, 例如這個炒豬肝不柴的影片網址 :

就是這一招!讓你炒豬肝軟嫩不柴!

點影片播放後按滑鼠右鍵選擇 "將影片另存為 ..." 即可下載 mp4 影片保存了 :




這招真的不錯用, 以後就可以將值得保存的影片留下來了.