当前位置:   article > 正文

Matpotlib绘图遇到时间刻度就犯难?现在,一次性告诉你四种方法

mdates.autodatelocator()

公众号后台回复“图书“,了解更多号主新书内容

作者:宁海涛

来源: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)可视化展现出来,有助于我们直接观察。主要代码如下:

  1. //Filename Locator.python
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import matplotlib.ticker as ticker
  5. plt.rcParams['font.family'] = "Times New Roman"
  6. def setup(ax, title):
  7.     """Set up common parameters for the Axes in the example."""
  8.     # only show the bottom spine
  9.     ax.yaxis.set_major_locator(ticker.NullLocator())
  10.     ax.spines['right'].set_color('none')
  11.     ax.spines['left'].set_color('none')
  12.     ax.spines['top'].set_color('none')
  13.     ax.xaxis.set_ticks_position('bottom')
  14.     ax.tick_params(which='major', width=1.00, length=5)
  15.     ax.tick_params(which='minor', width=0.75, length=2.5)
  16.     ax.set_xlim(05)
  17.     ax.set_ylim(01)
  18.     ax.text(0.00.2, title, transform=ax.transAxes,
  19.             fontsize=14, fontname='Monospace', color='tab:blue')
  20. fig, axs = plt.subplots(81, figsize=(86),dpi=200)
  21. # Null Locator
  22. setup(axs[0], title="NullLocator()")
  23. axs[0].xaxis.set_major_locator(ticker.NullLocator())
  24. axs[0].xaxis.set_minor_locator(ticker.NullLocator())
  25. # Multiple Locator
  26. setup(axs[1], title="MultipleLocator(0.5)")
  27. axs[1].xaxis.set_major_locator(ticker.MultipleLocator(0.5))
  28. axs[1].xaxis.set_minor_locator(ticker.MultipleLocator(0.1))
  29. # Fixed Locator
  30. setup(axs[2], title="FixedLocator([0, 1, 5])")
  31. axs[2].xaxis.set_major_locator(ticker.FixedLocator([015]))
  32. axs[2].xaxis.set_minor_locator(ticker.FixedLocator(np.linspace(0.20.84)))
  33. # Linear Locator
  34. setup(axs[3], title="LinearLocator(numticks=3)")
  35. axs[3].xaxis.set_major_locator(ticker.LinearLocator(3))
  36. axs[3].xaxis.set_minor_locator(ticker.LinearLocator(31))
  37. # Index Locator
  38. setup(axs[4], title="IndexLocator(base=0.5, offset=0.25)")
  39. axs[4].plot(range(05), [0]*5, color='white')
  40. axs[4].xaxis.set_major_locator(ticker.IndexLocator(base=0.5, offset=0.25))
  41. # Auto Locator
  42. setup(axs[5], title="AutoLocator()")
  43. axs[5].xaxis.set_major_locator(ticker.AutoLocator())
  44. axs[5].xaxis.set_minor_locator(ticker.AutoMinorLocator())
  45. # MaxN Locator
  46. setup(axs[6], title="MaxNLocator(n=4)")
  47. axs[6].xaxis.set_major_locator(ticker.MaxNLocator(4))
  48. axs[6].xaxis.set_minor_locator(ticker.MaxNLocator(40))
  49. # Log Locator
  50. setup(axs[7], title="LogLocator(base=10, numticks=15)")
  51. axs[7].set_xlim(10**310**10)
  52. axs[7].set_xscale('log')
  53. axs[7].xaxis.set_major_locator(ticker.LogLocator(base=10, numticks=15))
  54. plt.tight_layout()
  55. plt.savefig(r'F:\DataCharm\学术图表绘制\Python-matplotlib\matplotlib_locators',width=6,height=4,
  56.             dpi=900,bbox_inches='tight')
  57. plt.show()

可视化结果如下:

图中红框标出的为 Tick locators 较常用的的几种形式。

Tick formatters

Tick formatters 设置刻度标签形式,主要对绘图刻度标签定制化需求时,matplotlib 可支持修改的刻度标签形式如下:

定位器解释说明
NullFormatter刻度线上没有标签。
IndexFormatter从标签列表中设置刻度标签。
FixedFormatter手动设置标签字符串。
FuncFormatter用户定义的功能设置标签。
StrMethodFormatter使用字符串方法设置刻度标签。
FormatStrFormatter使用旧式的sprintf格式字符串。
ScalarFormatter标量的默认格式:自动选择格式字符串。
LogFormatterLog对数形式的刻度标签。
LogFormatterExponent使用exponent=log_base(value)形式的刻度标签。
LogFormatterMathtext使用Math文本使用exponent = log_base(value)格式化对数轴的值。
LogitFormatter概率格式器。
PercentFormatter将标签格式化为百分比。

还是老样子,我们可视化展示来看,这样就对每一个刻度标签形式有明确的理解,代码如下:

  1. // filename Tick formatters.python
  2. import matplotlib.pyplot as plt
  3. from matplotlib import ticker
  4. def setup(ax, title):
  5.     """Set up common parameters for the Axes in the example."""
  6.     # only show the bottom spine
  7.     ax.yaxis.set_major_locator(ticker.NullLocator())
  8.     ax.spines['right'].set_color('none')
  9.     ax.spines['left'].set_color('none')
  10.     ax.spines['top'].set_color('none')
  11.     # define tick positions
  12.     ax.xaxis.set_major_locator(ticker.MultipleLocator(1.00))
  13.     ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25))
  14.     ax.xaxis.set_ticks_position('bottom')
  15.     ax.tick_params(which='major', width=1.00, length=5)
  16.     ax.tick_params(which='minor', width=0.75, length=2.5, labelsize=10)
  17.     ax.set_xlim(05)
  18.     ax.set_ylim(01)
  19.     ax.text(0.00.2, title, transform=ax.transAxes,
  20.             fontsize=14, fontname='Monospace', color='tab:blue')
  21. fig0, axs0 = plt.subplots(21, figsize=(82))
  22. fig0.suptitle('Simple Formatting')
  23. setup(axs0[0], title="'{x} km'")
  24. axs0[0].xaxis.set_major_formatter('{x} km')
  25. setup(axs0[1], title="lambda x, pos: str(x-5)")
  26. axs0[1].xaxis.set_major_formatter(lambda x, pos: str(x-5))
  27. fig0.tight_layout()
  28. # The remaining examples use Formatter objects.
  29. fig1, axs1 = plt.subplots(71, figsize=(86))
  30. fig1.suptitle('Formatter Object Formatting')
  31. # Null formatter
  32. setup(axs1[0], title="NullFormatter()")
  33. axs1[0].xaxis.set_major_formatter(ticker.NullFormatter())
  34. # StrMethod formatter
  35. setup(axs1[1], title="StrMethodFormatter('{x:.3f}')")
  36. axs1[1].xaxis.set_major_formatter(ticker.StrMethodFormatter("{x:.3f}"))
  37. # FuncFormatter can be used as a decorator
  38. @ticker.FuncFormatter
  39. def major_formatter(x, pos):
  40.     return f'[{x:.2f}]'
  41. setup(axs1[2], title='FuncFormatter("[{:.2f}]".format')
  42. axs1[2].xaxis.set_major_formatter(major_formatter)
  43. # Fixed formatter
  44. setup(axs1[3], title="FixedFormatter(['A', 'B', 'C', ...])")
  45. # FixedFormatter should only be used together with FixedLocator.
  46. # Otherwise, one cannot be sure where the labels will end up.
  47. positions = [012345]
  48. labels = ['A''B''C''D''E''F']
  49. axs1[3].xaxis.set_major_locator(ticker.FixedLocator(positions))
  50. axs1[3].xaxis.set_major_formatter(ticker.FixedFormatter(labels))
  51. # Scalar formatter
  52. setup(axs1[4], title="ScalarFormatter()")
  53. axs1[4].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
  54. # FormatStr formatter
  55. setup(axs1[5], title="FormatStrFormatter('#%d')")
  56. axs1[5].xaxis.set_major_formatter(ticker.FormatStrFormatter("#%d"))
  57. # Percent formatter
  58. setup(axs1[6], title="PercentFormatter(xmax=5)")
  59. axs1[6].xaxis.set_major_formatter(ticker.PercentFormatter(xmax=5))
  60. fig1.tight_layout()
  61. plt.show()

结果如下:

以上就是对matplotlib 的刻度位置和刻度标签形式的介绍,大家也只需了解一两个常用的即可,其他用时再到matplotlib查找即可。下面我们将通过几个例子讲解刻度中用的最多的「时间刻度形式」的设置。

 时间刻度形式

默认时间格式

这里我们使用自己生成的数据进行绘制,详细代码如下:

  1. //filename time_tick01.python
  2. //@by DataCharm
  3. import matplotlib.pyplot as plt
  4. import matplotlib.dates as mdates
  5. from datetime import datetime
  6. plt.rcParams['font.family'] = 'Times New Roman'
  7. dates=[20200601,20200602,20200603,20200604,20200605,20200606,20200607,20200608]
  8. sales=[20,30,40,60,50,70,40,30]
  9. #将dates改成日期格式
  10. x= [datetime.strptime(str(d), '%Y%m%d').date() for d in dates]
  11. #绘图
  12. fig,ax = plt.subplots(figsize=(4,2.5),dpi=200)
  13. ax.plot(x,sales,lw=2,color='#24C8B0',marker='o',ms=6, mec='#FD6174',mew=1.5, mfc='w')
  14. #设置时间刻度轴旋转角度:使用ax.tick_params
  15. # ax.tick_params(axis='x',direction='in',labelrotation=40,labelsize=8,pad=5) #选择x轴
  16. # ax.tick_params(axis='y',direction='in',labelsize=8,pad=5
  17. #或者如下设置
  18. for label in ax.get_xticklabels():
  19.     label.set_rotation(40)
  20.     label.set_horizontalalignment('right')
  21. ax.text(.85,.05,'\nVisualization by DataCharm',transform = ax.transAxes,
  22.         ha='center', va='center',fontsize = 4,color='black',fontweight='bold',family='Roboto Mono')
  23. #ax.tick_params(pad=5)
  24. plt.savefig("F:\DataCharm\学术图表绘制\Python-matplotlib\matplotlib_time_ticks_set01.png",width=8,height=5,dpi=900,bbox_inches='tight')
  25. #显示图像
  26. plt.show()

可视化结果如下:这里我们可以发现,虽然我们设置了旋转角度(具体设置方式看绘图代码),但也不可避免导致影响美观。接下来我们使用半自动方式定制时间刻度形式。

使用DayLocator、HourLocator等时间刻度定位器

具体代码如下:

  1. //filename time_tick02.python
  2. //@by DataCharm
  3. import matplotlib.pyplot as plt
  4. import matplotlib.dates as mdates
  5. from datetime import datetime
  6. dates=[20200601,20200602,20200603,20200604,20200605,20200606,20200607,20200608]
  7. sales=[20,30,40,60,50,70,40,30]
  8. #将dates改成日期格式
  9. x= [datetime.strptime(str(d), '%Y%m%d').date() for d in dates]
  10. #绘图
  11. fig,ax = plt.subplots(figsize=(4,2.5),dpi=200)
  12. ax.plot(x,sales,lw=2,color='#24C8B0',marker='o',ms=6, mec='#FD6174',mew=1.5, mfc='w')
  13. #设置x轴主刻度格式
  14. day =  mdates.DayLocator(interval=2) #主刻度为天,间隔2
  15. ax.xaxis.set_major_locator(day) #设置主刻度
  16. ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))  
  17. #设置副刻度格式
  18. hoursLoc = mdates.HourLocator(interval=20) #为20小时为1副刻度
  19. ax.xaxis.set_minor_locator(hoursLoc)
  20. ax.xaxis.set_minor_formatter(mdates.DateFormatter('%H'))
  21. #设置主刻度旋转角度和刻度label刻度间的距离pad
  22. ax.tick_params(which='major',axis='x',labelrotation=10,labelsize=9,length=5,pad=10)
  23. ax.tick_params(which='minor',axis='x',labelsize=8,length=3)
  24. ax.tick_params(axis='y',labelsize=9,length=3,direction='in')
  25. ax.text(.85,.05,'\nVisualization by DataCharm',transform = ax.transAxes,
  26.         ha='center', va='center',fontsize = 4,color='black',fontweight='bold',family='Roboto Mono')
  27. plt.savefig("F:\DataCharm\学术图表绘制\Python-matplotlib\matplotlib_time_ticks_set03.png",width=8,height=5,dpi=900,
  28.             bbox_inches='tight')
  29. #显示图像
  30. plt.show()

可视化结果如下:可以发现(如图中红色圆圈所示),我们分别设置了主副刻度形式且设置了时间间隔。接下来我们看一个一键设置时间刻度形式的方式。

使用ConciseDateFormatter 时间刻度形式

绘图代码如下:

  1. //filename time_tick_ConciseDate.python
  2. //@by DataCharm
  3. import datetime
  4. import matplotlib.pyplot as plt
  5. import matplotlib.dates as mdates
  6. import numpy as np
  7. dates=[20200601,20200602,20200603,20200604,20200605,20200606,20200607,20200608]
  8. sales=[20,30,40,60,50,70,40,30]
  9. #将dates改成日期格式
  10. x= [datetime.strptime(str(d), '%Y%m%d').date() for d in dates]
  11. fig,ax = plt.subplots(figsize=(4,2.5),dpi=200)
  12. locator = mdates.AutoDateLocator(minticks=2, maxticks=7)
  13. formatter = mdates.ConciseDateFormatter(locator)
  14. ax.plot(x,sales,lw=2,color='#24C8B0',marker='o',ms=6, mec='#FD6174',mew=1.5, mfc='w')
  15. ax.xaxis.set_major_locator(locator)
  16. ax.xaxis.set_major_formatter(formatter)
  17. ax.text(.85,.05,'\nVisualization by DataCharm',transform = ax.transAxes,
  18.         ha='center', va='center',fontsize = 4,color='black',fontweight='bold',family='Roboto Mono')
  19. plt.savefig("F:\DataCharm\学术图表绘制\Python-matplotlib\matplotlib_time_ticks_set02.png",width=8,height=5,dpi=900,bbox_inches='tight')
  20. plt.show()

可以看出(如下图红色圆圈所示),这种方法可以完美解决时间刻度拥挤的现象,而且在对多时间或者一天内多小时也能够完美解决。

直接更改刻度标签名称(tickslabel)

最后这种方法就比较简单粗暴了,我们直接使用ax.set_xticklabels() 命名刻度标签。代码如下:

  1. //filename time_tick_04.python
  2. //@by DataCharm
  3. import matplotlib.pyplot as plt
  4. import matplotlib.dates as mdates
  5. from datetime import datetime
  6. dates=[20200601,20200602,20200603,20200604,20200605,20200606,20200607,20200608]
  7. sales=[20,30,40,60,50,70,40,30]
  8. date_label = ['2020-0601','2020-06-02','20200603','2020-604','2020605','20200606','2020-0607',
  9.              '2020-0608']
  10. #将dates改成日期格式
  11. x= [datetime.strptime(str(d), '%Y%m%d').date() for d in dates]
  12. #绘图
  13. fig,ax = plt.subplots(figsize=(4,2.5),dpi=200)
  14. ax.plot(x,sales,lw=2,color='#24C8B0',marker='o',ms=6, mec='#FD6174',mew=1.5, mfc='w')
  15. #自定义刻度label
  16. ax.set_xticklabels(date_label)
  17. #设置主刻度旋转角度和刻度label于刻度间的距离pad
  18. ax.tick_params(axis='x',labelrotation=15,labelsize=8,length=5,pad=5)
  19. ax.tick_params(axis='y',labelsize=9,length=3,direction='in')
  20. ax.text(.85,.05,'\nVisualization by DataCharm',transform = ax.transAxes,
  21.         ha='center', va='center',fontsize = 4,color='black',fontweight='bold',family='Roboto Mono')
  22. plt.savefig("F:\DataCharm\学术图表绘制\Python-matplotlib\matplotlib_time_ticks_set04.png",width=8,height=5,dpi=900,
  23.             bbox_inches='tight')
  24. #显示图像
  25. plt.show()

结果如下(图中红色圆圈内),这里我随意定义刻度labels形式。

 总结

本篇推文首先简单介绍了Python-matplotlib刻度(ticker) 设置位置和形式,然后具体介绍了时间刻度设置的几种方法,希望能够给大家解决时间刻度设置带来灵感。就本人绘图而言,matplotlib时间刻度设置还是采用ConciseDateFormatter方法最为方便,当然,如果定制化需求较高,大家也可以采用直接设置刻度的方法。

  1. ◆ ◆ ◆  ◆ ◆
  2. 麟哥新书已经在当当上架了,我写了本书:《拿下Offer-数据分析师求职面试指南》,目前当当正在举行活动,大家可以用相当于原价4.45折的预购价格购买,还是非常划算的:
  3. 点击下方小程序即可进入购买页面:
  1. 数据森麟公众号的交流群已经建立,许多小伙伴已经加入其中,感谢大家的支持。大家可以在群里交流关于数据分析&数据挖掘的相关内容,还没有加入的小伙伴可以扫描下方管理员二维码,进群前一定要关注公众号奥,关注后让管理员帮忙拉进群,期待大家的加入。
  2. 管理员二维码:
  3. 猜你喜欢
  4. ● 麟哥拼了!!!亲自出镜推荐自己新书《数据分析师求职面试指南》● 厉害了!麟哥新书登顶京东销量排行榜!● 笑死人不偿命的知乎沙雕问题排行榜
  5. ● 用Python扒出B站那些“惊为天人”的阿婆主!● 你相信逛B站也能学编程吗点击阅读原文,即可参与当当4.45折购书活动
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/681761
推荐阅读
相关标签
  

闽ICP备14008679号