作者:燕清,老齊
與本文相關的圖書推薦:《跟老齊學Python:數據分析》
AI Studio是一個非常好用的數據科學在線實驗平臺,不論是教學、學習還是開發,都可以使用。但是,下面的缺憾未免成為了珍珠上的一點瑕疵。
%matplotlib inline
import matplotlib.pyplot as plt
labels = ['娛樂','育兒','飲食','房貸','交通','其它']
sizes = [2,5,12,70,2,9]
explode = (0,0,0,0.1,0,0)
plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=False, startangle=150)
plt.title("餅圖示例-8月份家庭支出")輸出結果:
在繪製這個餅圖的時候,我們在標題以及餅圖不同區域的標籤設置了中文,但是現實效果不能令人滿意,沒有顯示相應的漢字。很多人遇到過這種問題,一種常見解決之道就是「繞著走」,將中文換成英文,乃至於在某些官方的案例中也是如此。
專業的開發者天生就是「以解決難題為榮」的,這個難題必須要破解。
如果在網上搜索Matplotlib顯示漢字的問題,會有好多種方法,但是那些方法都是針對本地作業系統的,而非針對Ai Studio這樣的遠程系統——雖然也是Ubuntu作業系統,但是由於每個人使用的是一個虛擬環境,在權限、路徑等方面與本地作業系統還是有所差別的。
查看已有字體在開始解決問題之前,先對當前我們使用的虛擬作業系統以及它已有字體有所了解。
!cat /etc/*-release輸出:
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.3 LTS"
NAME="Ubuntu"
VERSION="16.04.3 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.3 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial從上述結果,我們了解到,現在所使用的Ai Studio是Ubuntu作業系統。因此,各種Linux命令就可以放心使用了。
首先看一看系統自帶的字體。
# Linux系統默認字體文件路徑
!ls /usr/share/fonts/輸出:
cmap truetype type1 X11顯然作業系統默認有一些字體,但這些字體中有多少是支持顯示漢字的呢?還要繼續查看:
# 查看系統可用的ttf格式中文字體
!fc-list :lang=zh | grep ".ttf"沒有任何查詢結果,說明系統默認字體中沒有支持漢字的ttf格式字體。
熟悉Matplotlib的朋友可能會想到,也應該看看Matplotlib庫的字體目錄,或者將支持漢字的字體放到該目錄中。
Ai Studio雖然是Ubuntu作業系統,但又不完全等同於本地的Ubuntu系統,Python第三方庫的安裝位置與本地計算機中的位置不同。
import matplotlib
matplotlib.__path__輸出:
['/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib']以上的輸出結果:/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib,就是matplotlib的存儲路徑,或者說,所有第三方包都會被安裝到/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/裡面。
那麼,Matplotlib保存字體的路徑就應該是/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf,可以查看其中的字體:
# matplotlib字體路徑(aistudio)
!ls /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf輸出:
cmb10.ttf DejaVuSerif.ttf
cmex10.ttf LICENSE_STIX
cmmi10.ttf STIXGeneralBolIta.ttf
cmr10.ttf STIXGeneralBol.ttf
cmss10.ttf STIXGeneralItalic.ttf
cmsy10.ttf STIXGeneral.ttf
cmtt10.ttf STIXNonUniBolIta.ttf
DejaVuSans-BoldOblique.ttf STIXNonUniBol.ttf
DejaVuSans-Bold.ttf STIXNonUniIta.ttf
DejaVuSansDisplay.ttf STIXNonUni.ttf
DejaVuSansMono-BoldOblique.ttf STIXSizFiveSymReg.ttf
DejaVuSansMono-Bold.ttf STIXSizFourSymBol.ttf
DejaVuSansMono-Oblique.ttf STIXSizFourSymReg.ttf
DejaVuSansMono.ttf STIXSizOneSymBol.ttf
DejaVuSans-Oblique.ttf STIXSizOneSymReg.ttf
DejaVuSans.ttf STIXSizThreeSymBol.ttf
DejaVuSerif-BoldItalic.ttf STIXSizThreeSymReg.ttf
DejaVuSerif-Bold.ttf STIXSizTwoSymBol.ttf
DejaVuSerifDisplay.ttf STIXSizTwoSymReg.ttf
DejaVuSerif-Italic.ttf查看上面的顯示結果,會發現,的確沒有支持漢字顯示的字體,所以,前面可視化結果中不能顯示漢字是很正常的。
按照在本地計算機上設置漢字顯示的思維方法,將支持漢字顯示的字體放到上述目錄中,並修改相應的配置文件matplotlibrc,是否可以?如果讀者有興趣,可以嘗試。這裡只說明結果:無法解決本文的問題。
下載字體既然系統默認沒有支持漢字的字體,就不得不下載了。注意,不是下載到你所使用的本地計算機,而是下載到當前Ai Studio給我們提供的虛擬作業系統上。
# 下載中文字體
!wget https://mydueros.cdn.bcebos.com/font/simhei.ttf輸出:
--2020-04-10 15:44:35-- https://mydueros.cdn.bcebos.com/font/simhei.ttf
Resolving mydueros.cdn.bcebos.com (mydueros.cdn.bcebos.com)... 182.61.128.198
Connecting to mydueros.cdn.bcebos.com (mydueros.cdn.bcebos.com)|182.61.128.198|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 9753388 (9.3M) [application/octet-stream]
Saving to: 『simhei.ttf.1』
simhei.ttf.1 100%[===================>] 9.30M 54.7MB/s in 0.2s
2020-04-10 15:44:35 (54.7 MB/s) - 『simhei.ttf.1』 saved [9753388/9753388]字體下載之後,會保存到當前項目的永久文件夾中。點擊界面左側的「文件夾」,可以看到剛剛下載的字體文件simhei.ttf,再用下面的方式得到這個字體的名稱。
# 查看字體的引用名
import matplotlib.font_manager as font_manager
fontpath = 'simhei.ttf'
prop = font_manager.FontProperties(fname=fontpath)
print(prop.get_name())輸出:
SimHei從上述返回結果可知,下載的字體文件simhei.ttf,在Matplotlib中,所引用的字體名稱是SimHei。
第一種方法這是一種非常靈活的方法,可以根據需要對所繪製圖像設置不同的字體。
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname='simhei.ttf', size=16) # 創建字體對象
labels = ['娛樂','育兒','飲食','房貸','交通','其它']
sizes = [2,5,12,70,2,9]
explode = (0,0,0,0.1,0,0)
plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=False, startangle=150, textprops={'fontproperties':font})
plt.title("餅圖示例-8月份家庭支出", fontproperties=font)輸出:
觀察上述圖示,標題和餅圖的各個分區的標示都顯示中文了。
在plt.pie和plt.title中,都是用了參數'fontproperties',這個參數是matplotlib的文本參數之一(查看:Text properties and layout:https://matplotlib.org/3.1.1/tutorials/text/text_props.html),其值是FontProperties類的實例,即前面所創建的字體對象。
如此解決了當前圖示中漢字顯示問題。
第二種方法第一種方法定製性比較強,在一個項目中,可以給不同圖示配置不同的字體。如果不需要如此,也可以用這裡介紹的第二種方法,一個項目中所有可視化的圖示都用同一種漢字字體。
在創建共本項目應用的字體目錄fonts,並把所下載的字體放到該目錄中。
#創建字體目錄fonts
!mkdir .fonts
# 複製字體文件到該路徑
!cp simhei.ttf .fonts/上面的操作完成之後,一定要執行下面的操作:
重啟環境,即用滑鼠點擊本項目瀏覽器中的下圖所示圖標:
這步完成之後,執行下面的代碼,就實現了漢字的顯示。
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
# 設置顯示中文
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 指定默認字體
matplotlib.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負號'-'顯示為方塊的問題
labels = ['娛樂','育兒','飲食','房貸','交通','其它']
sizes = [2,5,12,70,2,9]
explode = (0,0,0,0.1,0,0)
plt.pie(sizes,explode=explode,labels=labels,autopct='%1.1f%%',shadow=False,startangle=150)
plt.title("餅圖示例-8月份家庭支出")輸出:
以上技巧,發布出來,供大家參考。
★搜索技術問答的公眾號:老齊教室
」★在公眾號中回覆:老齊,可查看所有文章、書籍、課程。
」覺得好看,就點這裡👇👇👇