Matplotlib數據可視化(3):文本與軸


 

在一幅圖表中,文本、坐標軸和圖像的是信息傳遞的核心,對着三者的設置是作圖這最為關心的內容,在上一篇博客中雖然列舉了一些設置方法,但沒有進行深入介紹,本文以圍繞如何對文本和坐標軸進行設置展開(對圖像的設置在后續介紹到各種圖繪制時介紹)。

這里所說的文本是指在使用matplotlib作圖過程中通過代碼的方式往圖中添加的各種文字,包括figure標題、axes標題、坐標軸標簽、坐標軸刻度標簽、注釋、普通文本等。軸設置指的是對與坐標軸相關的的元素的設置,例如顯示范圍、刻度、刻度標簽等。

In [1]:
from matplotlib import pyplot as plt
import numpy as np
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 中文字體支持
 

1 標題

 

(1)figure標題與axes標題

In [2]:
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)字體設置

In [3]:
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)設置水平距離

In [4]:
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)設置垂直距離

In [5]:
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)添加坐標軸標簽

In [6]:
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)與坐標軸間距

In [7]:
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)位置設置

In [8]:
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)字體設置

In [9]:
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)設置刻度標簽

In [10]:
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)刻度標簽顯示其他字符

In [11]:
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)刻度數量與格式

In [12]:
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)自定義是否顯示某刻度標簽

In [13]:
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)單獨設置某一刻度標簽樣式

In [14]:
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)主刻度、次刻度、網格

In [15]:
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的值為布爾值,分別代表設置繪圖區四個邊框線上的刻度線標簽是否顯示
In [16]:
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)隱藏邊框+設置坐標軸相交位置

In [17]:
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)時間日期刻度

In [18]:
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作圖過程中在文本、坐標軸設置上可能會遇上的場景示例,供參考使用。在本文撰寫過程中也發現,對於文本和坐標軸的設置多種多樣,就算是對同一元素實現同一效果的設置方法也有多種,本文只是例舉的示例了一小部分。對於注釋這類文本,本來也想說一說,但是感覺注釋本就不太常用,且本文本身寫的也有些亂,就不在繼續添亂了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM