在一幅圖表中,文本、坐標(biāo)軸和圖像的是信息傳遞的核心,對(duì)著三者的設(shè)置是作圖這最為關(guān)心的內(nèi)容,在上一篇博客中雖然列舉了一些設(shè)置方法,但沒(méi)有進(jìn)行深入介紹,本文以圍繞如何對(duì)文本和坐標(biāo)軸進(jìn)行設(shè)置展開(kāi)(對(duì)圖像的設(shè)置在后續(xù)介紹到各種圖繪制時(shí)介紹)。
這里所說(shuō)的文本是指在使用matplotlib作圖過(guò)程中通過(guò)代碼的方式往圖中添加的各種文字,包括figure標(biāo)題、axes標(biāo)題、坐標(biāo)軸標(biāo)簽、坐標(biāo)軸刻度標(biāo)簽、注釋、普通文本等。軸設(shè)置指的是對(duì)與坐標(biāo)軸相關(guān)的的元素的設(shè)置,例如顯示范圍、刻度、刻度標(biāo)簽等。
from matplotlib import pyplot as pltimport numpy as npimport matplotlib as mpl mpl.rcParams['font.sans-serif' ] = ['SimHei' ] # 中文字體支持
1 標(biāo)題 (1)figure標(biāo)題與axes標(biāo)題
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標(biāo)題' ) ax1.set_title('ax1-標(biāo)題' ) ax2.set_title('ax2-標(biāo)題' ) plt.show()
(2)字體設(shè)置
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標(biāo)題' , color='red' , fontsize=20 ) font = FontProperties() # 字體類(lèi) font.set_family('serif' ) font.set_name('SimHei' ) font.set_style('italic' ) ax1.set_title('ax1-標(biāo)題' ,fontproperties=font) # 傳遞字體類(lèi)設(shè)置字體 ax2.set_title('ax2-標(biāo)題' , color='green' ) plt.show()
(3)設(shè)置水平距離
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標(biāo)題' , color='red' , fontsize=20 ) locs = ['left' , 'center' , 'right' ]for ax, loc in zip(axs, locs): ax.plot(x1, y1) ax.set_title('axes標(biāo)題 ' + loc, loc=loc, color='blue' ) plt.show()
(4)設(shè)置垂直距離
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('垂直距離測(cè)試圖-標(biāo)題' , pad=30 ) plt.show()
2 坐標(biāo)軸標(biāo)簽 (1)添加坐標(biāo)軸標(biāo)簽
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('時(shí)間 [s]' ) ax.set_ylabel('阻尼振蕩 [V]' ) plt.show()
(2)與坐標(biāo)軸間距
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('時(shí)間 [s]' , labelpad=28 ) ax.set_ylabel('阻尼振蕩 [V]' , labelpad=28 ) # 指定labelpad參數(shù)設(shè)置距離 plt.show()
(3)位置設(shè)置
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 ), # 位置,坐標(biāo)軸總長(zhǎng)的比例 horizontalalignment='left' ) # 對(duì)齊方式,左對(duì)齊,右對(duì)齊 ax.set_ylabel('Damped oscillation [V]' ) plt.show()
(4)字體設(shè)置
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' ) # 可以通過(guò)出不同參數(shù)來(lái)設(shè)置字體 ax.set_ylabel('Damped oscillation [V]' , fontproperties=font, color='red' ) # 也可以直接傳遞一個(gè)FontProperties類(lèi)實(shí)例設(shè)置字體 plt.show()
3 刻度和刻度標(biāo)簽 (1)設(shè)置刻度標(biāo)簽
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 ]) # 這是默認(rèn)的,系統(tǒng)會(huì)根據(jù)傳遞的數(shù)據(jù)自動(dòng)設(shè)置刻度 axs[1 ].xaxis.set_ticks([0 , 1 , 3 , 5 ,]) # 傳遞列表 axs[2 ].xaxis.set_ticks(np.arange(0. , 5.1 , 2.0 )) # 每0.5個(gè)單位間隔顯示 axs[3 ].xaxis.set_ticks(np.arange(0. , 5.1 , 0.5 )) # 每2個(gè)單位顯示 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)刻度標(biāo)簽顯示其他字符
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(['第一天' , '第二天' , '第三天' , '第四天' , '第五天' ], # 這里的字符列表必須與上面一行的刻度列表一一對(duì)應(yīng) color='red' , fontsize=15 , # 直接設(shè)置樣式,這里與其他設(shè)置text的方法一樣 rotation=30 ) # 旋轉(zhuǎn)角度 plt.show()
(3)刻度數(shù)量與格式
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' ) # 設(shè)置顯示精度格式 locator = mpl.ticker.MaxNLocator(nbins=3 ) # 設(shè)置顯示刻度的數(shù)量 axes.xaxis.set_major_formatter(formatter) axes.xaxis.set_major_locator(locator) plt.show()
(4)自定義是否顯示某刻度標(biāo)簽
x1 = np.linspace(0.0 , 10.0 , 100 ) y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)def formatoddticks (x, pos) : """ 如果是3的倍數(shù),則顯示空 """ if x % 3 : return '%1.2f' % x else : return '' # 可以設(shè)置成其它字符 fig, ax = plt.subplots(figsize=(5 , 3 ), tight_layout=True ) ax.plot(x1, y1) formatter = mpl.ticker.FuncFormatter(formatoddticks) # 將定義的格式函數(shù)作為參數(shù)傳遞 locator = mpl.ticker.MaxNLocator(nbins=6 ) ax.xaxis.set_major_formatter(formatter) ax.xaxis.set_major_locator(locator) plt.show()
(5)單獨(dú)設(shè)置某一刻度標(biāo)簽樣式
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)主刻度、次刻度、網(wǎng)格
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主刻度標(biāo)簽設(shè)置為20的倍數(shù) xmajorFormatter = FormatStrFormatter('%5.1f' ) #設(shè)置x軸標(biāo)簽文本的格式 xminorLocator = MultipleLocator(5 ) #將x軸次刻度標(biāo)簽設(shè)置為5的倍數(shù) ymajorLocator = MultipleLocator(0.5 ) #將y軸主刻度標(biāo)簽設(shè)置為0.5的倍數(shù) ymajorFormatter = FormatStrFormatter('%1.1f' ) #設(shè)置y軸標(biāo)簽文本的格式 yminorLocator = MultipleLocator(0.1 ) #將此y軸次刻度標(biāo)簽設(shè)置為0.1的倍數(shù) #設(shè)置主刻度標(biāo)簽的位置,標(biāo)簽文本的格式 ax.xaxis.set_major_locator(xmajorLocator) ax.xaxis.set_major_formatter(xmajorFormatter) ax.yaxis.set_major_locator(ymajorLocator) ax.yaxis.set_major_formatter(ymajorFormatter)#顯示次刻度標(biāo)簽的位置,沒(méi)有標(biāo)簽文本 ax.xaxis.set_minor_locator(xminorLocator) ax.yaxis.set_minor_locator(yminorLocator) ax.xaxis.grid(True , which='major' ) #x坐標(biāo)軸的網(wǎng)格使用主刻度 ax.yaxis.grid(True , which='minor' ) #y坐標(biāo)軸的網(wǎng)格使用次刻度 plt.show()
(7)刻度線樣式設(shè)置
刻度線的樣式主要是通過(guò)axes.tick_params()方法來(lái)設(shè)置,該方法主要參數(shù)如下:
axis:取值為'x'、'y'或'both',指定設(shè)置哪一條軸上的刻度,'both'表示同時(shí)設(shè)置兩條坐標(biāo)軸,默認(rèn)值為'both'; which:取值為 'major'、'minor'、'both',分別代表設(shè)置主刻度線、副刻度線以及同時(shí)設(shè)置,默認(rèn)值為'major'; direction:值為'in'、'out'、'inout',分別代表刻度線顯示在繪圖區(qū)內(nèi)側(cè)、外側(cè)以及同時(shí)顯示; length和width:分別用于設(shè)置刻度線的長(zhǎng)度和寬度; pad:用于設(shè)置刻度線與標(biāo)簽間的距離; color、labelcolor、colors:參數(shù)color、labelcolor、colors分別用于設(shè)置刻度線的顏色、刻度線標(biāo)簽的顏色以及同時(shí)設(shè)置刻度線及標(biāo)簽顏色; labelsize:參數(shù)labelsize用于設(shè)置刻度線標(biāo)簽的字體大小; bottom, top, left, right:參數(shù)bottom, top, left, right的值為布爾值,分別代表設(shè)置繪圖區(qū)四個(gè)邊框線上的的刻度線是否顯示; labelbottom, labeltop, labelleft, labelright:參數(shù)labelbottom, labeltop, labelleft, labelright的值為布爾值,分別代表設(shè)置繪圖區(qū)四個(gè)邊框線上的刻度線標(biāo)簽是否顯示 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' , # 只設(shè)置x軸刻度 direction='in' , # 刻度線朝內(nèi) length=3 , width=3 , # 長(zhǎng)度和寬度 colors='green' , # 顏色 labelsize=15 , # 標(biāo)簽字體大小 top=True , left=True , labeltop=True , labelright=True ) axes.tick_params(axis='y' , # 只設(shè)置y軸刻度 direction='in' , # 刻度線朝內(nèi) length=6 , width=3 , # 長(zhǎng)度和寬度 colors='red' , # 顏色 labelsize=15 , # 標(biāo)簽字體大小 top=True , right=True , labeltop=True , labelright=True ) plt.show()
(8)隱藏邊框+設(shè)置坐標(biāo)軸相交位置
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)時(shí)間日期刻度
import matplotlib.pyplot as pltimport matplotlib.dates as mdatesfrom datetime import datetimefrom matplotlib.ticker import MultipleLocator, FormatStrFormatter #銷(xiāo)售數(shù)據(jù) # 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)#設(shè)置x軸主刻度格式 days_loc = mdates.DayLocator() #主刻度為每天 axes[0 ].xaxis.set_major_locator(days_loc) #設(shè)置主刻度 axes[0 ].xaxis.set_major_formatter(mdates.DateFormatter('%Y年%m月%d日' ))#設(shè)置副刻度格式 # hoursLoc = mpl.dates.HourLocator(interval=6) # 每六小時(shí)顯示刻度,但是未必是6的整數(shù)倍 hoursLoc = mpl.dates.HourLocator(byhour=[6 , 12 , 18 , 24 ]) # 手動(dòng)指定需要顯示的副刻度 axes[0 ].xaxis.set_minor_locator(hoursLoc) axes[0 ].xaxis.set_minor_formatter(mdates.DateFormatter('%H' )) # 如果副刻度不需要顯示,注釋這行 axes[0 ].tick_params(pad=15 ) #參數(shù)pad用于設(shè)置刻度線與標(biāo)簽間的距離 #銷(xiāo)售數(shù)據(jù) 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)#設(shè)置x軸主刻度格式 months_loc = mpl.dates.MonthLocator() # 主刻度以月為單位 axes[1 ].xaxis.set_major_locator(months_loc) #設(shè)置主刻度 axes[1 ].xaxis.set_major_formatter(mdates.DateFormatter('%Y年%m月%d日' ))#設(shè)置副刻度格式 days_loc = mpl.dates.DayLocator(interval=10 ) # 每10個(gè)單位長(zhǎng)度顯示一次副刻度,這種方法比上面的方法簡(jiǎn)單,但是未必是整數(shù)倍或?qū)R主刻度 axes[1 ].xaxis.set_minor_locator(days_loc) axes[1 ].xaxis.set_minor_formatter(mdates.DateFormatter('%d' )) # 如果副刻度不需要顯示,注釋這行 axes[1 ].tick_params(pad=20 ) #參數(shù)pad用于設(shè)置刻度線與標(biāo)簽間的距離 plt.show()
除了上述示例中使用到的DayLocator、MonthLocator、HourLocator外,matplotlib提供了WeekdayLocator、YearLocator等幾個(gè)類(lèi)對(duì)周、年進(jìn)行設(shè)置。
4 總結(jié) 本文提供了許多matplotlib作圖過(guò)程中在文本、坐標(biāo)軸設(shè)置上可能會(huì)遇上的場(chǎng)景示例,供參考使用。在本文撰寫(xiě)過(guò)程中也發(fā)現(xiàn),對(duì)于文本和坐標(biāo)軸的設(shè)置多種多樣,就算是對(duì)同一元素實(shí)現(xiàn)同一效果的設(shè)置方法也有多種,本文只是例舉的示例了一小部分。對(duì)于注釋這類(lèi)文本,本來(lái)也想說(shuō)一說(shuō),但是感覺(jué)注釋本就不太常用,且本文本身寫(xiě)的也有些亂,就不在繼續(xù)添亂了。
作者:奧辰 Github:https://github.com/ChenHuabin321