Annotations¶
Annotations combine text with arrows to highlight specific features in your plot.
Basic Annotation¶
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 3))
ax.grid(True)
ax.set_xlim(-0.5, 3.5)
ax.set_ylim(-0.05, 0.25)
ax.axhline(0, xmin=-0.5, xmax=3.5)
# Plot a point
ax.plot(1, 0, "o")
# Annotate the point
ax.annotate(
"Annotation", # Text
fontsize=14,
family="serif",
xy=(1, 0), # Point to annotate
xytext=(+20, +50), # Text position offset
textcoords="offset points", # Offset in points from xy
arrowprops=dict(arrowstyle="->", connectionstyle="arc3, rad=.5")
)
plt.show()
annotate() Parameters¶
Key parameters:
ax.annotate(
text, # Annotation text
xy=(x, y), # Point to annotate
xytext=(x, y), # Text position
xycoords='data', # Coordinate system for xy
textcoords='data', # Coordinate system for xytext
fontsize=12,
fontweight='bold',
color='black',
ha='center', # Horizontal alignment
va='center', # Vertical alignment
arrowprops=dict(...) # Arrow properties
)
Arrow Styles¶
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(figsize=(10, 6))
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
arrow_styles = ['->', '-[', '|-|', '-|>', '<->', '<|-|>', 'fancy', 'simple', 'wedge']
for i, style in enumerate(arrow_styles):
y = 9 - i
ax.plot(2, y, 'ko', ms=5)
ax.annotate(
f"arrowstyle='{style}'",
xy=(2, y),
xytext=(5, y),
fontsize=10,
arrowprops=dict(arrowstyle=style, color='blue')
)
plt.show()
Connection Styles¶
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 6))
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
connection_styles = [
'arc3,rad=0',
'arc3,rad=0.3',
'arc3,rad=-0.3',
'angle,angleA=0,angleB=90',
'angle3,angleA=0,angleB=90',
'arc,angleA=0,angleB=90,armA=30,armB=30,rad=0'
]
for i, style in enumerate(connection_styles):
y = 9 - i * 1.5
ax.plot(2, y, 'ko', ms=5)
ax.annotate(
style[:20] + '...' if len(style) > 20 else style,
xy=(2, y),
xytext=(6, y),
fontsize=9,
arrowprops=dict(
arrowstyle='->',
connectionstyle=style,
color='green'
)
)
plt.show()
Coordinate Systems¶
Different coordinate systems for xycoords and textcoords:
| Value | Description |
|---|---|
'data' |
Data coordinates (default) |
'axes fraction' |
Fraction of axes (0-1) |
'figure fraction' |
Fraction of figure (0-1) |
'offset points' |
Offset in points from xy |
'offset pixels' |
Offset in pixels from xy |
Practical Example: Statistical Plot¶
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
df = 5
chi2_statistic = 12.5
fig, ax = plt.subplots()
# Plot chi-square distribution
x = np.linspace(0, 20, 200)
y = stats.chi2(df).pdf(x)
ax.plot(x, y, 'b-', lw=2)
ax.fill_between(x, y, where=(x >= chi2_statistic), alpha=0.3, color='red')
# Annotate the p-value region
xy = ((chi2_statistic + 15.0) / 2, 0.01)
xytext = (16.5, 0.10)
ax.annotate(
'p-value',
xy=xy,
xytext=xytext,
fontsize=15,
arrowprops=dict(color='k', width=0.2, headwidth=8)
)
ax.set_xlabel('$\\chi^2$')
ax.set_ylabel('Density')
ax.set_title(f'Chi-Square Distribution (df={df})')
plt.show()
Financial Data Annotation¶
import matplotlib.pyplot as plt
import pandas as pd
import yfinance as yf
def main():
ticker = 'AAPL'
data = yf.download(ticker, start='2023-01-01', end='2024-12-31')
fig, ax = plt.subplots(figsize=(12, 3))
ax.plot(data['Close'], label=ticker)
# Mark a specific date
date_to_mark = pd.to_datetime('2023-12-20')
price = data.loc[date_to_mark, 'Close']
ax.plot(date_to_mark, price, 'ro', ms=10)
ax.annotate(
'Dec 20, 2023',
xy=(date_to_mark, price),
xytext=(date_to_mark, price + 10),
fontsize=10,
ha='center',
arrowprops=dict(arrowstyle='->', color='red')
)
ax.legend()
plt.show()
if __name__ == "__main__":
main()
Key Takeaways¶
ax.annotate()adds text with an arrow to a pointxyis the point to annotatexytextis where the text appearsarrowpropscontrols arrow appearance- Use
arrowstylefor arrow head style - Use
connectionstylefor arrow path shape textcoords='offset points'is useful for relative positioning