Matpotlib绘图遇到时间刻度就犯难?现在,一次性告诉你四种方法
公眾號后臺回復“圖書“,了解更多號主新書內容
作者:寧海濤
來源:DataCharm
點擊藍字 關注我們
最近有小伙伴私信我關于matplotlib時間類型刻度的設置問題,第一感覺就是官網有好多例子介紹啊?轉念一想,在實際應用中類似設置還挺多和好多小伙伴詢問,那么本期就就簡單介紹下Python-matplotlib「刻度(ticker)」?的使用方法,并結合具體例子講解時間刻度設置問題,使小伙伴們定制化刻度不再煩惱。本期推文只要涉及知識點如下:
Tick locators 刻度位置介紹
Tick formatters 刻度形式介紹
時間刻度的設置
?位置(Locator)和形式 (Formatter)
Tick Locator
Tick Locator主要設置刻度位置,這在我的繪圖教程中主要是用來設置副刻度(minor),而Formatter則是主要設置刻度形式。Matplotlib對這兩者則有著多種用法,其中Locator的子類主要如下:
| AutoLocator | 自動定位器,多數繪圖的默認刻度線定位。 |
| MaxNLocator | 在最合適的位置找到帶有刻度的最大間隔數。 |
| LinearLocator | 從最小到最大之間的均勻刻度定位。 |
| LogLocator | 從最小到最大呈對數形式的刻度定位。 |
| MultipleLocator | 刻度和范圍是基數的倍數;整數或浮點數。(自定義刻度用較多的方法)。 |
| FixedLocator | 固定刻度定位。刻度位置是固定的。 |
| IndexLocator | 索引定位器。 |
| NullLocator | 空定位器。無刻度位置。 |
| SymmetricalLogLocator | 與符號規范一起使用的定位器;對于超出閾值的部分,其工作原理類似于LogLocator,如果在限制范圍內,則將其加0。 |
| LogitLocator | 用于logit縮放的刻度定位器。 |
| OldAutoLocator | 選擇一個MultipleLocator并動態重新分配它,以在導航期間進行智能打勾。(直接翻譯,感覺用的不多)。 |
| AutoMinorLocator | 軸為線性且主刻度線等距分布時,副刻度線定位器。將主要刻度間隔細分為指定數量的次要間隔,根據主要間隔默認為4或5。 |
看完是不是覺得小編啥都沒說,越看越糊涂?其實我也是。下面 我們就將每種刻度定位(Locator)可視化展現出來,有助于我們直接觀察。主要代碼如下:
//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\學術圖表繪制\Python-matplotlib\matplotlib_locators',width=6,height=4,dpi=900,bbox_inches='tight') plt.show()可視化結果如下:
圖中紅框標出的為?Tick locators?較常用的的幾種形式。
Tick formatters
Tick formatters?設置刻度標簽形式,主要對繪圖刻度標簽定制化需求時,matplotlib 可支持修改的刻度標簽形式如下:
| NullFormatter | 刻度線上沒有標簽。 |
| IndexFormatter | 從標簽列表中設置刻度標簽。 |
| FixedFormatter | 手動設置標簽字符串。 |
| FuncFormatter | 用戶定義的功能設置標簽。 |
| StrMethodFormatter | 使用字符串方法設置刻度標簽。 |
| FormatStrFormatter | 使用舊式的sprintf格式字符串。 |
| ScalarFormatter | 標量的默認格式:自動選擇格式字符串。 |
| LogFormatter | Log對數形式的刻度標簽。 |
| LogFormatterExponent | 使用exponent=log_base(value)形式的刻度標簽。 |
| LogFormatterMathtext | 使用Math文本使用exponent = log_base(value)格式化對數軸的值。 |
| LogitFormatter | 概率格式器。 |
| PercentFormatter | 將標簽格式化為百分比。 |
還是老樣子,我們可視化展示來看,這樣就對每一個刻度標簽形式有明確的理解,代碼如下:
//?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()結果如下:
以上就是對matplotlib 的刻度位置和刻度標簽形式的介紹,大家也只需了解一兩個常用的即可,其他用時再到matplotlib查找即可。下面我們將通過幾個例子講解刻度中用的最多的「時間刻度形式」的設置。
?時間刻度形式
默認時間格式
這里我們使用自己生成的數據進行繪制,詳細代碼如下:
//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') #設置時間刻度軸旋轉角度:使用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)? #或者如下設置 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\學術圖表繪制\Python-matplotlib\matplotlib_time_ticks_set01.png",width=8,height=5,dpi=900,bbox_inches='tight') #顯示圖像 plt.show()可視化結果如下:這里我們可以發現,雖然我們設置了旋轉角度(具體設置方式看繪圖代碼),但也不可避免導致影響美觀。接下來我們使用半自動方式定制時間刻度形式。
使用DayLocator、HourLocator等時間刻度定位器
具體代碼如下:
//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')#設置x軸主刻度格式 day?=??mdates.DayLocator(interval=2)?#主刻度為天,間隔2天 ax.xaxis.set_major_locator(day)?#設置主刻度 ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))?? #設置副刻度格式 hoursLoc?=?mdates.HourLocator(interval=20)?#為20小時為1副刻度 ax.xaxis.set_minor_locator(hoursLoc) ax.xaxis.set_minor_formatter(mdates.DateFormatter('%H')) #設置主刻度旋轉角度和刻度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\學術圖表繪制\Python-matplotlib\matplotlib_time_ticks_set03.png",width=8,height=5,dpi=900,bbox_inches='tight') #顯示圖像 plt.show()可視化結果如下:可以發現(如圖中紅色圓圈所示),我們分別設置了主副刻度形式且設置了時間間隔。接下來我們看一個一鍵設置時間刻度形式的方式。
使用ConciseDateFormatter 時間刻度形式
繪圖代碼如下:
//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\學術圖表繪制\Python-matplotlib\matplotlib_time_ticks_set02.png",width=8,height=5,dpi=900,bbox_inches='tight') plt.show()可以看出(如下圖紅色圓圈所示),這種方法可以完美解決時間刻度擁擠的現象,而且在對多時間或者一天內多小時也能夠完美解決。
直接更改刻度標簽名稱(tickslabel)
最后這種方法就比較簡單粗暴了,我們直接使用ax.set_xticklabels()?命名刻度標簽。代碼如下:
//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)#設置主刻度旋轉角度和刻度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\學術圖表繪制\Python-matplotlib\matplotlib_time_ticks_set04.png",width=8,height=5,dpi=900,bbox_inches='tight') #顯示圖像 plt.show()結果如下(圖中紅色圓圈內),這里我隨意定義刻度labels形式。
?總結
本篇推文首先簡單介紹了Python-matplotlib刻度(ticker)?設置位置和形式,然后具體介紹了時間刻度設置的幾種方法,希望能夠給大家解決時間刻度設置帶來靈感。就本人繪圖而言,matplotlib時間刻度設置還是采用ConciseDateFormatter方法最為方便,當然,如果定制化需求較高,大家也可以采用直接設置刻度的方法。
◆?◆?◆ ?◆?◆ 麟哥新書已經在當當上架了,我寫了本書:《拿下Offer-數據分析師求職面試指南》,目前當當正在舉行活動,大家可以用相當于原價4.45折的預購價格購買,還是非常劃算的:點擊下方小程序即可進入購買頁面:數據森麟公眾號的交流群已經建立,許多小伙伴已經加入其中,感謝大家的支持。大家可以在群里交流關于數據分析&數據挖掘的相關內容,還沒有加入的小伙伴可以掃描下方管理員二維碼,進群前一定要關注公眾號奧,關注后讓管理員幫忙拉進群,期待大家的加入。管理員二維碼:猜你喜歡●?麟哥拼了!!!親自出鏡推薦自己新書《數據分析師求職面試指南》●?厲害了!麟哥新書登頂京東銷量排行榜!●?笑死人不償命的知乎沙雕問題排行榜 ●?用Python扒出B站那些“驚為天人”的阿婆主!●?你相信逛B站也能學編程嗎點擊閱讀原文,即可參與當當4.45折購書活動總結
以上是生活随笔為你收集整理的Matpotlib绘图遇到时间刻度就犯难?现在,一次性告诉你四种方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python的seek函数
- 下一篇: Mediawiki