2020年2月27日 星期四

Python, Matplotlib, 中文字體顯示的問題

雖然網路上有許多篇文章探討,不過最近再碰到這個問題的時候,仍舊看得有點似懂非懂的。

這裡綜合整理一下個人的看法,並且添上一些說明。

關於中文字體的顯示這是新手關卡,幾乎會碰到也幾乎需要解決。

要解決這個問題,首先可對兩個地方進行改善。

一、 系統磁碟:\\使用者\使用者名稱\.matplotlib
二、python環境\Lib\site-packages\matplotlib\mpl-data (如果使用anaconda,環境就是anaconda的資料夾。如果使用visual studio,可以從python環境打開檔案管理員進入資料夾。)


【如果你想增加字體,一定要做的步驟】

首先第一個地方,進入後會發現一個 fontList.json 的檔案,簡單來說,就是 matplotlib 讀取字體的紀錄。如果想要加入新的字體在 matplotlib 的繪圖中顯示,就得刪除  fontList.json ,讓 matplotlib 重新讀取並生成新的 json。萬一沒有刪,這個檔案就不會變更,新增的字體就不會被讀取到。(如果刪了matplotlib的字體,該json檔也會被變更。)

想顯示中文字,也不一定要新增中文字體,你可以用記事本打開來看,其中有一行「"C:\\WINDOWS\\Fonts\\kaiu.ttf",」這表示它讀取到系統字形的 kaiu.ttf,也就是知名的「標楷體」,於是在程式中只要指定字體為標楷體,就可以正常顯示中文。

plt.rcParams['font.sans-serif'] = ['DFKai-SB'] #可以直接用上此行顯示中文字,如果不嫌棄標楷體的話

""" 一定要使用「字體名稱」,不是字檔名kaiu。可以從新生的 json 檔搜尋字檔名(如: kaiu.ttf),會看到有一項 "name": "DFKai-SB",其餘字體也可以找到對應的name。"""


【新增字體】

從第二地方 mpl-data 進入 fonts 再進入 ttf 資料夾,這裡可以丟上你喜歡的字體,從網路上下載的也行。

假設我有一個喜歡的字型,範例字型,把它的 ttf 檔放進來後,去第一地方刪除 fontList.json 然後重載(import matplotlib),然後打開 json 搜尋字檔名 I.Ngaan.ttf ,就會找到該字體的 "name": "I.Ngaan"。

plt.rcParams['font.sans-serif'] = ['I.Ngaan']

這樣就能讓 matplotlib 以這個字體顯示。


【一勞永逸,懶得在程式裡加上那一行】

第二地方有個名為 matplotlibrc 的檔案,可用記事本打開它。搜尋「font.sans-serif」,把字體名,注意!是字體名!要怎麼得知字體名?可由【新增字體】這一部分去了解。在該行的冒號後面加入字體名(範例: I.Ngaan, 或是 DFKai-SB,),然後刪除前方註解(#)。

font.sans-serif     : I.Ngaan,  DFKai-SB,  DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif

至於其他很像的「font.cursive」或是「font.fantasy」,從這裡可以了解他們的意思。

!!接著這裡也可以順便解決另外一個常見的matplotlib的問題「負號無法正常顯示」。

找到解決方法通常是加上一句:
plt.rcParams['axes.unicode_minus']=False

在這個 matplotlibrc 的檔案中,搜尋「axes.unicode_minus」可以找到一句
#axes.unicode_minus  : True

將其改成
axes.unicode_minus  : False

就可以一次解決負號顯示的問題。


會特別紀錄這篇,是因為字體名的關係,網路上有教學如何添加字體,給了範例,卻沒有說為什麼字體名是這個。於是我嘗試用['標楷體']卻失敗,用字檔名['kaiu']也失敗,可是,一定得有一個可以找到對照的地方,搜尋方法,最後從json檔找到答案,。
這些方法與說明是目前我在網路沒有找到的,也許日後還會碰到這問題,到時來到在這裡就能找到解答。
個人是不推薦第三種一勞永逸的解法,因為換台電腦就要再去改寫,實在麻煩。所以推薦使用 ['DFKai-SB'] (標楷體),因為對繁體中文的系統都會自帶這個字體,這樣就不需要額外再改動任何檔案。

群益API,PYTHON,錯誤代碼2017

按下登入,得到錯誤代碼2017,查表之後得到解釋:

「SK_WARNING_REGISTER_REPLYLIB_ONREPLYMESSAGE_FIRST」

這邊是給無法順利從其他正規解決方法的人,一個解法。即便順利回報OnReplyMessage,用範例都會得到錯誤代碼2017的替代方案

使用舊版的SKCOM.dll(64位元)。下載連結

印象中這是去年我找到的方法,不過今年卻找不到出處,於是在此紀錄。因為今天剛好又再一次碰到。

以下是替換成舊版的SKCOM.dll的步驟:

一、按照群益API說明,從解壓縮後資料夾中元件裡的Uninstall.bat,解除註冊COM元件。
(依照自己的電腦位元版本選擇x86或是x64)

二、將下載來的舊版SKCOM.dll複製過去,替換同資料夾的SKCOM.dll。

三、按照正常的註冊流程,重新註冊元件:
1.用系統管理員身分執行 cmd ,進入到舊版SKCOM.dll所在的資料夾(cd 資料夾路徑),然後輸入「regsvr32.exe SKCOM.dll」。
2.用系統管理員身分執行 install.bat 。

群益API可以下載新版的,只要裡面的SKCOM.dll替換成舊版的就可以,不一定要找到舊的API才能執行。

這招大概只能撐到舊版不被支援的那一天,姑且就先將就吧。