在一幅图表中,文本、坐标轴和图像的是信息传递的核心,对着三者的设置是作图这最为关心的内容,在上一篇博客中虽然列举了一些设置方法,但没有进行深入介绍,本文以围绕如何对文本和坐标轴进行设置展开(对图像的设置在后续介绍到各种图绘制时介绍)。
这里所说的文本是指在使用matplotlib作图过程中通过代码的方式往图中添加的各种文字,包括figure标题、axes标题、坐标轴标签、坐标轴刻度标签、注释、普通文本等。轴设置指的是对与坐标轴相关的的元素的设置,例如显示范围、刻度、刻度标签等。
from matplotlib import pyplot as plt import numpy as np import matplotlib as mpl mpl.rcParams['font.sans-serif'] = ['SimHei'] # 中文字体支持
1 标题
(1)figure标题与axes标题
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig = plt.figure(figsize=(8, 3)) ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122) fig.subplots_adjust(top=0.85) fig.suptitle('figure标题') ax1.set_title('ax1-标题') ax2.set_title('ax2-标题') plt.show()
(2)字体设置
from matplotlib.font_manager import FontProperties x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig = plt.figure(figsize=(8, 3)) ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122) fig.subplots_adjust(top=0.85) fig.suptitle('figure标题', color='red', fontsize=20) font = FontProperties() # 字体类 font.set_family('serif') font.set_name('SimHei') font.set_style('italic') ax1.set_title('ax1-标题',fontproperties=font) # 传递字体类设置字体 ax2.set_title('ax2-标题', color='green') plt.show()
(3)设置水平距离
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig, axs = plt.subplots(3, 1, figsize=(5, 10)) fig.subplots_adjust(top=0.93) fig.suptitle('figure标题', color='red', fontsize=20) locs = ['left', 'center', 'right'] for ax, loc in zip(axs, locs): ax.plot(x1, y1) ax.set_title('axes标题 '+ loc, loc=loc, color='blue') plt.show()
(4)设置垂直距离
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig, ax = plt.subplots(figsize=(5, 3)) fig.subplots_adjust(top=0.8) ax.plot(x1, y1) ax.set_title('垂直距离测试图-标题', pad=30) plt.show()
2 坐标轴标签
(1)添加坐标轴标签
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig, ax = plt.subplots(figsize=(5, 3)) fig.subplots_adjust(bottom=0.15, left=0.2) ax.plot(x1, y1) ax.set_xlabel('时间 [s]') ax.set_ylabel('阻尼振荡 [V]') plt.show()
(2)与坐标轴间距
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig, ax = plt.subplots(figsize=(5, 3)) fig.subplots_adjust(bottom=0.15, left=0.2) ax.plot(x1, y1*10000) ax.set_xlabel('时间 [s]', labelpad=28) ax.set_ylabel('阻尼振荡 [V]', labelpad=28) # 指定labelpad参数设置距离 plt.show()
(3)位置设置
x1 = np.linspace(0.0, 10.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig, ax = plt.subplots(figsize=(5, 3)) fig.subplots_adjust(bottom=0.15, left=0.2) ax.plot(x1, y1) ax.set_xlabel('time [s]', position=(0.2, 1e6), # 位置,坐标轴总长的比例 horizontalalignment='left') # 对齐方式,左对齐,右对齐 ax.set_ylabel('Damped oscillation [V]') plt.show()
(4)字体设置
from matplotlib.font_manager import FontProperties font = FontProperties() font.set_family('serif') font.set_name('DejaVu Sans') font.set_style('italic') fig, ax = plt.subplots(figsize=(5, 3)) fig.subplots_adjust(bottom=0.15, left=0.2) ax.plot(x1, y1) ax.set_xlabel('time [s]', fontsize=20, fontweight='bold') # 可以通过出不同参数来设置字体 ax.set_ylabel('Damped oscillation [V]', fontproperties=font, color='red') # 也可以直接传递一个FontProperties类实例设置字体 plt.show()
3 刻度和刻度标签
(1)设置刻度标签
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig, axs = plt.subplots(5, 1, figsize=(10, 6), tight_layout=True) axs[0].plot(x1, y1) axs[1].plot(x1, y1) axs[2].plot(x1, y1) axs[3].plot(x1, y1) axs[4].plot(x1, y1) axs[0].xaxis.set_ticks([1, 2, 3, 4, 5]) # 这是默认的,系统会根据传递的数据自动设置刻度 axs[1].xaxis.set_ticks([0, 1, 3 , 5,]) # 传递列表 axs[2].xaxis.set_ticks(np.arange(0., 5.1, 2.0)) # 每0.5个单位间隔显示 axs[3].xaxis.set_ticks(np.arange(0., 5.1, 0.5)) # 每2个单位显示 ticks_2 = np.arange(0., 5.1, 0.5) tickla_2 = ['%1.2f' % tick for tick in ticks_2] # 显示精度 axs[4].xaxis.set_ticks(ticks_2) axs[4].xaxis.set_ticklabels(tickla_2) plt.show()
(2)刻度标签显示其他字符
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig = plt.figure() axes = fig.add_subplot(1, 1, 1) axes.plot(x1, y1) axes.xaxis.set_ticks([1, 2 , 3, 4, 5]) axes.set_xticklabels(['第一天', '第二天', '第三天', '第四天', '第五天'], # 这里的字符列表必须与上面一行的刻度列表一一对应 color='red', fontsize=15, # 直接设置样式,这里与其他设置text的方法一样 rotation=30) # 旋转角度 plt.show()
(3)刻度数量与格式
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig = plt.figure() axes = fig.add_subplot(1, 1, 1) axes.plot(x1, y1) formatter = mpl.ticker.FormatStrFormatter('%1.5f') # 设置显示精度格式 locator = mpl.ticker.MaxNLocator(nbins=3) # 设置显示刻度的数量 axes.xaxis.set_major_formatter(formatter) axes.xaxis.set_major_locator(locator) plt.show()
(4)自定义是否显示某刻度标签
x1 = np.linspace(0.0, 10.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) def formatoddticks(x, pos): """ 如果是3的倍数,则显示空 """ if x % 3: return '%1.2f' % x else: return '' # 可以设置成其它字符 fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True) ax.plot(x1, y1) formatter = mpl.ticker.FuncFormatter(formatoddticks) # 将定义的格式函数作为参数传递 locator = mpl.ticker.MaxNLocator(nbins=6) ax.xaxis.set_major_formatter(formatter) ax.xaxis.set_major_locator(locator) plt.show()
(5)单独设置某一刻度标签样式
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig = plt.figure() axes = fig.add_subplot(1, 1, 1) axes.plot(x1,y1) label_1 = axes.get_xticklabels()[3] label_1.set_color('red') label_1.set_fontsize(20) label_1.set_label(15) plt.show()
(6)主刻度、次刻度、网格
from matplotlib.ticker import MultipleLocator, FormatStrFormatter x1 = np.linspace(0.0, 100.0, 500) y1 = np.sin(0.1*np.pi*x1)*np.exp(-x1*0.01) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(x1,y1) xmajorLocator = MultipleLocator(20) #将x主刻度标签设置为20的倍数 xmajorFormatter = FormatStrFormatter('%5.1f') #设置x轴标签文本的格式 xminorLocator = MultipleLocator(5) #将x轴次刻度标签设置为5的倍数 ymajorLocator = MultipleLocator(0.5) #将y轴主刻度标签设置为0.5的倍数 ymajorFormatter = FormatStrFormatter('%1.1f') #设置y轴标签文本的格式 yminorLocator = MultipleLocator(0.1) #将此y轴次刻度标签设置为0.1的倍数 #设置主刻度标签的位置,标签文本的格式 ax.xaxis.set_major_locator(xmajorLocator) ax.xaxis.set_major_formatter(xmajorFormatter) ax.yaxis.set_major_locator(ymajorLocator) ax.yaxis.set_major_formatter(ymajorFormatter) #显示次刻度标签的位置,没有标签文本 ax.xaxis.set_minor_locator(xminorLocator) ax.yaxis.set_minor_locator(yminorLocator) ax.xaxis.grid(True, which='major') #x坐标轴的网格使用主刻度 ax.yaxis.grid(True, which='minor') #y坐标轴的网格使用次刻度 plt.show()
(7)刻度线样式设置
刻度线的样式主要是通过axes.tick_params()方法来设置,该方法主要参数如下:
- axis:取值为'x'、'y'或'both',指定设置哪一条轴上的刻度,'both'表示同时设置两条坐标轴,默认值为'both';
- which:取值为 'major'、'minor'、'both',分别代表设置主刻度线、副刻度线以及同时设置,默认值为'major';
- direction:值为'in'、'out'、'inout',分别代表刻度线显示在绘图区内侧、外侧以及同时显示;
- length和width:分别用于设置刻度线的长度和宽度;
- pad:用于设置刻度线与标签间的距离;
- color、labelcolor、colors:参数color、labelcolor、colors分别用于设置刻度线的颜色、刻度线标签的颜色以及同时设置刻度线及标签颜色;
- labelsize:参数labelsize用于设置刻度线标签的字体大小;
- bottom, top, left, right:参数bottom, top, left, right的值为布尔值,分别代表设置绘图区四个边框线上的的刻度线是否显示;
- labelbottom, labeltop, labelleft, labelright:参数labelbottom, labeltop, labelleft, labelright的值为布尔值,分别代表设置绘图区四个边框线上的刻度线标签是否显示
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig = plt.figure() axes = fig.add_subplot(1, 1, 1) axes.plot(x1,y1) axes.tick_params(axis='x', # 只设置x轴刻度 direction='in', # 刻度线朝内 length=3, width=3, # 长度和宽度 colors='green', # 颜色 labelsize=15, # 标签字体大小 top=True, left=True, labeltop=True, labelright=True ) axes.tick_params(axis='y', # 只设置y轴刻度 direction='in', # 刻度线朝内 length=6, width=3, # 长度和宽度 colors='red', # 颜色 labelsize=15, # 标签字体大小 top=True, right=True, labeltop=True, labelright=True ) plt.show()
(8)隐藏边框+设置坐标轴相交位置
x1 = np.linspace(0.0, 5.0, 100) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) fig = plt.figure() axes = fig.add_subplot(1, 1, 1) axes.plot(x1,y1) axes.spines['top'].set_color('none') axes.spines['right'].set_color('none') axes.spines["bottom"].set_position(("data", 0)) axes.spines["left"].set_position(("data", 0))
(9)时间日期刻度
import matplotlib.pyplot as plt import matplotlib.dates as mdates from datetime import datetime from matplotlib.ticker import MultipleLocator, FormatStrFormatter #销售数据 # dates=[20200101,20200201,20200301,20200401] dates=[20200101,20200102,20200103,20200104] y=[100,120.1,90.6,110] #将dates改成日期格式 x= [datetime.strptime(str(d), '%Y%m%d').date() for d in dates] #figure布局 fig, axes = plt.subplots(1, 2, figsize=(15, 2), tight_layout=True) axes[0].plot(x,y) #设置x轴主刻度格式 days_loc = mdates.DayLocator() #主刻度为每天 axes[0].xaxis.set_major_locator(days_loc) #设置主刻度 axes[0].xaxis.set_major_formatter(mdates.DateFormatter('%Y年%m月%d日')) #设置副刻度格式 # hoursLoc = mpl.dates.HourLocator(interval=6) # 每六小时显示刻度,但是未必是6的整数倍 hoursLoc = mpl.dates.HourLocator(byhour=[6, 12, 18, 24]) # 手动指定需要显示的副刻度 axes[0].xaxis.set_minor_locator(hoursLoc) axes[0].xaxis.set_minor_formatter(mdates.DateFormatter('%H')) # 如果副刻度不需要显示,注释这行 axes[0].tick_params(pad=15) #参数pad用于设置刻度线与标签间的距离 #销售数据 dates=[20200101,20200201,20200301,20200401] y=[100,120.1,90.6,110] #将dates改成日期格式 x= [datetime.strptime(str(d), '%Y%m%d').date() for d in dates] axes[1].plot(x,y) #设置x轴主刻度格式 months_loc = mpl.dates.MonthLocator() # 主刻度以月为单位 axes[1].xaxis.set_major_locator(months_loc) #设置主刻度 axes[1].xaxis.set_major_formatter(mdates.DateFormatter('%Y年%m月%d日')) #设置副刻度格式 days_loc = mpl.dates.DayLocator(interval=10) # 每10个单位长度显示一次副刻度,这种方法比上面的方法简单,但是未必是整数倍或对齐主刻度 axes[1].xaxis.set_minor_locator(days_loc) axes[1].xaxis.set_minor_formatter(mdates.DateFormatter('%d')) # 如果副刻度不需要显示,注释这行 axes[1].tick_params(pad=20) #参数pad用于设置刻度线与标签间的距离 plt.show()
除了上述示例中使用到的DayLocator、MonthLocator、HourLocator外,matplotlib提供了WeekdayLocator、YearLocator等几个类对周、年进行设置。
4 总结
本文提供了许多matplotlib作图过程中在文本、坐标轴设置上可能会遇上的场景示例,供参考使用。在本文撰写过程中也发现,对于文本和坐标轴的设置多种多样,就算是对同一元素实现同一效果的设置方法也有多种,本文只是例举的示例了一小部分。对于注释这类文本,本来也想说一说,但是感觉注释本就不太常用,且本文本身写的也有些乱,就不在继续添乱了。