畫出這張官方神圖,你的Matplotlib就畢業(yè)了!

大家好,我是早起。
在昨天的文章人人都能看懂的Matplotlib繪圖原理中,我們對Matplotlib的繪圖機(jī)制進(jìn)行了講解,在弄清楚plt.xxxx和ax.xxxx中plt和ax區(qū)別之后,本文繼續(xù)講解xxxx究竟是什么。
現(xiàn)在我們應(yīng)該知道Matplotlib繪圖其實(shí)很簡單,不就是弄一塊畫布,然后往這塊畫布上添加我們要的圖形,最后就是進(jìn)行修飾。
如何添加畫布/繪圖區(qū)域已經(jīng)講過,如何添加圖形,看我發(fā)的各種可視化圖鑒就行了,而最需要花時(shí)間的就是對初步成型的圖案進(jìn)行修飾,先來看一張來自官方文檔的圖
我們可以看到,其實(shí)無非就是設(shè)置標(biāo)題、圖例、坐標(biāo)軸、標(biāo)記點(diǎn)等操作,這部分看起來簡單,不過有時(shí)因?yàn)閿?shù)據(jù)的原因,想要調(diào)整到一個(gè)合適的樣式,是需要花費(fèi)心思的。
但不論如何,能用到的Matplotlib修飾操作就這么多,本文將按照上圖的順序帶大家手把手的繪制出圖中的每一部分,希望以這種方式對常用的修飾語法進(jìn)行講解!
如果你能獨(dú)立的,簡單思考查詢后能將這張圖畫出來,那么matplotlib基本就算畢業(yè)了!
請注意,由于篇幅原因,本文對大多數(shù)方法僅作簡單介紹,因此并不適合作為速查手冊使用,詳細(xì)的matplotlib各組件設(shè)置,點(diǎn)擊菜單欄查看專題文章。
標(biāo)題
首先是標(biāo)題,如果是使用plt.xxxx那么就用plt.title(),如果使用ax.xxxx可以使用ax.set_title(),現(xiàn)在我們把標(biāo)題做成官方文檔的樣式,更多標(biāo)題的修改方法可以查看matplotlib標(biāo)題設(shè)置
plt.rc('font',family='Avenir')?
plt.figure(figsize?=?(8,7),?dpi=100)
plt.title("Anacomy?of?a?figure",fontsize?=?20,fontweight='heavy')
plt.show()

刻度
搞定了標(biāo)題,下一步就是刻度了,根據(jù)我的了解,因?yàn)樽约旱臄?shù)據(jù)原因,大多需要對刻度進(jìn)行調(diào)整,但是修改刻度,相對復(fù)雜一點(diǎn),所以很多人多會(huì)卡在刻度設(shè)置上。
其實(shí)設(shè)置刻度確實(shí)體育達(dá)標(biāo)復(fù)雜,從圖中我們可以看到又分為主、副刻度,再算上xy軸,一共就是4個(gè)刻度需要設(shè)置。
因?yàn)楸容^復(fù)雜,所以建議使用ax.xxxx進(jìn)行設(shè)置。這里我們首先需要把刻度讀取出來,先使用的語法為
ax?=?plt.gca()
意思是Get Current Axes,獲得當(dāng)前繪圖區(qū)域,接下來使用ax.set_xlim設(shè)置x坐標(biāo)軸范圍,等同于plt.xlim(),y軸同理
ax.set_xlim(0,4)
ax.set_ylim(0,4)
現(xiàn)在坐標(biāo)軸范圍搞定了,接下來就是比較復(fù)雜的刻度調(diào)整,我們可以看到,從官方示例圖中,我們可以發(fā)現(xiàn)在matplotlib中,一個(gè)坐標(biāo)軸,分為主副兩個(gè)刻度。
關(guān)于坐標(biāo)軸刻度的設(shè)置詳情,可以參考matplotlib刻度設(shè)置文章,我們先來設(shè)置x、y軸的主刻度,只需要將間隔調(diào)整為1即可,通過修改locator類完成
xmajorLocator???=?MultipleLocator(1)
ax.xaxis.set_major_locator(xmajorLocator)
ymajorLocator???=?MultipleLocator(1)
ax.yaxis.set_major_locator(ymajorLocator)

主刻度的調(diào)整就完成了,接下來是副刻度的調(diào)整,我們需要將x軸副刻度以0.25為單位分開,并顯示數(shù)值,y軸副刻度同樣為0.25但是不顯示數(shù)值,以x軸為例,調(diào)整副刻度及數(shù)值顯示可以通過·ax.xaxis.set_minor_formatter和ax.yaxis.set_minor_locator`實(shí)現(xiàn)
xminorLocator???=?MultipleLocator(0.25)
ax.xaxis.set_minor_locator(xminorLocator)
yminorLocator???=?MultipleLocator(0.25)
ax.yaxis.set_minor_locator(yminorLocator)
xminorFormatter?=?FormatStrFormatter('%0.2f')
ax.xaxis.set_minor_formatter(xminorFormatter)

可以看打,現(xiàn)在的主副刻度已經(jīng)做的差不多了,但是官方示例圖中的刻度線更長一點(diǎn),對刻度線進(jìn)行調(diào)整可以使用tick_params
tick_params(which='major',length=8)
tick_params(which='minor',length=4)

網(wǎng)格線
刻度線搞定之后,下一步添加網(wǎng)格線,我們可以使用ax.xaxis.grid和ax.yaxis.grid分別對指定x軸和y軸的網(wǎng)格線,可選參數(shù)非常多,詳見matplotlib網(wǎng)格線設(shè)置
在這里,我們按照官方示例圖的樣式,兩個(gè)坐標(biāo)軸都添加主刻度網(wǎng)格線,并使用,linestyle = (0,(10,5))對線性進(jìn)一步調(diào)整
ax.xaxis.grid(True,?which='major',linestyle?=?(0,(8,4)))?
ax.yaxis.grid(True,?which='major',linestyle?=?(0,(8,4)))?
現(xiàn)在看我們的圖是不是和示例圖有幾分相似了呢??
坐標(biāo)軸文字
現(xiàn)在繼續(xù)給坐標(biāo)軸添加文字,這部分就比較簡單了,當(dāng)然我也寫了詳細(xì)的文檔,這里使用ax.set_xlabel或者plt.xlabel都可以,我們使用如下代碼
ax.set_xlabel("X?axis?label",fontsize?=?12)
ax.set_ylabel("Y?axis?label",fontsize?=?12)

添加圖像
現(xiàn)在對于畫布的修飾部分,基本就結(jié)束了,下面添加圖形,示例圖中一共有兩個(gè)折線圖和一個(gè)散點(diǎn)圖,我們擬合部分?jǐn)?shù)據(jù)并制作進(jìn)行,這里使用ax.plot和ax.scatter分別制作折線圖和散點(diǎn)圖,不知道怎么畫的可以看我之前發(fā)的各種圖鑒
x?=?list(np.arange(0.5,3.3,0.1))
y1?=?[-0.04658*i**3+0.5494*i**2-1.3151*i?+?1.415?for?i?in?x]
ax.plot(x,y1,color?=?'red',alpha?=?0.7,?linewidth=2.3)
x?=?list(np.arange(0.5,3.5,0.1))
y2?=?[0.1545*i**3-0.799*i**2+0.4316*i?+?3.744?for?i?in?x]
ax.plot(x,y2,color?=?'blue',alpha?=?0.7,?linewidth=2.3)
ax.scatter(A,?B,marker?=?'o',color="w",edgecolors='black')

現(xiàn)在,是不是感覺非常相似了!我們繼續(xù)。
添加圖例
整體還差最后一個(gè)圖例就完成了,添加圖例比較簡單,使用plt.legend()或者ax.legend()都可以實(shí)現(xiàn),不過需要在繪圖是添加label標(biāo)簽才行
添加文字
其實(shí)圖像主體部分已經(jīng)完成了,但是原來的示例圖中還有一些藍(lán)色的文字,我們也添加進(jìn)來,其實(shí)用到的就是plt.text(),也是非常常見的一個(gè)用法,我在matplotlib添加注釋中有詳細(xì)講解,本文這里就是根據(jù)坐標(biāo)添加文字,部分代碼如下
ax.text(2.9,2.7,"Gird",family?=?"DejaVu?Sans",fontsize?=?11,color?=?'blue',weight='heavy')
ax.text(3.45,3.45,"Legend",family?=?"DejaVu?Sans",fontsize?=?10,color?=?'blue',weight='heavy')
ax.text(1.5,3.85,"Title",family?=?"DejaVu?Sans",fontsize?=?11,color?=?'blue',weight='heavy')
ax.text(-0.25,3.75,"Major?tick",family?=?"DejaVu?Sans",fontsize?=?10,color?=?'blue',weight='heavy')
ax.text(-0.25,3.25,"Minor?tick",family?=?"DejaVu?Sans",fontsize?=?10,color?=?'blue',weight='heavy')
ax.text(-0.45,2.75,"Major?tick?label",family?=?"DejaVu?Sans",fontsize?=?10,color?=?'blue',weight='heavy')
ax.text(0.12,-0.5,"Minor?tick?label",family?=?"DejaVu?Sans",fontsize?=?10,color?=?'blue',weight='heavy')

其中箭頭是通過ax.arrow做出來的,使用方法和ax.text一樣通過調(diào)整坐標(biāo)控制
ax.arrow(3.3,0.41,-0.15,-0.33,ec='blue',head_width=0.04)
ax.arrow(3.6,0.41,0.32,-0.15,ec='blue',head_width=0.04)
現(xiàn)在我們的畫的圖和官方文檔的示例圖已經(jīng)差不多一樣了,唯一就是差了在不同組件旁的類似放大鏡效果的圖片。
添加自定義圖片
最后,讓我們和官方文檔一樣,在注釋的位置添加指定圖片,來達(dá)到一種放大的感覺。
在Matplotlib中,添加圖片的方法有多種,這里我們選擇使用ax.add_artist(),詳細(xì)講解在后續(xù)文章中更新,簡單來說就是打開一張圖片,之后根據(jù)坐標(biāo)添加到我們想要的位置就行了。
以左上角Major tick的圓為例,我們使用OffsetImage打開一張圖片
arr_lena?=?mpimg.imread('/Users/liuhuanshuo/Desktop/WechatIMG2278.png')
imagebox?=?OffsetImage(arr_lena,?zoom=0.38)
之后使用a1 = AnnotationBbox(imagebox, (0, 4), frameon = False)設(shè)置圖片位置,最后使用ax.add_artist(a1)就能添加一個(gè)空心圓在左上角,之后如法炮制就可以了。
最終我們制作的仿官方文檔效果圖如下
是不是可以以假亂真呢,感興趣的讀者可以自己嘗試?yán)L制一下。長按掃描下方二維碼關(guān)注「可視化圖鑒」在后臺回復(fù)0117可以獲得我使用Notebook進(jìn)行學(xué)習(xí)、復(fù)現(xiàn)。
最后早起想說一下,其實(shí)這篇文檔本來的標(biāo)題是「一篇文章帶你搞定Matplotlib中組件設(shè)置」,后來寫著寫著,發(fā)現(xiàn)一篇文章根本搞不定,可能光一個(gè)plt.tltle()就有很多可以說道的,所以我就希望通過繪制官方示例圖,帶大家了解Matplotlib中繪圖的基本流程和常見方法使用。
當(dāng)然每一個(gè)組件設(shè)置,我都寫了詳細(xì)的文檔指導(dǎo)你修改,所以如果你對文章任何一個(gè)部分感興趣,都可以查看對應(yīng)設(shè)置的文章來進(jìn)一步學(xué)習(xí)!
最后推薦一本數(shù)據(jù)可視化的書,R語言數(shù)據(jù)分析與可視化從入門到精通,本書是關(guān)于R語言數(shù)據(jù)分析與可視化從入門到精通的指南,較為全面地介紹了R語言的常用功能和方法,且緊密圍繞實(shí)際應(yīng)用展開。例如,從R語言的發(fā)展歷史到R語言的一些常用函數(shù),從數(shù)據(jù)管理到數(shù)據(jù)分析,從基礎(chǔ)統(tǒng)計(jì)到高級統(tǒng)計(jì),從圖形生成到圖形優(yōu)化,從分步應(yīng)用到綜合應(yīng)用等。通過本書,讀者可以掌握R語言的基本功能和原理,并進(jìn)一步深入學(xué)習(xí)更多的相關(guān)知識。
“為了回饋粉絲,早起也送幾本給大家。
點(diǎn)擊閱讀原文,關(guān)注公眾號「可視化圖鑒」,按照文中規(guī)則進(jìn)行留言,即有機(jī)會(huì)包郵獲贈(zèng)圖書!
”
