過去這一周整理 Matplotlib 學習筆記, 不僅寫完進階篇, 還回頭增修基礎篇. 進階篇中關於中文顯示的問題在 Windows 很取巧地直接在程式中用 plr.rcParams() 指定內建的微軟正黑體或雅黑體, 不費甚麼力就輕鬆搞定, 參考 :
但這做法在 Linux 就不靈了, 因為 Linux 中沒有內建這兩種中文字型, 必須老實地去下載字型檔, 然後修改 Matplotlib 設定檔才行, 以下是我在鄉下那台 Pi 3 上的測試紀錄.
樹莓派的 matplotlib 內建的 ttf 字型可用 matplotlib.font_manager.fontManager 類別的 ttflist 屬性來查詢, 裡面用串列紀錄了代表全部 ttf 字型的 Font 物件, 例如 :
pi@raspberrypi:~ $ python
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from matplotlib.font_manager import fontManager
>>> for ttf in fontManager.ttflist:
... print(ttf)
...
<Font 'STIXSizeFourSym' (STIXSizFourSymBol.ttf) normal normal bold normal>
<Font 'cmtt10' (cmtt10.ttf) normal normal 400 normal>
<Font 'STIXNonUnicode' (STIXNonUniBolIta.ttf) italic normal bold normal>
<Font 'STIXSizeTwoSym' (STIXSizTwoSymReg.ttf) normal normal regular normal>
<Font 'STIXSizeThreeSym' (STIXSizThreeSymBol.ttf) normal normal bold normal>
<Font 'cmex10' (cmex10.ttf) normal normal 400 normal>
<Font 'STIXNonUnicode' (STIXNonUniBol.ttf) normal normal bold normal>
<Font 'DejaVu Serif' (DejaVuSerif-Italic.ttf) italic normal 400 normal>
<Font 'STIXSizeThreeSym' (STIXSizThreeSymReg.ttf) normal normal regular normal>
<Font 'cmb10' (cmb10.ttf) normal normal 400 normal>
<Font 'cmmi10' (cmmi10.ttf) normal normal 400 normal>
<Font 'DejaVu Sans Mono' (DejaVuSansMono-Bold.ttf) normal normal bold normal>
<Font 'DejaVu Sans' (DejaVuSans-Oblique.ttf) oblique normal 400 normal>
<Font 'cmr10' (cmr10.ttf) normal normal 400 normal>
<Font 'STIXGeneral' (STIXGeneral.ttf) normal normal regular normal>
<Font 'DejaVu Sans Display' (DejaVuSansDisplay.ttf) normal normal 400 normal>
<Font 'DejaVu Sans' (DejaVuSans.ttf) normal normal 400 normal>
<Font 'cmss10' (cmss10.ttf) normal normal 400 normal>
<Font 'DejaVu Sans' (DejaVuSans-Bold.ttf) normal normal bold normal>
<Font 'STIXSizeOneSym' (STIXSizOneSymReg.ttf) normal normal regular normal>
<Font 'DejaVu Sans Mono' (DejaVuSansMono-Oblique.ttf) oblique normal 400 normal>
<Font 'STIXGeneral' (STIXGeneralBolIta.ttf) italic normal bold normal>
<Font 'DejaVu Sans Mono' (DejaVuSansMono-BoldOblique.ttf) oblique normal bold normal>
<Font 'STIXGeneral' (STIXGeneralBol.ttf) normal normal bold normal>
<Font 'STIXNonUnicode' (STIXNonUniIta.ttf) italic normal 400 normal>
<Font 'STIXSizeFourSym' (STIXSizFourSymReg.ttf) normal normal regular normal>
<Font 'DejaVu Serif' (DejaVuSerif-Bold.ttf) normal normal bold normal>
<Font 'cmsy10' (cmsy10.ttf) normal normal 400 normal>
<Font 'DejaVu Serif' (DejaVuSerif.ttf) normal normal 400 normal>
<Font 'STIXGeneral' (STIXGeneralItalic.ttf) italic normal 400 normal>
<Font 'DejaVu Serif Display' (DejaVuSerifDisplay.ttf) normal normal 400 normal>
<Font 'STIXSizeOneSym' (STIXSizOneSymBol.ttf) normal normal bold normal>
<Font 'STIXSizeTwoSym' (STIXSizTwoSymBol.ttf) normal normal bold normal>
<Font 'STIXNonUnicode' (STIXNonUni.ttf) normal normal regular normal>
<Font 'DejaVu Sans' (DejaVuSans-BoldOblique.ttf) oblique normal bold normal>
<Font 'DejaVu Sans Mono' (DejaVuSansMono.ttf) normal normal 400 normal>
<Font 'STIXSizeFiveSym' (STIXSizFiveSymReg.ttf) normal normal regular normal>
<Font 'DejaVu Serif' (DejaVuSerif-BoldItalic.ttf) italic normal bold normal>
<Font 'Caladea' (Caladea-Italic.ttf) italic normal 400 normal>
<Font 'PibotoLt' (PibotoLtItalic.ttf) italic normal 400 normal>
<Font 'FreeSans' (FreeSansBoldOblique.ttf) oblique normal bold normal>
<Font 'Lato' (Lato-Hairline.ttf) normal normal 400 normal>
<Font 'Liberation Mono' (LiberationMono-BoldItalic.ttf) italic normal bold normal>
<Font 'Liberation Mono' (LiberationMono-Italic.ttf) italic normal 400 normal>
<Font 'Piboto' (Piboto-BoldItalic.ttf) italic normal bold normal>
<Font 'Carlito' (Carlito-Regular.ttf) normal normal 400 normal>
<Font 'Linux Libertine O' (LinLibertine_R.otf) normal normal 400 normal>
<Font 'Piboto Condensed' (PibotoCondensed-Italic.ttf) italic normal 400 condensed>
<Font 'FreeSerif' (FreeSerifBoldItalic.ttf) italic normal bold normal>
<Font 'Piboto Condensed' (PibotoCondensed-Regular.ttf) normal normal regular condensed>
<Font 'Liberation Sans Narrow' (LiberationSansNarrow-BoldItalic.ttf) italic normal bold condensed>
<Font 'Caladea' (Caladea-Regular.ttf) normal normal 400 normal>
<Font 'FreeMono' (FreeMono.ttf) normal normal 400 normal>
<Font 'Piboto' (Piboto-Italic.ttf) italic normal 400 normal>
<Font 'DejaVu Serif' (DejaVuSerifCondensed.ttf) normal normal 400 condensed>
<Font 'Lato' (Lato-ThinItalic.ttf) italic normal 400 normal>
<Font 'Gentium Basic' (GenBasI.ttf) italic normal 400 normal>
<Font 'Carlito' (Carlito-Italic.ttf) italic normal 400 normal>
<Font 'Lato' (Lato-SemiboldItalic.ttf) italic normal bold normal>
<Font 'DejaVu Sans' (DejaVuSans-ExtraLight.ttf) normal normal light normal>
<Font 'FreeSans' (FreeSans.ttf) normal normal 400 normal>
<Font 'Piboto' (Piboto-Light.ttf) normal normal light normal>
<Font 'Gentium Book Basic' (GenBkBasR.ttf) normal normal book normal>
<Font 'FreeMono' (FreeMonoBold.ttf) normal normal bold normal>
<Font 'FreeSerif' (FreeSerifItalic.ttf) italic normal 400 normal>
<Font 'Linux Libertine O' (LinLibertine_RI.otf) italic normal 400 normal>
<Font 'Lato' (Lato-HairlineItalic.ttf) italic normal 400 normal>
<Font 'Liberation Sans' (LiberationSans-Bold.ttf) normal normal bold normal>
<Font 'Liberation Serif' (LiberationSerif-Italic.ttf) italic normal 400 normal>
<Font 'Lato' (Lato-Regular.ttf) normal normal regular normal>
<Font 'Piboto Condensed' (PibotoCondensed-BoldItalic.ttf) italic normal bold condensed>
<Font 'Liberation Serif' (LiberationSerif-Bold.ttf) normal normal bold normal>
<Font 'Lato' (Lato-Light.ttf) normal normal light normal>
<Font 'Lato' (Lato-Thin.ttf) normal normal 400 normal>
<Font 'Liberation Mono' (LiberationMono-Bold.ttf) normal normal bold normal>
<Font 'DejaVu Sans' (DejaVuSansCondensed-Oblique.ttf) oblique normal 400 condensed>
<Font 'DejaVu Serif' (DejaVuSerifCondensed-BoldItalic.ttf) italic normal bold condensed>
<Font 'FreeSerif' (FreeSerif.ttf) normal normal 400 normal>
<Font 'Caladea' (Caladea-Bold.ttf) normal normal bold normal>
<Font 'Liberation Sans' (LiberationSans-Italic.ttf) italic normal 400 normal>
<Font 'Liberation Sans' (LiberationSans-BoldItalic.ttf) italic normal bold normal>
<Font 'Carlito' (Carlito-Bold.ttf) normal normal bold normal>
<Font 'Lato' (Lato-BlackItalic.ttf) italic normal black normal>
<Font 'Linux Libertine Initials O' (LinLibertine_I.otf) normal normal 400 normal>
<Font 'FreeSans' (FreeSansOblique.ttf) oblique normal 400 normal>
<Font 'Liberation Sans Narrow' (LiberationSansNarrow-Italic.ttf) italic normal 400 condensed>
<Font 'Piboto' (Piboto-Thin.ttf) normal normal 400 normal>
<Font 'DejaVu Serif' (DejaVuSerifCondensed-Italic.ttf) italic normal 400 condensed>
<Font 'OpenSymbol' (opens___.ttf) normal normal 400 normal>
<Font 'Liberation Mono' (LiberationMono-Regular.ttf) normal normal 400 normal>
<Font 'PibotoLt' (PibotoLtBold.ttf) normal normal bold normal>
<Font 'Gentium' (Gentium-R.ttf) normal normal 400 normal>
<Font 'Liberation Sans' (LiberationSans-Regular.ttf) normal normal 400 normal>
<Font 'Lato' (Lato-Italic.ttf) italic normal 400 normal>
<Font 'Lato' (Lato-BoldItalic.ttf) italic normal bold normal>
<Font 'Lato' (Lato-MediumItalic.ttf) italic normal medium normal>
<Font 'Linux Libertine O' (LinLibertine_RB.otf) normal normal bold normal>
<Font 'Gentium Book Basic' (GenBkBasBI.ttf) italic normal bold normal>
<Font 'Gentium' (Gentium-I.ttf) italic normal 400 normal>
<Font 'Lato' (Lato-Heavy.ttf) normal normal heavy normal>
<Font 'Liberation Serif' (LiberationSerif-BoldItalic.ttf) italic normal bold normal>
<Font 'Lato' (Lato-Medium.ttf) normal normal medium normal>
<Font 'Lato' (Lato-LightItalic.ttf) italic normal light normal>
<Font 'FreeSerif' (FreeSerifBold.ttf) normal normal bold normal>
<Font 'Lato' (Lato-HeavyItalic.ttf) italic normal heavy normal>
<Font 'DejaVu Serif' (DejaVuSerifCondensed-Bold.ttf) normal normal bold condensed>
<Font 'Linux Libertine O' (LinLibertine_RBI.otf) italic normal bold normal>
<Font 'GentiumAlt' (GentiumAlt-R.ttf) normal normal 400 normal>
<Font 'Gentium Book Basic' (GenBkBasB.ttf) normal normal bold normal>
<Font 'Liberation Serif' (LiberationSerif-Regular.ttf) normal normal 400 normal>
<Font 'GentiumAlt' (GentiumAlt-I.ttf) italic normal 400 normal>
<Font 'Linux Libertine Mono O' (LinLibertine_M.otf) normal normal 400 normal>
<Font 'Gentium Book Basic' (GenBkBasI.ttf) italic normal book normal>
<Font 'Lato' (Lato-Bold.ttf) normal normal bold normal>
<Font 'Carlito' (Carlito-BoldItalic.ttf) italic normal bold normal>
<Font 'Linux Biolinum O' (LinBiolinum_R.otf) normal normal 400 normal>
<Font 'FreeMono' (FreeMonoOblique.ttf) oblique normal 400 normal>
<Font 'Liberation Sans Narrow' (LiberationSansNarrow-Regular.ttf) normal normal 400 condensed>
<Font 'Linux Libertine O' (LinLibertine_RZ.otf) normal normal bold normal>
<Font 'FreeMono' (FreeMonoBoldOblique.ttf) oblique normal bold normal>
<Font 'PibotoLt' (PibotoLtBoldItalic.ttf) italic normal bold normal>
<Font 'Gentium Basic' (GenBasR.ttf) normal normal 400 normal>
<Font 'DejaVu Sans' (DejaVuSansCondensed-BoldOblique.ttf) oblique normal bold condensed>
<Font 'Noto Mono' (NotoMono-Regular.ttf) normal normal 400 normal>
<Font 'Liberation Sans Narrow' (LiberationSansNarrow-Bold.ttf) normal normal bold condensed>
<Font 'Caladea' (Caladea-BoldItalic.ttf) italic normal bold normal>
<Font 'Lato' (Lato-Semibold.ttf) normal normal bold normal>
<Font 'Piboto' (Piboto-LightItalic.ttf) italic normal light normal>
<Font 'Piboto' (Piboto-Bold.ttf) normal normal bold normal>
<Font 'Linux Biolinum Keyboard O' (LinBiolinum_K.otf) normal normal 400 normal>
<Font 'Linux Biolinum O' (LinBiolinum_RI.otf) italic normal 400 normal>
<Font 'PibotoLt' (PibotoLt-Regular.ttf) normal normal regular normal>
<Font 'DejaVu Sans' (DejaVuSansCondensed.ttf) normal normal 400 condensed>
<Font 'Piboto' (Piboto-Regular.ttf) normal normal regular normal>
<Font 'FreeSans' (FreeSansBold.ttf) normal normal bold normal>
<Font 'DejaVu Math TeX Gyre' (DejaVuMathTeXGyre.ttf) normal normal regular normal>
<Font 'Piboto' (Piboto-ThinItalic.ttf) italic normal 400 normal>
<Font 'Linux Libertine O' (LinLibertine_RZI.otf) italic normal bold normal>
<Font 'DejaVu Sans' (DejaVuSansCondensed-Bold.ttf) normal normal bold condensed>
<Font 'Gentium Basic' (GenBasBI.ttf) italic normal bold normal>
<Font 'Lato' (Lato-Black.ttf) normal normal black normal>
<Font 'Gentium Basic' (GenBasB.ttf) normal normal bold normal>
<Font 'Linux Biolinum O' (LinBiolinum_RB.otf) normal normal bold normal>
<Font 'Linux Libertine Display O' (LinLibertine_DR.otf) normal normal 400 normal>
<Font 'Droid Sans Fallback' (DroidSansFallbackFull.ttf) normal normal 400 normal>
<Font 'Piboto Condensed' (PibotoCondensed-Bold.ttf) normal normal bold condensed>
>>>
可見內建的 ttf 字型中並無中文字型, 必須自己下載中文字型檔, 然後修改 matplotlib 設定檔中的預設字型, 讓它能抓到所下載的中文字型. 這個 matplotlib 設定檔位置可用 matplotlib.matplotlib_fname() 查詢 :
>>> import matplotlib
>>> matplotlib.matplotlib_fname()
'/home/pi/.local/lib/python3.5/site-packages/matplotlib/mpl-data/matplotlibrc'
此設定檔是純文字檔, 可用 vim 或 nano 等開啟編輯. 以下是讓 matplotlib 能顯示中文的作法:
1. 下載微軟正黑體 TTF 字型檔 :
參考下面這篇文章, 作者是以微軟正黑體為例 :
開啟樹莓派瀏覽器, 點下列網址下載微軟正黑體 ttf 字型檔 (msj.ttf, 20.7MB) :
# https://github.com/tony1966/tony1966.github.io/blob/master/test/python/Matplotlib/msj.ttf (按右下角的 Download 鈕)
參考 :
預設會下載到 Downloads 目錄下, Matplotlib 的字型都放在 Python 安裝目錄下的 site-packages/matplotlib/mpl-data/fonts/ttf 子目錄下, 上面利用 matplotlib.matplotlib_fname() 指令已知我樹莓派安裝目錄為 /home/pi/.local/lib/python3.5, 因此要將所下載的正黑體字型檔 msj.ttf 複製或搬移到下列子目錄下 :
/home/pi/.local/lib/python3.5/site-packages/matplotlib/mpl-data/fonts/ttf
指令如下 :
pi@raspberrypi:~ $ mv Downloads/msj.ttf .local/lib/python3.5/site-packages/matplotlib/mpl-data/fonts/ttf/msj.ttf
pi@raspberrypi:~ $ ls -ls .local/lib/python3.5/site-packages/matplotlib/mpl-data/fonts/ttf
總計 27992
28 -rw-r--r-- 1 pi pi 25680 4月 14 2019 cmb10.ttf
24 -rw-r--r-- 1 pi pi 21092 4月 14 2019 cmex10.ttf
32 -rw-r--r-- 1 pi pi 32560 4月 14 2019 cmmi10.ttf
28 -rw-r--r-- 1 pi pi 26348 4月 14 2019 cmr10.ttf
20 -rw-r--r-- 1 pi pi 20376 4月 14 2019 cmss10.ttf
32 -rw-r--r-- 1 pi pi 29396 4月 14 2019 cmsy10.ttf
28 -rw-r--r-- 1 pi pi 28136 4月 14 2019 cmtt10.ttf
628 -rw-r--r-- 1 pi pi 641720 4月 14 2019 DejaVuSans-BoldOblique.ttf
688 -rw-r--r-- 1 pi pi 704128 4月 14 2019 DejaVuSans-Bold.ttf
28 -rw-r--r-- 1 pi pi 25712 4月 14 2019 DejaVuSansDisplay.ttf
248 -rw-r--r-- 1 pi pi 253116 4月 14 2019 DejaVuSansMono-BoldOblique.ttf
324 -rw-r--r-- 1 pi pi 331536 4月 14 2019 DejaVuSansMono-Bold.ttf
248 -rw-r--r-- 1 pi pi 251472 4月 14 2019 DejaVuSansMono-Oblique.ttf
336 -rw-r--r-- 1 pi pi 340240 4月 14 2019 DejaVuSansMono.ttf
620 -rw-r--r-- 1 pi pi 633840 4月 14 2019 DejaVuSans-Oblique.ttf
740 -rw-r--r-- 1 pi pi 756072 4月 14 2019 DejaVuSans.ttf
340 -rw-r--r-- 1 pi pi 347064 4月 14 2019 DejaVuSerif-BoldItalic.ttf
348 -rw-r--r-- 1 pi pi 355692 4月 14 2019 DejaVuSerif-Bold.ttf
16 -rw-r--r-- 1 pi pi 14300 4月 14 2019 DejaVuSerifDisplay.ttf
340 -rw-r--r-- 1 pi pi 345612 4月 14 2019 DejaVuSerif-Italic.ttf
372 -rw-r--r-- 1 pi pi 379740 4月 14 2019 DejaVuSerif.ttf
8 -rw-r--r-- 1 pi pi 4816 4月 14 2019 LICENSE_DEJAVU
8 -rw-r--r-- 1 pi pi 5475 4月 14 2019 LICENSE_STIX
4 -rw-r--r-- 1 pi pi 988 4月 14 2019 local.conf
21160 -rw-r--r-- 1 pi pi 21663376 3月 5 13:10 msj.ttf
180 -rw-r--r-- 1 pi pi 181152 4月 14 2019 STIXGeneralBolIta.ttf
232 -rw-r--r-- 1 pi pi 237360 4月 14 2019 STIXGeneralBol.ttf
172 -rw-r--r-- 1 pi pi 175040 4月 14 2019 STIXGeneralItalic.ttf
440 -rw-r--r-- 1 pi pi 448228 4月 14 2019 STIXGeneral.ttf
44 -rw-r--r-- 1 pi pi 41272 4月 14 2019 STIXNonUniBolIta.ttf
32 -rw-r--r-- 1 pi pi 30512 4月 14 2019 STIXNonUniBol.ttf
48 -rw-r--r-- 1 pi pi 46752 4月 14 2019 STIXNonUniIta.ttf
60 -rw-r--r-- 1 pi pi 59108 4月 14 2019 STIXNonUni.ttf
16 -rw-r--r-- 1 pi pi 13656 4月 14 2019 STIXSizFiveSymReg.ttf
12 -rw-r--r-- 1 pi pi 12228 4月 14 2019 STIXSizFourSymBol.ttf
16 -rw-r--r-- 1 pi pi 15972 4月 14 2019 STIXSizFourSymReg.ttf
16 -rw-r--r-- 1 pi pi 12556 4月 14 2019 STIXSizOneSymBol.ttf
20 -rw-r--r-- 1 pi pi 19760 4月 14 2019 STIXSizOneSymReg.ttf
12 -rw-r--r-- 1 pi pi 12192 4月 14 2019 STIXSizThreeSymBol.ttf
16 -rw-r--r-- 1 pi pi 15836 4月 14 2019 STIXSizThreeSymReg.ttf
12 -rw-r--r-- 1 pi pi 12116 4月 14 2019 STIXSizTwoSymBol.ttf
16 -rw-r--r-- 1 pi pi 15704 4月 14 2019 STIXSizTwoSymReg.ttf
可見 msj.ttf 已放進 ttf 子目錄了.
2. 編輯 matplotlib 字型設定檔 :
使用 nano 編輯 matplotlib 設定檔 :
pi@raspberrypi:~ $ nano .local/lib/python3.5/site-packages/matplotlib/mpl-data/matplotlibrc
找到 '#font.family: sans-serif' 這一列, 把 font.family 前面的 # 刪除, 再往下一點找到 '#font.serif :' 這一列, 同樣是把前面的 # 刪除, 而且在冒號後面添加 'Microsoft JhengHei,' :
改好後按 Ctrl+O, 再按 Ctrl+X 存檔後跳出 nano.
3. 刪除 matplotlib 快取檔 (cache) :
快取目錄位於 home 的 .cache 資料夾下, 必須用 rm -rf 指令刪除其中的 matplotlib 快取資料夾, 因為快取中存放的是之前純英文的字型, 如果不刪除的話, 執行 Matplotlib 繪圖程式時會直接去抓原本的快取, 必須刪除讓它重新建立快取才能抓到新增的中文字型檔 :
pi@raspberrypi:~ $ ls -ls .cache
總計 28
4 drwx------ 3 pi pi 4096 4月 5 2019 chromium
4 drwxr-xr-x 2 pi pi 4096 4月 5 2019 fontconfig
4 drwxr-xr-x 3 pi pi 4096 11月 13 2018 lxsession
4 drwxr-xr-x 3 pi pi 4096 3月 5 08:01 matplotlib
4 drwx------ 2 pi pi 4096 3月 5 17:17 menus
4 drwxr-xr-x 3 pi pi 4096 3月 5 17:17 openbox
4 drwx------ 4 pi pi 4096 4月 5 2019 pip
pi@raspberrypi:~/.cache $ rm -rf .cache/matplotlib
經過上面三道程序後, 只要在程式中用 plt.rcParams() 指定微軟正黑體就可以在 Matplotlib 繪製的圖形中顯示中文了, 例如 :
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"]=["Microsoft JhengHei"] # 使用微軟正黑體
week=['日','一','二','三','四','五','六']
temperature=[25.4, 23.7, 28.6, 29.2, 24.8, 22.5, 21.9]
plt.plot(week, temperature)
plt.title('溫度變化圖')
plt.xlabel('星期')
plt.ylabel('攝氏')
plt.show()
注意, 也可以用 plt.rcParams["font.family"]=["Microsoft JhengHei"], 結果如下 :
Bingo! 終於搞定了, 以後我的自動機就能用 matplotlib 產生含有中文的圖形了.
沒有留言:
張貼留言