# 8.12 文本和注解

``````%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('seaborn-whitegrid')
import numpy as np
import pandas as pd
``````

## 示例： 美国新生儿的假期效应

``````births = pd.read_csv('data/births.csv')

quartiles = np.percentile(births['births'], [25, 50, 75])
mu, sig = quartiles[1], 0.74 * (quartiles[2] - quartiles[0])
births = births.query('(births > @mu - 5 * @sig) & (births < @mu + 5 * @sig)')

births['day'] = births['day'].astype(int)

births.index = pd.to_datetime(10000 * births.year +
100 * births.month +
births.day, format='%Y%m%d')
births_by_date = births.pivot_table('births',
[births.index.month, births.index.day])
births_by_date.index = [pd.datetime(2012, month, day)
for (month, day) in births_by_date.index]

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

When we're communicating data like this, it is often useful to annotate certain features of the plot to draw the reader's attention. This can be done manually with the `plt.text`/`ax.text` command, which will place text at a particular x/y value:

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

# 向绘图添加标签
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'));
``````

`ax.text`方法接受`x`位置，`y`位置，字符串，然后是可选关键字，指定文本的颜色，大小，样式，对齐方式和其他属性。在这里，我们使用`ha='right'``ha='center'`，其中`ha`是 horizonal alignment 的缩写。可用选项的更多信息，请参阅`plt.text()``mpl.text.Text()`的文档字符串。

## 变换和文本位置

• `ax.transData`：数据坐标相关的变换
• `ax.transAxes`：轴域（以轴域维度为单位）相关的变换
• `fig.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`坐标给出了关联`x`轴和`y`轴标签的常用数据坐标。`transAxes`坐标给出了相对于轴域左下角（这里是白框）的位置，作为轴域大小的比例。`transFigure`坐标是相似的，但是指定相对于图左下角（这里是灰框）的位置，作为图形大小的比例。

``````ax.set_xlim(0, 2)
ax.set_ylim(-6, 6)
fig
``````

## 箭头和标注

``````%matplotlib inline

fig, ax = plt.subplots()

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

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="->",

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',
arrowprops=dict(arrowstyle="->",

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);
``````