Reputation: 1665
I have an index array (x) of dates (datetime objects) and an array of actual values (y: bond prices). Doing the following:
plot(x,y)
produces a perfectly fine time series graph with the x-axis labeled with the dates. No problem so far. But I want to add text on certain dates. For example, on 2009-10-31, I wish to display the text "Event 1" with an arrow pointing to the y value at that date.
I have read through the Matplotlib documentation on text() and annotate() to no avail.
Upvotes: 49
Views: 47642
Reputation: 23141
Newer versions of matplotlib (e.g. 3.7.0) doesn't require explicit date2num
calls anymore. Just pass a point on the plot directly as xy=
to annotate()
.
from datetime import datetime
import matplotlib.pyplot as plt
x = [datetime(2009, 5, 1), datetime(2010, 6, 1),
datetime(2011, 4, 1), datetime(2012, 6, 1)]
y = [1, 3, 2, 5]
fig, ax = plt.subplots(facecolor='white')
ax.plot(x, y, linestyle='--')
ax.annotate('Test', xy=(x[1], y[1]), # <---- directly pass the point position
xytext=(-15, 15), textcoords='offset points',
arrowprops={'arrowstyle': '->'})
fig.autofmt_xdate()
A more terse (but less flexible) solution is to use text()
to annotate. Again, no need to perform a datetime-to-number conversion; just pass the point as is.
plt.plot(x, y, linestyle='--')
plt.text(x[1], y[1], 'Test') # use x-y coordinate values as is
plt.xticks(plt.xticks()[0][::2]);
Upvotes: 2
Reputation: 284602
Matplotlib uses an internal floating point format for dates.
You just need to convert your date to that format (using matplotlib.dates.date2num
or matplotlib.dates.datestr2num
) and then use annotate
as usual.
As a somewhat excessively fancy example:
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
x = [dt.datetime(2009, 05, 01), dt.datetime(2010, 06, 01),
dt.datetime(2011, 04, 01), dt.datetime(2012, 06, 01)]
y = [1, 3, 2, 5]
fig, ax = plt.subplots()
ax.plot_date(x, y, linestyle='--')
ax.annotate('Test', (mdates.date2num(x[1]), y[1]), xytext=(15, 15),
textcoords='offset points', arrowprops=dict(arrowstyle='-|>'))
fig.autofmt_xdate()
plt.show()
Upvotes: 89