2025/06/26

matplotlib 畫圖中文字變方框怎麼辦?

在 Python 程式裡常會用 matplotlib 畫圖,但很困擾的是中文都會變成方框框。

matplotlib 畫的圖中文字變方框框
圖、matplotlib 畫的圖中文字變方框框

這是因為 matplotlib 預設字體是 DejaVu Sans,所以無法顯示中文。既然是預設字體的問題,那我們就改一下字型。要改用字型顯示也不難,只要在畫圖指令前用 rcParams 指定中文字體即可。

import matplotlib.pyplot as plt
    
# 指定字型為 SimHei
plt.rcParams['font.family'] = ['SimHei']

# 這招在 google colab 行不通
# google colab 要用蔡炎龍老師提供的方法

指定中文字型後,matplotlib 就可以正確的顯示中文了。

指定字型後 matplotlib 中文顯示正常
圖、指定字型後 matplotlib 中文顯示正常

不過我們不滿足,希望除了 SimHei 字型外,還能使用更多自己喜歡的字體,要怎麼辦?

嗯,這就要看你想在哪個平台的 matplotlib 顯示中文了,方法都不太一樣。

  • Excel
  • Anaconda Jupyter Notebook
  • Google Colab

Excel

如果是想要在 Microsoft Excel 裡用 matplotlib 畫圖,還希望有多種中文字型可以使用,這個願望短時間內似乎無解。用底下的程式碼跑一下就知道,Excel 裡的 matplotlib 能用的字體不多:

from matplotlib import pyplot as plt
from matplotlib import font_manager as fm

a=sorted([font.name for font in fm.fontManager.ttflist])

for i in a:
    print(i)

Excel 裡的 matplotlib 能用的字體不多
圖、Excel 裡的 matplotlib 能用的字體不多

從顯示結果來看,能用的就 MingLiU(細明體)、SimHei(黑體)、SimSun(宋體) 3 個。Meiryo(日文黑體) 與 Batang(韓文明體) 雖然也能用,但會缺字,所以真正能用的就 3 個字體

你可能會想:『我才不信!網路上應該有教怎麼做吧?』

嗯,我試了很多方法了,怎麼樣都無效。直到我查看 matplotlib 的快取資料夾:

import matplotlib
matplotlib.get_cachedir()

『嗯?快取資料夾在 "/home/jovyan" 下?我的電腦沒這個使用者啊?』

快取資料夾在 /home/jovyan 下
圖、快取資料夾在 /home/jovyan 下

怪了!那我現在檔案所在位置呢?

import os

current_directory = os.getcwd()
print(f"當前資料夾路徑: {current_directory}")

當前資料夾在 "/mnt/file_upload",也是不存在的路徑。

檔案所在資料夾實際上不存在
圖、檔案所在資料夾實際上不存在

為什麼檔案所在位置會是一個不存在的資料夾呢?該不會是放在一個容器內吧?查了一下微軟文章,還真的是:

  • Python code runs within the compliance boundary of your organization on hypervisor isolated containers.
  • The Python code doesn't have access to your computer, devices, or account.
  • The Python code doesn't have network access.

既然 Excel 中的 Python 是在一個隔離的容器內執行,無法存取電腦裡的資料也無法接觸網路,那就無法修改它的設定,只能用它目前提供的字體,等哪天微軟把更多字體放入容器內才能使用更多字型了。

另外,因為 Excel 版的 Python 是在容器內執行的,所以要程式自己將 matplotlib 畫的圖存下來 plt.savefig('clean_plot.png', dpi=300) 也就不可行了,因為存到容器裡我們根本看不到。

在 Excel 的 matplotlib 用更多字型不可行,我們看看 Jupyter 的 Notebook 吧。

Anaconda Jupyter 的 Notebook

要在 Anaconda 的 Jupyter 的 Notebook 用更多中文字型,其實不需要修改 matplotlibrc 這個檔案

無論是 C:\Users\使用者\anaconda3\Lib\site-packages\matplotlib\mpl-data\ 下的 matplotlibrc 或是 C:\Users\使用者\.matplotlib 下的 matplotlibrc 都不用改。只要掃一下目前有哪些字型能使用,然後抓一個能用的字型就可以了。

from matplotlib import pyplot as plt
from matplotlib import font_manager as fm

a=sorted([font.name for font in fm.fontManager.ttflist])

for i in a:
    print(i)

matplotlib 可用系統中安裝的字體
圖、matplotlib 可用系統中安裝的字體

看到列出的清單知道有哪些字體後,直接輸入字型名稱就可以了。比方說我想要使用源泉圓體,直接輸入 "GenSenMaruGothic TW TTF" 就行。

使用源泉圓體顯示中文
圖、使用源泉圓體顯示中文

Matplotlib 能用的字體列表存在 C:\Users\使用者\.matplotlib\ 資料夾下的 fontlist-v390.json 裡,該檔案會詳細記錄每個字體存在哪個路徑,不會抓錯字體。像源泉圓體就安裝在我個人資料夾下,而不是安裝在 C:\Windows\Fonts\ 裡。

fontlist-v390.json 檔詳細記錄每個字型所在位置
圖、fontlist-v390.json 檔詳細記錄每個字型所在位置

fontlist-v390.json 這個檔如果誤刪了也不用緊張,重新掃一次系統裡有哪些字體,這個檔案就又自動生成了。比方說,現在我的 C:\Users\使用者\.matplotlib\ 資料夾裡是空的:

C:\Users\使用者\.matplotlib\ 資料夾裡無檔案
圖、C:\Users\使用者\.matplotlib\ 資料夾裡無檔案

在 Jupyter 裡重啟 kernel 再重新執行掃字型的程式:

from matplotlib import pyplot as plt
from matplotlib import font_manager as fm

a=sorted([font.name for font in fm.fontManager.ttflist])

for i in a:
    print(i)

資料夾裡已經立即生成一個新的 fontlist-v390.json 檔了。

即時生成新的 fontlist-v390.json
圖、即時生成新的 fontlist-v390.json

記得要在 Jupyter 裡重啟 kernel 再執行程式才會生成檔案喔,否則它會抓記憶體裡的資料,不會生成檔案。

你可以看到,在 C:\Users\使用者\.matplotlib\ 這個資料夾裡就只有 fontlist-v390.json 這一個檔案,沒有 matplotlibrc,所以你其實不需要修改 matplotlibrc 這個檔,可能是 matplotlib 的設定已經改了吧?網路上的資料已經不適用了。

Colab 中讓 matplotlib 使用中文

政大蔡炎龍教授已經有教怎麼在 matplotlib 中使用中文,我就不再說了,大家直接看蔡教授的教學吧。

蔡炎龍教授教你怎麼上傳中文字型到 colab
圖、蔡炎龍教授教你怎麼上傳中文字型到 colab

為什麼有這一篇教學

其實是昨天想要在 Excel 裡用比較好看的字體呈現數據圖的標題,但找了很久都找不到方法。最後猜測Excel 是不是把 Python 關在容器裡?這麼想之後就在微軟官網找到資料,確定 Excel 裡的 Python 是在容器裡面執行的,要改字體基本上不可能,我昨天浪費了好多時間。

接著想想,哇,Python 的執行方式除了系統中執行 (包含系統裡加容器)、colab 執行,現在還多了一個在 Excel 裡用容器執行,每種環境要用中文的方法都不太一樣,所以還是寫一篇文章記錄一下好了,以免之後忘記。

寫下來才能記得。

沒有留言:

張貼留言