10000 Merge pull request #21873 from StefRe/date_index_formatter · matplotlib/matplotlib@1a3be58 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1a3be58

Browse files
authored
Merge pull request #21873 from StefRe/date_index_formatter
DOC: Update and consolidate Custom Tick Formatter for Time Series example
2 parents f0995e1 + 5ad9546 commit 1a3be58

File tree

5 files changed

+91
-108
lines changed

5 files changed

+91
-108
lines changed

examples/lines_bars_and_markers/scatter_demo2.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
import matplotlib.pyplot as plt
1010
import matplotlib.cbook as cbook
1111

12-
# Load a numpy record array from yahoo csv data with fields date, open, close,
13-
# volume, adj_close from the mpl-data/example directory. The record array
14-
# stores the date as an np.datetime64 with a day unit ('D') in the date column.
12+
# Load a numpy record array from yahoo csv data with fields date, open, high,
13+
# low, close, volume, adj_close from the mpl-data/sample_data directory. The
14+
# record array stores the date as an np.datetime64 with a day unit ('D') in
15+
# the date column.
1516
price_data = (cbook.get_sample_data('goog.npz', np_load=True)['price_data']
1617
.view(np.recarray))
1718
price_data = price_data[-250:] # get the most recent 250 trading days

examples/text_labels_and_annotations/date.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@
2626
import matplotlib.dates as mdates
2727
import matplotlib.cbook as cbook
2828

29-
# Load a numpy structured array from yahoo csv data with fields date, open,
30-
# close, volume, adj_close from the mpl-data/example directory. This array
31-
# stores the date as an np.datetime64 with a day unit ('D') in the 'date'
32-
# column.
29+
# Load a numpy record array from yahoo csv data with fields date, open, high,
30+
# low, close, volume, adj_close from the mpl-data/sample_data directory. The
31+
# record array stores the date as an np.datetime64 with a day unit ('D') in
32+
# the date column.
3333
data = cbook.get_sample_data('goog.npz', np_load=True)['price_data']
3434

3535
fig, axs = plt.subplots(3, 1, figsize=(6.4, 7), constrained_layout=True)

examples/text_labels_and_annotations/date_index_formatter.py

Lines changed: 0 additions & 56 deletions
This file was deleted.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"""
2+
=====================================
3+
Custom tick formatter for time series
4+
=====================================
5+
6+
.. redirect-from:: /gallery/text_labels_and_annotations/date_index_formatter
7+
.. redirect-from:: /gallery/ticks/date_index_formatter2
8+
9+
When plotting daily data, e.g., financial time series, one often wants
10+
to leave out days on which there is no data, for instance weekends, so that
11+
the data are plotted at regular intervals without extra spaces for the days
12+
with no data.
13+
The example shows how to use an 'index formatter' to achieve the desired plot.
14+
"""
15+
16+
import numpy as np
17+
import matplotlib.pyplot as plt
18+
import matplotlib.cbook as cbook
19+
import matplotlib.lines as ml
20+
from matplotlib.dates import DateFormatter, DayLocator
21+
from matplotlib.ticker import Formatter
22+
23+
24+
# Load a numpy record array from yahoo csv data with fields date, open, high,
25+
# low, close, volume, adj_close from the mpl-data/sample_data directory. The
26+
# record array stores the date as an np.datetime64 with a day unit ('D') in
27+
# the date column (``r.date``).
28+
r = (cbook.get_sample_data('goog.npz', np_load=True)['price_data']
29+
.view(np.recarray))
30+
r = r[:9] # get the first 9 days
31+
32+
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6, 6),
33+
constrained_layout={'hspace': .15})
34+
35+
# First we'll do it the default way, with gaps on weekends
36+
ax1.plot(r.date, r.adj_close, 'o-')
37+
38+
# Highlight gaps in daily data
39+
gaps = np.flatnonzero(np.diff(r.date) > np.timedelta64(1, 'D'))
40+
for gap in r[['date', 'adj_close']][np.stack((gaps, gaps + 1)).T]:
41+
ax1.plot(gap.date, gap.adj_close, 'w--', lw=2)
42+
ax1.legend(handles=[ml.Line2D([], [], ls='--', label='Gaps in daily data')])
43+
44+
ax1.set_title("Plot y at x Coordinates")
45+
ax1.xaxis.set_major_locator(DayLocator())
46+
ax1.xaxis.set_major_formatter(DateFormatter('%a'))
47+
48+
49+
# Next we'll write a custom index formatter. Below we will plot
50+
# the data against an index that goes from 0, 1, ... len(data). Instead of
51+
# formatting the tick marks as integers, we format as times.
52+
def format_date(x, _):
53+
try:
54+
# convert datetime64 to datetime, and use datetime's strftime:
55+
return r.date[round(x)].item().strftime('%a')
56+
except IndexError:
57+
pass
58+
59+
# Create an index plot (x defaults to range(len(y)) if omitted)
60+
ax2.plot(r.adj_close, 'o-')
61+
62+
ax2.set_title("Plot y at Index Coordinates Using Custom Formatter")
63+
ax2.xaxis.set_major_formatter(format_date) # internally creates FuncFormatter
64+
65+
#############################################################################
66+
# Instead of passing a function into `.Axis.set_major_formatter` you can use
67+
# any other callable, e.g. an instance of a class that implements __call__:
68+
69+
70+
class MyFormatter(Formatter):
71+
def __init__(self, dates, fmt='%a'):
72+
self.dates = dates
73+
self.fmt = fmt
74+
75+
def __call__(self, x, pos=0):
76+
"""Return the label for time x at position pos."""
77+
try:
78+
return self.dates[round(x)].item().strftime(self.fmt)
79+
except IndexError:
80+
pass
81+
82+
83+
ax2.xaxis.set_major_formatter(MyFormatter(r.date, '%a'))

examples/ticks/date_index_formatter2.py

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)
0