[Python3] Matplotlib —— (十) 文字與註釋


[ Matplotlib version: 3.2.1 ]


十一、文字與註釋

一些場景中,可視化需要輔之以少量文字提示(textual cue)和標籤。

(一)在圖中添加文字標籤

最基本的註釋(annotation)類型有座標軸標題與圖標題,此外,可以通過plt.text/ax.text命令手動添加註釋,它們可以在具體的x/y座標點上放上文字

  • ax.text方法需要一個x軸座標、一個y軸座標、一個字符串和一些可選參數,比如文字的顏色、字號、風格、對齊方式以及其他文字屬性
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('seaborn-whitegrid')
import numpy as np
import pandas as pd

案例:節假日對美國出生率的影響

  • 日均出生人數統計圖
    日均出生人數統計圖
# 在圖上增加文字標籤
# ha是水平對齊方式縮寫(horizonal alignment)
style = dict(size=10, color='gray')

ax.text('2012-1-1', 3950, "New Year's Day", **style)
ax.text('2012-7-4', 4250, "Independence Day", ha='center', **style)
ax.text('2012-9-4', 4850, "Labor Day", ha='center', **style)
ax.text('2012-10-31', 4600, "Halloween", ha='right', **style)
ax.text('2012-11-25', 4450, "Thanksgiving", ha='center', **style)
ax.text('2012-12-25', 3850, "Christmas", ha='right', **style)

# 設置座標軸標題
ax.set(title='USA births by day of year (1969-1988)',
       ylabel='average daily births')

# 設置x軸刻度值,讓月份居中顯示
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
ax.xaxis.set_minor_locator(mpl.dates.MonthLocator(bymonthday=15))
ax.xaxis.set_major_formatter(plt.NullFormatter())
ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter('%h'))

fig

在這裏插入圖片描述

(二)座標變換與文字位置

有時候需要將文字放在與數據無關的位置上,比如座標軸或者圖形中。在Matplotlib中,通過調整座標變換(transform)來實現。

任何圖形顯示框架都需要一些變換座標系的機制。

  • 例如:當一個位於(x,y)=(1,1)位置的點需要以某種方式顯示在圖上特定的位置時,就需要用屏幕的像素來表示
  • 用數學方法處理這種座標系變換很簡單,matplotlib.transforms子模塊中有一組工具可以實現類似功能

一共有三種解決這類問題的預定義變換方式:

  • ax.transData:以數據爲基準的座標變換
  • ax.transAxes:以座標軸爲基準的座標變換(以座標軸維度爲單位)
  • fig.transFigure:以圖形爲基準的座標變換(以圖形維度爲單位)

默認情況下,文字在各自的座標系中都是左對齊。

  • transData座標用x軸與y軸的標籤作爲數據座標
  • tranAxes座標以座標軸(下圖白色矩形)左下角的位置爲原點,按座標軸尺寸的比例呈現座標
  • transFigure座標以圖形(下圖灰色矩形)左下角的位置爲原點,按圖形尺寸的比例呈現座標
# 用三種變換方式將文字畫在不同的位置
fig, ax = plt.subplots(facecolor='lightgray')
ax.axis([0, 10, 0, 10])

# transform=ax.transData是默認值
ax.text(1, 5, ". Data: (1, 5)", transform=ax.transData)
ax.text(0.5, 0.1, ". Axes: (0.5, 0.1)", transform=ax.transAxes)
ax.text(0.2, 0.2, ". Figure: (0.2, 0.2)", transform=fig.transFigure)

在這裏插入圖片描述

  • 注意:如果改變了座標軸上下限,那麼只有transData座標會受影響,其他座標系都不變
  • 在Jupyter Notebook中,可以把%matplotlib inline改成%matplotlib notebook,然後用圖形菜單與圖形交互(拖動按鈕)就可以實現座標軸平移
# 改變座標軸上下限
ax.set_xlim(0, 2)
ax.set_ylim(-6, 6)
fig

在這裏插入圖片描述

(三)箭頭與註釋

除了刻度線和文字,簡單的箭頭也是一種有用的註釋標籤。

  • (不推薦)plt.arrow()函數可以實現這個功能,但它創建出的箭頭是SVG向量圖對象,會隨着圖形分辨率的變化而改變,最終得出的可能不是想要的結果。
  • (推薦)plt.annotate()函數既可以創建文字,也可以創建箭頭,而且它創建的箭頭能夠進行非常靈活的配置。
fig, ax = plt.subplots()

x = np.linspace(0, 20, 1000)
ax.plot(x, np.cos(x))
ax.axis('equal')

# 箭頭的風格是通過arrowprops字典控制的
ax.annotate('local maximum', xy=(6.28, 1), xytext=(10, 4),
            arrowprops=dict(facecolor='black', shrink=0.05))

ax.annotate('local minimum', xy=(5 * np.pi, -1), xytext=(2, -6),
            arrowprops=dict(arrowstyle="->",
                            connectionstyle="angle3,angleA=0,angleB=-90"))

在這裏插入圖片描述

用前面的案例演示箭頭註釋:

fig, ax = plt.subplots(figsize=(12, 4))
births_by_date.plot(ax=ax)

# 在圖上增加箭頭標籤
ax.annotate("New Year's Day", xy=('2012-1-1', 4100), xycoords='data',
            xytext=(50, -30), textcoords='offset points',
            arrowprops=dict(arrowstyle="->",
                            connectionstyle="arc3,rad=-0.2"))

ax.annotate("Independence Day", xy=('2012-7-4', 4250), xycoords='data',
            bbox=dict(boxstyle="round", fc="none", ec="gray"),
            xytext=(10, -40), textcoords='offset points', ha='center',
            arrowprops=dict(arrowstyle="->"))

ax.annotate('Labor Day', xy=('2012-9-4', 4850), xycoords='data', ha='center',
            xytext=(0, -20), textcoords='offset points')
ax.annotate('', xy=('2012-9-1', 4850), xytext=('2012-9-7', 4850),
            xycoords='data', textcoords='data',
            arrowprops={'arrowstyle': '|-|,widthA=0.2,widthB=0.2', })

ax.annotate('Halloween', xy=('2012-10-31', 4600), xycoords='data',
            xytext=(-80, -40), textcoords='offset points',
            arrowprops=dict(arrowstyle="fancy",
                            fc="0.6", ec="none",
                            connectionstyle="angle3,angleA=0,angleB=-90"))

ax.annotate('Thanksgiving', xy=('2012-11-25', 4500), xycoords='data',
            xytext=(-120, 60), textcoords='offset points',
            bbox=dict(boxstyle="round4,pad=.5", fc="0.9"),
            arrowprops=dict(arrowstyle="->",
                            connectionstyle="angle,angleA=0,angleB=80,rad=20"))

ax.annotate('Christmas', xy=('2012-12-25', 3850), xycoords='data',
            xytext=(-30, 0), textcoords='offset points',
            size=13, ha='right', va="center",
            bbox=dict(boxstyle="round", alpha=0.1),
            arrowprops=dict(arrowstyle="wedge,tail_width=0.5", alpha=0.1))

# 設置座標軸標題
ax.set(title='USA births by day of year (1969-1988)',
       ylabel='average daily births')

# 設置x軸刻度值,讓月份居中顯示
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
ax.xaxis.set_minor_locator(mpl.dates.MonthLocator(bymonthday=15))
ax.xaxis.set_major_formatter(plt.NullFormatter())
ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter('%h'))

ax.set_ylim(3600, 5400)

在這裏插入圖片描述

  • 箭頭和文本框的配置功能非常細緻,這樣就可以創建自己想要的箭頭風格了。
  • 不過,功能太過細緻往往也就意味着操作起來比較複雜,如果要做一個產品級的圖形,可能要耗費大量時間。

Matplotlib 相關閱讀:

[Python3] Matplotlib —— (一) 入門基礎
[Python3] Matplotlib —— (二) 簡易線形圖
[Python3] Matplotlib —— (三) 簡易散點圖
[Python3] Matplotlib —— (四) 可視化異常處理
[Python3] Matplotlib —— (五) 密度圖與等高線圖
[Python3] Matplotlib —— (六) 頻次直方圖、數據區間劃分和分佈密度
[Python3] Matplotlib —— (七) 配置圖例
[Python3] Matplotlib —— (八) 配置顏色條
[Python3] Matplotlib —— (九) 多子圖



總結自《Python數據科學手冊》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章