Matpotlib绘图遇到时间刻度就犯难?现在,一次性告诉你四种方法
公眾號(hào)后臺(tái)回復(fù)“圖書“,了解更多號(hào)主新書內(nèi)容
作者:寧海濤
來(lái)源:DataCharm
點(diǎn)擊藍(lán)字 關(guān)注我們
最近有小伙伴私信我關(guān)于matplotlib時(shí)間類型刻度的設(shè)置問(wèn)題,第一感覺(jué)就是官網(wǎng)有好多例子介紹啊?轉(zhuǎn)念一想,在實(shí)際應(yīng)用中類似設(shè)置還挺多和好多小伙伴詢問(wèn),那么本期就就簡(jiǎn)單介紹下Python-matplotlib「刻度(ticker)」?的使用方法,并結(jié)合具體例子講解時(shí)間刻度設(shè)置問(wèn)題,使小伙伴們定制化刻度不再煩惱。本期推文只要涉及知識(shí)點(diǎn)如下:
Tick locators 刻度位置介紹
Tick formatters 刻度形式介紹
時(shí)間刻度的設(shè)置
?位置(Locator)和形式 (Formatter)
Tick Locator
Tick Locator主要設(shè)置刻度位置,這在我的繪圖教程中主要是用來(lái)設(shè)置副刻度(minor),而Formatter則是主要設(shè)置刻度形式。Matplotlib對(duì)這兩者則有著多種用法,其中Locator的子類主要如下:
| AutoLocator | 自動(dòng)定位器,多數(shù)繪圖的默認(rèn)刻度線定位。 |
| MaxNLocator | 在最合適的位置找到帶有刻度的最大間隔數(shù)。 |
| LinearLocator | 從最小到最大之間的均勻刻度定位。 |
| LogLocator | 從最小到最大呈對(duì)數(shù)形式的刻度定位。 |
| MultipleLocator | 刻度和范圍是基數(shù)的倍數(shù);整數(shù)或浮點(diǎn)數(shù)。(自定義刻度用較多的方法)。 |
| FixedLocator | 固定刻度定位。刻度位置是固定的。 |
| IndexLocator | 索引定位器。 |
| NullLocator | 空定位器。無(wú)刻度位置。 |
| SymmetricalLogLocator | 與符號(hào)規(guī)范一起使用的定位器;對(duì)于超出閾值的部分,其工作原理類似于LogLocator,如果在限制范圍內(nèi),則將其加0。 |
| LogitLocator | 用于logit縮放的刻度定位器。 |
| OldAutoLocator | 選擇一個(gè)MultipleLocator并動(dòng)態(tài)重新分配它,以在導(dǎo)航期間進(jìn)行智能打勾。(直接翻譯,感覺(jué)用的不多)。 |
| AutoMinorLocator | 軸為線性且主刻度線等距分布時(shí),副刻度線定位器。將主要刻度間隔細(xì)分為指定數(shù)量的次要間隔,根據(jù)主要間隔默認(rèn)為4或5。 |
看完是不是覺(jué)得小編啥都沒(méi)說(shuō),越看越糊涂?其實(shí)我也是。下面 我們就將每種刻度定位(Locator)可視化展現(xiàn)出來(lái),有助于我們直接觀察。主要代碼如下:
//Filename?Locator.python import?numpy?as?np import?matplotlib.pyplot?as?plt import?matplotlib.ticker?as?ticker plt.rcParams['font.family']?=?"Times?New?Roman"def?setup(ax,?title):"""Set?up?common?parameters?for?the?Axes?in?the?example."""#?only?show?the?bottom?spineax.yaxis.set_major_locator(ticker.NullLocator())ax.spines['right'].set_color('none')ax.spines['left'].set_color('none')ax.spines['top'].set_color('none')ax.xaxis.set_ticks_position('bottom')ax.tick_params(which='major',?width=1.00,?length=5)ax.tick_params(which='minor',?width=0.75,?length=2.5)ax.set_xlim(0,?5)ax.set_ylim(0,?1)ax.text(0.0,?0.2,?title,?transform=ax.transAxes,fontsize=14,?fontname='Monospace',?color='tab:blue')fig,?axs?=?plt.subplots(8,?1,?figsize=(8,?6),dpi=200)#?Null?Locator setup(axs[0],?title="NullLocator()") axs[0].xaxis.set_major_locator(ticker.NullLocator()) axs[0].xaxis.set_minor_locator(ticker.NullLocator())#?Multiple?Locator setup(axs[1],?title="MultipleLocator(0.5)") axs[1].xaxis.set_major_locator(ticker.MultipleLocator(0.5)) axs[1].xaxis.set_minor_locator(ticker.MultipleLocator(0.1))#?Fixed?Locator setup(axs[2],?title="FixedLocator([0,?1,?5])") axs[2].xaxis.set_major_locator(ticker.FixedLocator([0,?1,?5])) axs[2].xaxis.set_minor_locator(ticker.FixedLocator(np.linspace(0.2,?0.8,?4)))#?Linear?Locator setup(axs[3],?title="LinearLocator(numticks=3)") axs[3].xaxis.set_major_locator(ticker.LinearLocator(3)) axs[3].xaxis.set_minor_locator(ticker.LinearLocator(31))#?Index?Locator setup(axs[4],?title="IndexLocator(base=0.5,?offset=0.25)") axs[4].plot(range(0,?5),?[0]*5,?color='white') axs[4].xaxis.set_major_locator(ticker.IndexLocator(base=0.5,?offset=0.25))#?Auto?Locator setup(axs[5],?title="AutoLocator()") axs[5].xaxis.set_major_locator(ticker.AutoLocator()) axs[5].xaxis.set_minor_locator(ticker.AutoMinorLocator())#?MaxN?Locator setup(axs[6],?title="MaxNLocator(n=4)") axs[6].xaxis.set_major_locator(ticker.MaxNLocator(4)) axs[6].xaxis.set_minor_locator(ticker.MaxNLocator(40))#?Log?Locator setup(axs[7],?title="LogLocator(base=10,?numticks=15)") axs[7].set_xlim(10**3,?10**10) axs[7].set_xscale('log') axs[7].xaxis.set_major_locator(ticker.LogLocator(base=10,?numticks=15))plt.tight_layout() plt.savefig(r'F:\DataCharm\學(xué)術(shù)圖表繪制\Python-matplotlib\matplotlib_locators',width=6,height=4,dpi=900,bbox_inches='tight') plt.show()可視化結(jié)果如下:
圖中紅框標(biāo)出的為?Tick locators?較常用的的幾種形式。
Tick formatters
Tick formatters?設(shè)置刻度標(biāo)簽形式,主要對(duì)繪圖刻度標(biāo)簽定制化需求時(shí),matplotlib 可支持修改的刻度標(biāo)簽形式如下:
| NullFormatter | 刻度線上沒(méi)有標(biāo)簽。 |
| IndexFormatter | 從標(biāo)簽列表中設(shè)置刻度標(biāo)簽。 |
| FixedFormatter | 手動(dòng)設(shè)置標(biāo)簽字符串。 |
| FuncFormatter | 用戶定義的功能設(shè)置標(biāo)簽。 |
| StrMethodFormatter | 使用字符串方法設(shè)置刻度標(biāo)簽。 |
| FormatStrFormatter | 使用舊式的sprintf格式字符串。 |
| ScalarFormatter | 標(biāo)量的默認(rèn)格式:自動(dòng)選擇格式字符串。 |
| LogFormatter | Log對(duì)數(shù)形式的刻度標(biāo)簽。 |
| LogFormatterExponent | 使用exponent=log_base(value)形式的刻度標(biāo)簽。 |
| LogFormatterMathtext | 使用Math文本使用exponent = log_base(value)格式化對(duì)數(shù)軸的值。 |
| LogitFormatter | 概率格式器。 |
| PercentFormatter | 將標(biāo)簽格式化為百分比。 |
還是老樣子,我們可視化展示來(lái)看,這樣就對(duì)每一個(gè)刻度標(biāo)簽形式有明確的理解,代碼如下:
//?filename?Tick?formatters.pythonimport?matplotlib.pyplot?as?plt from?matplotlib?import?tickerdef?setup(ax,?title):"""Set?up?common?parameters?for?the?Axes?in?the?example."""#?only?show?the?bottom?spineax.yaxis.set_major_locator(ticker.NullLocator())ax.spines['right'].set_color('none')ax.spines['left'].set_color('none')ax.spines['top'].set_color('none')#?define?tick?positionsax.xaxis.set_major_locator(ticker.MultipleLocator(1.00))ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25))ax.xaxis.set_ticks_position('bottom')ax.tick_params(which='major',?width=1.00,?length=5)ax.tick_params(which='minor',?width=0.75,?length=2.5,?labelsize=10)ax.set_xlim(0,?5)ax.set_ylim(0,?1)ax.text(0.0,?0.2,?title,?transform=ax.transAxes,fontsize=14,?fontname='Monospace',?color='tab:blue')fig0,?axs0?=?plt.subplots(2,?1,?figsize=(8,?2)) fig0.suptitle('Simple?Formatting')setup(axs0[0],?title="'{x}?km'") axs0[0].xaxis.set_major_formatter('{x}?km')setup(axs0[1],?title="lambda?x,?pos:?str(x-5)") axs0[1].xaxis.set_major_formatter(lambda?x,?pos:?str(x-5))fig0.tight_layout()#?The?remaining?examples?use?Formatter?objects.fig1,?axs1?=?plt.subplots(7,?1,?figsize=(8,?6)) fig1.suptitle('Formatter?Object?Formatting')#?Null?formatter setup(axs1[0],?title="NullFormatter()") axs1[0].xaxis.set_major_formatter(ticker.NullFormatter())#?StrMethod?formatter setup(axs1[1],?title="StrMethodFormatter('{x:.3f}')") axs1[1].xaxis.set_major_formatter(ticker.StrMethodFormatter("{x:.3f}"))#?FuncFormatter?can?be?used?as?a?decorator @ticker.FuncFormatter def?major_formatter(x,?pos):return?f'[{x:.2f}]'setup(axs1[2],?title='FuncFormatter("[{:.2f}]".format') axs1[2].xaxis.set_major_formatter(major_formatter)#?Fixed?formatter setup(axs1[3],?title="FixedFormatter(['A',?'B',?'C',?...])") #?FixedFormatter?should?only?be?used?together?with?FixedLocator. #?Otherwise,?one?cannot?be?sure?where?the?labels?will?end?up. positions?=?[0,?1,?2,?3,?4,?5] labels?=?['A',?'B',?'C',?'D',?'E',?'F'] axs1[3].xaxis.set_major_locator(ticker.FixedLocator(positions)) axs1[3].xaxis.set_major_formatter(ticker.FixedFormatter(labels))#?Scalar?formatter setup(axs1[4],?title="ScalarFormatter()") axs1[4].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))#?FormatStr?formatter setup(axs1[5],?title="FormatStrFormatter('#%d')") axs1[5].xaxis.set_major_formatter(ticker.FormatStrFormatter("#%d"))#?Percent?formatter setup(axs1[6],?title="PercentFormatter(xmax=5)") axs1[6].xaxis.set_major_formatter(ticker.PercentFormatter(xmax=5))fig1.tight_layout() plt.show()結(jié)果如下:
以上就是對(duì)matplotlib 的刻度位置和刻度標(biāo)簽形式的介紹,大家也只需了解一兩個(gè)常用的即可,其他用時(shí)再到matplotlib查找即可。下面我們將通過(guò)幾個(gè)例子講解刻度中用的最多的「時(shí)間刻度形式」的設(shè)置。
?時(shí)間刻度形式
默認(rèn)時(shí)間格式
這里我們使用自己生成的數(shù)據(jù)進(jìn)行繪制,詳細(xì)代碼如下:
//filename?time_tick01.python //@by?DataCharm import?matplotlib.pyplot?as?plt import?matplotlib.dates?as?mdates from?datetime?import?datetimeplt.rcParams['font.family']?=?'Times?New?Roman'dates=[20200601,20200602,20200603,20200604,20200605,20200606,20200607,20200608] sales=[20,30,40,60,50,70,40,30] #將dates改成日期格式 x=?[datetime.strptime(str(d),?'%Y%m%d').date()?for?d?in?dates] #繪圖 fig,ax?=?plt.subplots(figsize=(4,2.5),dpi=200) ax.plot(x,sales,lw=2,color='#24C8B0',marker='o',ms=6,?mec='#FD6174',mew=1.5,?mfc='w') #設(shè)置時(shí)間刻度軸旋轉(zhuǎn)角度:使用ax.tick_params #?ax.tick_params(axis='x',direction='in',labelrotation=40,labelsize=8,pad=5)?#選擇x軸 #?ax.tick_params(axis='y',direction='in',labelsize=8,pad=5)? #或者如下設(shè)置 for?label?in?ax.get_xticklabels():label.set_rotation(40)label.set_horizontalalignment('right') ax.text(.85,.05,'\nVisualization?by?DataCharm',transform?=?ax.transAxes,ha='center',?va='center',fontsize?=?4,color='black',fontweight='bold',family='Roboto?Mono') #ax.tick_params(pad=5) plt.savefig("F:\DataCharm\學(xué)術(shù)圖表繪制\Python-matplotlib\matplotlib_time_ticks_set01.png",width=8,height=5,dpi=900,bbox_inches='tight') #顯示圖像 plt.show()可視化結(jié)果如下:這里我們可以發(fā)現(xiàn),雖然我們?cè)O(shè)置了旋轉(zhuǎn)角度(具體設(shè)置方式看繪圖代碼),但也不可避免導(dǎo)致影響美觀。接下來(lái)我們使用半自動(dòng)方式定制時(shí)間刻度形式。
使用DayLocator、HourLocator等時(shí)間刻度定位器
具體代碼如下:
//filename?time_tick02.python //@by?DataCharm import?matplotlib.pyplot?as?plt import?matplotlib.dates?as?mdates from?datetime?import?datetimedates=[20200601,20200602,20200603,20200604,20200605,20200606,20200607,20200608] sales=[20,30,40,60,50,70,40,30] #將dates改成日期格式 x=?[datetime.strptime(str(d),?'%Y%m%d').date()?for?d?in?dates]#繪圖 fig,ax?=?plt.subplots(figsize=(4,2.5),dpi=200) ax.plot(x,sales,lw=2,color='#24C8B0',marker='o',ms=6,?mec='#FD6174',mew=1.5,?mfc='w')#設(shè)置x軸主刻度格式 day?=??mdates.DayLocator(interval=2)?#主刻度為天,間隔2天 ax.xaxis.set_major_locator(day)?#設(shè)置主刻度 ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))?? #設(shè)置副刻度格式 hoursLoc?=?mdates.HourLocator(interval=20)?#為20小時(shí)為1副刻度 ax.xaxis.set_minor_locator(hoursLoc) ax.xaxis.set_minor_formatter(mdates.DateFormatter('%H')) #設(shè)置主刻度旋轉(zhuǎn)角度和刻度label刻度間的距離pad ax.tick_params(which='major',axis='x',labelrotation=10,labelsize=9,length=5,pad=10) ax.tick_params(which='minor',axis='x',labelsize=8,length=3) ax.tick_params(axis='y',labelsize=9,length=3,direction='in')ax.text(.85,.05,'\nVisualization?by?DataCharm',transform?=?ax.transAxes,ha='center',?va='center',fontsize?=?4,color='black',fontweight='bold',family='Roboto?Mono') plt.savefig("F:\DataCharm\學(xué)術(shù)圖表繪制\Python-matplotlib\matplotlib_time_ticks_set03.png",width=8,height=5,dpi=900,bbox_inches='tight') #顯示圖像 plt.show()可視化結(jié)果如下:可以發(fā)現(xiàn)(如圖中紅色圓圈所示),我們分別設(shè)置了主副刻度形式且設(shè)置了時(shí)間間隔。接下來(lái)我們看一個(gè)一鍵設(shè)置時(shí)間刻度形式的方式。
使用ConciseDateFormatter 時(shí)間刻度形式
繪圖代碼如下:
//filename?time_tick_ConciseDate.python //@by?DataCharm import?datetime import?matplotlib.pyplot?as?plt import?matplotlib.dates?as?mdates import?numpy?as?npdates=[20200601,20200602,20200603,20200604,20200605,20200606,20200607,20200608] sales=[20,30,40,60,50,70,40,30] #將dates改成日期格式 x=?[datetime.strptime(str(d),?'%Y%m%d').date()?for?d?in?dates]fig,ax?=?plt.subplots(figsize=(4,2.5),dpi=200) locator?=?mdates.AutoDateLocator(minticks=2,?maxticks=7) formatter?=?mdates.ConciseDateFormatter(locator) ax.plot(x,sales,lw=2,color='#24C8B0',marker='o',ms=6,?mec='#FD6174',mew=1.5,?mfc='w') ax.xaxis.set_major_locator(locator) ax.xaxis.set_major_formatter(formatter) ax.text(.85,.05,'\nVisualization?by?DataCharm',transform?=?ax.transAxes,ha='center',?va='center',fontsize?=?4,color='black',fontweight='bold',family='Roboto?Mono') plt.savefig("F:\DataCharm\學(xué)術(shù)圖表繪制\Python-matplotlib\matplotlib_time_ticks_set02.png",width=8,height=5,dpi=900,bbox_inches='tight') plt.show()可以看出(如下圖紅色圓圈所示),這種方法可以完美解決時(shí)間刻度擁擠的現(xiàn)象,而且在對(duì)多時(shí)間或者一天內(nèi)多小時(shí)也能夠完美解決。
直接更改刻度標(biāo)簽名稱(tickslabel)
最后這種方法就比較簡(jiǎn)單粗暴了,我們直接使用ax.set_xticklabels()?命名刻度標(biāo)簽。代碼如下:
//filename?time_tick_04.python //@by?DataCharm import?matplotlib.pyplot?as?plt import?matplotlib.dates?as?mdates from?datetime?import?datetimedates=[20200601,20200602,20200603,20200604,20200605,20200606,20200607,20200608] sales=[20,30,40,60,50,70,40,30]date_label?=?['2020-0601','2020-06-02','20200603','2020-604','2020605','20200606','2020-0607','2020-0608'] #將dates改成日期格式 x=?[datetime.strptime(str(d),?'%Y%m%d').date()?for?d?in?dates]#繪圖 fig,ax?=?plt.subplots(figsize=(4,2.5),dpi=200) ax.plot(x,sales,lw=2,color='#24C8B0',marker='o',ms=6,?mec='#FD6174',mew=1.5,?mfc='w') #自定義刻度label ax.set_xticklabels(date_label)#設(shè)置主刻度旋轉(zhuǎn)角度和刻度label于刻度間的距離pad ax.tick_params(axis='x',labelrotation=15,labelsize=8,length=5,pad=5) ax.tick_params(axis='y',labelsize=9,length=3,direction='in')ax.text(.85,.05,'\nVisualization?by?DataCharm',transform?=?ax.transAxes,ha='center',?va='center',fontsize?=?4,color='black',fontweight='bold',family='Roboto?Mono') plt.savefig("F:\DataCharm\學(xué)術(shù)圖表繪制\Python-matplotlib\matplotlib_time_ticks_set04.png",width=8,height=5,dpi=900,bbox_inches='tight') #顯示圖像 plt.show()結(jié)果如下(圖中紅色圓圈內(nèi)),這里我隨意定義刻度labels形式。
?總結(jié)
本篇推文首先簡(jiǎn)單介紹了Python-matplotlib刻度(ticker)?設(shè)置位置和形式,然后具體介紹了時(shí)間刻度設(shè)置的幾種方法,希望能夠給大家解決時(shí)間刻度設(shè)置帶來(lái)靈感。就本人繪圖而言,matplotlib時(shí)間刻度設(shè)置還是采用ConciseDateFormatter方法最為方便,當(dāng)然,如果定制化需求較高,大家也可以采用直接設(shè)置刻度的方法。
◆?◆?◆ ?◆?◆ 麟哥新書已經(jīng)在當(dāng)當(dāng)上架了,我寫了本書:《拿下Offer-數(shù)據(jù)分析師求職面試指南》,目前當(dāng)當(dāng)正在舉行活動(dòng),大家可以用相當(dāng)于原價(jià)4.45折的預(yù)購(gòu)價(jià)格購(gòu)買,還是非常劃算的:點(diǎn)擊下方小程序即可進(jìn)入購(gòu)買頁(yè)面:數(shù)據(jù)森麟公眾號(hào)的交流群已經(jīng)建立,許多小伙伴已經(jīng)加入其中,感謝大家的支持。大家可以在群里交流關(guān)于數(shù)據(jù)分析&數(shù)據(jù)挖掘的相關(guān)內(nèi)容,還沒(méi)有加入的小伙伴可以掃描下方管理員二維碼,進(jìn)群前一定要關(guān)注公眾號(hào)奧,關(guān)注后讓管理員幫忙拉進(jìn)群,期待大家的加入。管理員二維碼:猜你喜歡●?麟哥拼了!!!親自出鏡推薦自己新書《數(shù)據(jù)分析師求職面試指南》●?厲害了!麟哥新書登頂京東銷量排行榜!●?笑死人不償命的知乎沙雕問(wèn)題排行榜 ●?用Python扒出B站那些“驚為天人”的阿婆主!●?你相信逛B站也能學(xué)編程嗎點(diǎn)擊閱讀原文,即可參與當(dāng)當(dāng)4.45折購(gòu)書活動(dòng)總結(jié)
以上是生活随笔為你收集整理的Matpotlib绘图遇到时间刻度就犯难?现在,一次性告诉你四种方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python的seek函数
- 下一篇: Mediawiki