在上一篇博文ID3決策樹算法中,繪制決策樹時,使用了Matplotlib的注解工具annotate,借此機會系統學習一下annotate的用法。
annotate用於在圖形上給數據添加文本注解,而且支持帶箭頭的划線工具,方便我們在合適的位置添加描述信息。
參數說明:
Axes.annotate(s, xy, *args, **kwargs)
- s:注釋文本的內容
- xy:被注釋的坐標點,二維元組形如(x,y)
- xytext:注釋文本的坐標點,也是二維元組,默認與xy相同
- xycoords:被注釋點的坐標系屬性,允許輸入的值如下
| 屬性值 | 含義 |
|---|---|
| 'figure points' | 以繪圖區左下角為參考,單位是點數 |
| 'figure pixels' | 以繪圖區左下角為參考,單位是像素數 |
| 'figure fraction' | 以繪圖區左下角為參考,單位是百分比 |
| 'axes points' | 以子繪圖區左下角為參考,單位是點數(一個figure可以有多個axex,默認為1個) |
| 'axes pixels' | 以子繪圖區左下角為參考,單位是像素數 |
| 'axes fraction' | 以子繪圖區左下角為參考,單位是百分比 |
| 'data' | 以被注釋的坐標點xy為參考 (默認值) |
| 'polar' | 不使用本地數據坐標系,使用極坐標系 |
- textcoords :注釋文本的坐標系屬性,默認與xycoords屬性值相同,也可設為不同的值。除了允許輸入xycoords的屬性值,還允許輸入以下兩種:
| 屬性值 | 含義 |
|---|---|
| 'offset points' | 相對於被注釋點xy的偏移量(單位是點) |
| 'offset pixels' | 相對於被注釋點xy的偏移量(單位是像素) |
arrowprops:箭頭的樣式,dict(字典)型數據,如果該屬性非空,則會在注釋文本和被注釋點之間畫一個箭頭。如果不設置'arrowstyle' 關鍵字,則允許包含以下關鍵字:
| 關鍵字 | 說明 |
|---|---|
| width | 箭頭的寬度(單位是點) |
| headwidth | 箭頭頭部的寬度(點) |
| headlength | 箭頭頭部的長度(點) |
| shrink | 箭頭兩端收縮的百分比(占總長) |
| ? | 任何 matplotlib.patches.FancyArrowPatch中的關鍵字 |
如果設置了‘arrowstyle’關鍵字,以上關鍵字就不能使用。允許的值有:
| 箭頭的樣式 | 屬性 |
|---|---|
'-' |
None |
'->' |
head_length=0.4,head_width=0.2 |
'-[' |
widthB=1.0,lengthB=0.2,angleB=None |
'|-|' |
widthA=1.0,widthB=1.0 |
'-|>' |
head_length=0.4,head_width=0.2 |
'<-' |
head_length=0.4,head_width=0.2 |
'<->' |
head_length=0.4,head_width=0.2 |
'<|-' |
head_length=0.4,head_width=0.2 |
'<|-|>' |
head_length=0.4,head_width=0.2 |
'fancy' |
head_length=0.4,head_width=0.4,tail_width=0.4 |
'simple' |
head_length=0.5,head_width=0.5,tail_width=0.2 |
'wedge' |
tail_width=0.3,shrink_factor=0.5 |
FancyArrowPatch的關鍵字包括:
| Key | Description |
|---|---|
| arrowstyle | 箭頭的樣式 |
| connectionstyle | 連接線的樣式 |
| relpos | 箭頭起始點相對注釋文本的位置,默認為 (0.5, 0.5),即文本的中心, (0,0)表示左下角,(1,1)表示右上角 |
| patchA | 箭頭起點處的圖形(matplotlib.patches對象),默認是注釋文字框 |
| patchB | 箭頭終點處的圖形(matplotlib.patches對象),默認為空 |
| shrinkA | 箭頭起點的縮進點數,默認為2 |
| shrinkB | 箭頭終點的縮進點數,默認為2 |
| mutation_scale | default is text size (in points) |
| mutation_aspect | default is 1. |
| ? | any key for matplotlib.patches.PathPatch |
- annotation_clip : 布爾值,可選參數,默認為空。設為True時,只有被注釋點在子圖區內時才繪制注釋;設為False時,無論被注釋點在哪里都繪制注釋。僅當xycoords為‘data’時,默認值空相當於True。
返回值:
Annotation對象
示例:
- 一個基本的注釋示例,設置了箭頭的顏色和縮進,感興趣的話可以以此為基礎嘗試更多的屬性和樣式。
import numpy as np import matplotlib.pyplot as plt fig, ax = plt.subplots() # 繪制一個余弦曲線 t = np.arange(0.0, 5.0, 0.01) s = np.cos(2*np.pi*t) line, = ax.plot(t, s, lw=2) # 繪制一個黑色,兩端縮進的箭頭 ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5), xycoords='data', arrowprops=dict(facecolor='black', shrink=0.05) ) ax.set_ylim(-2, 2) plt.show()
-

- 坐標轉換示例——在本例中,我們學習用不同的坐標體系繪制注釋。
-
import numpy as np import matplotlib.pyplot as plt # 以步長0.005繪制一個曲線 x = np.arange(0, 10, 0.005) y = np.exp(-x/2.) * np.sin(2*np.pi*x) fig, ax = plt.subplots() ax.plot(x, y) ax.set_xlim(0, 10) ax.set_ylim(-1, 1) # 被注釋點的數據軸坐標和所在的像素 xdata, ydata = 5, 0 xdisplay, ydisplay = ax.transData.transform_point((xdata, ydata)) # 設置注釋文本的樣式和箭頭的樣式 bbox = dict(boxstyle="round", fc="0.8") arrowprops = dict( arrowstyle = "->", connectionstyle = "angle,angleA=0,angleB=90,rad=10") # 設置偏移量 offset = 72 # xycoords默認為'data'數據軸坐標,對坐標點(5,0)添加注釋 # 注釋文本參考被注釋點設置偏移量,向左2*72points,向上72points ax.annotate('data = (%.1f, %.1f)'%(xdata, ydata), (xdata, ydata), xytext=(-2*offset, offset), textcoords='offset points', bbox=bbox, arrowprops=arrowprops) # xycoords以繪圖區左下角為參考,單位為像素 # 注釋文本參考被注釋點設置偏移量,向右0.5*72points,向下72points disp = ax.annotate('display = (%.1f, %.1f)'%(xdisplay, ydisplay), (xdisplay, ydisplay), xytext=(0.5*offset, -offset), xycoords='figure pixels', textcoords='offset points', bbox=bbox, arrowprops=arrowprops) plt.show()

- 極坐標上的注釋——在此例中,我們會在極坐標系繪圖,並在極坐標系設置被注釋點,以繪圖區的百分比為參數放置注釋文本。
import numpy as np import matplotlib.pyplot as plt # 繪制一個極地坐標,再以0.001為步長,畫一條螺旋曲線 fig = plt.figure() ax = fig.add_subplot(111, polar=True) r = np.arange(0,1,0.001) theta = 2 * 2*np.pi * r line, = ax.plot(theta, r, color='#ee8d18', lw=3) # 對索引為800處畫一個圓點,並做注釋 ind = 800 thisr, thistheta = r[ind], theta[ind] ax.plot([thistheta], [thisr], 'o') ax.annotate('a polar annotation', xy=(thistheta, thisr), # 被注釋點遵循極坐標系,坐標為角度和半徑 xytext=(0.05, 0.05), # 注釋文本放在繪圖區的0.05百分比處 textcoords='figure fraction', arrowprops=dict(facecolor='black', shrink=0.05),# 箭頭線為黑色,兩端縮進5% horizontalalignment='left',# 注釋文本的左端和低端對齊到指定位置 verticalalignment='bottom', ) plt.show()
- 不同樣式的注釋文本示例
import matplotlib.pyplot as plt # 設置繪圖區標題 fig = plt.figure() fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold') # 設置子繪圖區標題 ax = fig.add_subplot(111) fig.subplots_adjust(top=0.85) ax.set_title('axes title') # 設置x y坐標軸的標識 ax.set_xlabel('xlabel') ax.set_ylabel('ylabel') # 紅色、透明度0.5、邊框留白10 ax.text(3, 8, 'boxed italics text in data coords', style='italic', bbox={'facecolor':'red', 'alpha':0.5, 'pad':10}) # 文字中有數學公式 ax.text(2, 6, r'an equation: $E=mc^2$', fontsize=15) # 文字中有ASCII碼 ax.text(3, 2, 'unicode: Institut f\374r Festk\366rperphysik') # 轉換坐標系 ax.text(0.95, 0.01, 'colored text in axes coords', verticalalignment='bottom', horizontalalignment='right', transform=ax.transAxes, color='green', fontsize=15) # 在2,1處畫個圓點,添加注釋 ax.plot([2], [1], 'o') ax.annotate('annotate', xy=(2, 1), xytext=(3, 4), arrowprops=dict(facecolor='black', shrink=0.05)) ax.axis([0, 10, 0, 10]) plt.show()

參考:
官方文檔 https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.annotate.html#matplotlib.axes.Axes.annotate

