Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ddde7e8

Browse filesBrowse files
authored
Merge pull request #10841 from jklymak/enh-new-date-formatter
ENH: new date formatter
2 parents 18a8389 + a76c70f commit ddde7e8
Copy full SHA for ddde7e8

File tree

Expand file treeCollapse file tree

6 files changed

+559
-26
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+559
-26
lines changed

‎.flake8

Copy file name to clipboardExpand all lines: .flake8
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ per-file-ignores =
240240
examples/text_labels_and_annotations/tex_demo.py: E402
241241
examples/text_labels_and_annotations/watermark_text.py: E402
242242
examples/ticks_and_spines/auto_ticks.py: E501
243+
examples/ticks_and_spines/date_concise_formatter.py: E402
243244
examples/user_interfaces/canvasagg.py: E402
244245
examples/user_interfaces/embedding_in_gtk3_panzoom_sgskip.py: E402
245246
examples/user_interfaces/embedding_in_gtk3_sgskip.py: E402
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
:orphan:
2+
3+
New date formatter: `~.dates.ConciseDateFormatter`
4+
--------------------------------------------------
5+
6+
The automatic date formatter used by default can be quite verbose. A new
7+
formatter can be accessed that tries to make the tick labels appropriately
8+
concise.
9+
10+
.. plot::
11+
12+
import datetime
13+
import matplotlib.pyplot as plt
14+
import matplotlib.dates as mdates
15+
import numpy as np
16+
17+
# make a timeseries...
18+
base = datetime.datetime(2005, 2, 1)
19+
dates = np.array([base + datetime.timedelta(hours= 2 * i)
20+
for i in range(732)])
21+
N = len(dates)
22+
np.random.seed(19680801)
23+
y = np.cumsum(np.random.randn(N))
24+
25+
lims = [(np.datetime64('2005-02'), np.datetime64('2005-04')),
26+
(np.datetime64('2005-02-03'), np.datetime64('2005-02-15')),
27+
(np.datetime64('2005-02-03 11:00'), np.datetime64('2005-02-04 13:20'))]
28+
fig, axs = plt.subplots(3, 1, constrained_layout=True)
29+
for nn, ax in enumerate(axs):
30+
# activate the formatter here.
31+
locator = mdates.AutoDateLocator()
32+
formatter = mdates.ConciseDateFormatter(locator)
33+
ax.xaxis.set_major_locator(locator)
34+
ax.xaxis.set_major_formatter(formatter)
35+
36+
ax.plot(dates, y)
37+
ax.set_xlim(lims[nn])
38+
axs[0].set_title('Concise Date Formatter')
39+
40+
plt.show()
+183Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
"""
2+
================================================
3+
Formatting date ticks using ConciseDateFormatter
4+
================================================
5+
6+
Finding good tick values and formatting the ticks for an axis that
7+
has date data is often a challenge. `~.dates.ConciseDateFormatter` is
8+
meant to improve the strings chosen for the ticklabels, and to minimize
9+
the strings used in those tick labels as much as possible.
10+
11+
.. note::
12+
13+
This formatter is a candidate to become the default date tick formatter
14+
in future versions of Matplotlib. Please report any issues or
15+
suggestions for improvement to the github repository or mailing list.
16+
17+
"""
18+
import datetime
19+
import matplotlib.pyplot as plt
20+
import matplotlib.dates as mdates
21+
import numpy as np
22+
23+
#############################################################################
24+
# First, the default formatter.
25+
26+
base = datetime.datetime(2005, 2, 1)
27+
dates = np.array([base + datetime.timedelta(hours=(2 * i))
28+
for i in range(732)])
29+
N = len(dates)
30+
np.random.seed(19680801)
31+
y = np.cumsum(np.random.randn(N))
32+
33+
fig, axs = plt.subplots(3, 1, constrained_layout=True, figsize=(6, 6))
34+
lims = [(np.datetime64('2005-02'), np.datetime64('2005-04')),
35+
(np.datetime64('2005-02-03'), np.datetime64('2005-02-15')),
36+
(np.datetime64('2005-02-03 11:00'), np.datetime64('2005-02-04 13:20'))]
37+
for nn, ax in enumerate(axs):
38+
ax.plot(dates, y)
39+
ax.set_xlim(lims[nn])
40+
# rotate_labels...
41+
for label in ax.get_xticklabels():
42+
label.set_rotation(40)
43+
label.set_horizontalalignment('right')
44+
axs[0].set_title('Default Date Formatter')
45+
plt.show()
46+
47+
#############################################################################
48+
# The default date formater is quite verbose, so we have the option of
49+
# using `~.dates.ConciseDateFormatter`, as shown below. Note that
50+
# for this example the labels do not need to be rotated as they do for the
51+
# default formatter because the labels are as small as possible.
52+
53+
fig, axs = plt.subplots(3, 1, constrained_layout=True, figsize=(6, 6))
54+
for nn, ax in enumerate(axs):
55+
locator = mdates.AutoDateLocator(minticks=3, maxticks=7)
56+
formatter = mdates.ConciseDateFormatter(locator)
57+
ax.xaxis.set_major_locator(locator)
58+
ax.xaxis.set_major_formatter(formatter)
59+
60+
ax.plot(dates, y)
61+
ax.set_xlim(lims[nn])
62+
axs[0].set_title('Concise Date Formatter')
63+
64+
plt.show()
65+
66+
#############################################################################
67+
# If all calls to axes that have dates are to be made using this converter,
68+
# it is probably most convenient to use the units registry where you do
69+
# imports:
70+
71+
import matplotlib.units as munits
72+
converter = mdates.ConciseDateConverter()
73+
munits.registry[np.datetime64] = converter
74+
munits.registry[datetime.date] = converter
75+
munits.registry[datetime.datetime] = converter
76+
77+
fig, axs = plt.subplots(3, 1, figsize=(6, 6), constrained_layout=True)
78+
for nn, ax in enumerate(axs):
79+
ax.plot(dates, y)
80+
ax.set_xlim(lims[nn])
81+
axs[0].set_title('Concise Date Formatter')
82+
83+
plt.show()
84+
85+
#############################################################################
86+
# Localization of date formats
87+
# ============================
88+
#
89+
# Dates formats can be localized if the default formats are not desirable by
90+
# manipulating one of three lists of strings.
91+
#
92+
# The ``formatter.formats`` list of formats is for the normal tick labels,
93+
# There are six levels: years, months, days, hours, minutes, seconds.
94+
# The ``formatter.offset_formats`` is how the "offset" string on the right
95+
# of the axis is formatted. This is usually much more verbose than the tick
96+
# labels. Finally, the ``formatter.zero_formats`` are the formats of the
97+
# ticks that are "zeros". These are tick values that are either the first of
98+
# the year, month, or day of month, or the zeroth hour, minute, or second.
99+
# These are usually the same as the format of
100+
# the ticks a level above. For example if the axis limts mean the ticks are
101+
# mostly days, then we label 1 Mar 2005 simply with a "Mar". If the axis
102+
# limits are mostly hours, we label Feb 4 00:00 as simply "Feb-4".
103+
#
104+
# Note that these format lists can also be passed to `.ConciseDateFormatter`
105+
# as optional kwargs.
106+
#
107+
# Here we modify the labels to be "day month year", instead of the ISO
108+
# "year month day":
109+
110+
fig, axs = plt.subplots(3, 1, constrained_layout=True, figsize=(6, 6))
111+
112+
for nn, ax in enumerate(axs):
113+
locator = mdates.AutoDateLocator()
114+
formatter = mdates.ConciseDateFormatter(locator)
115+
formatter.formats = ['%y', # ticks are mostly years
116+
'%b', # ticks are mostly months
117+
'%d', # ticks are mostly days
118+
'%H:%M', # hrs
119+
'%H:%M', # min
120+
'%S.%f', ] # secs
121+
# these are mostly just the level above...
122+
formatter.zero_formats = [''] + formatter.formats[:-1]
123+
# ...except for ticks that are mostly hours, then it is nice to have
124+
# month-day:
125+
formatter.zero_formats[3] = '%d-%b'
126+
127+
formatter.offset_formats = ['',
128+
'%Y',
129+
'%b %Y',
130+
'%d %b %Y',
131+
'%d %b %Y',
132+
'%d %b %Y %H:%M', ]
133+
ax.xaxis.set_major_locator(locator)
134+
ax.xaxis.set_major_formatter(formatter)
135+
136+
ax.plot(dates, y)
137+
ax.set_xlim(lims[nn])
138+
axs[0].set_title('Concise Date Formatter')
139+
140+
plt.show()
141+
142+
#############################################################################
143+
# Registering a converter with localization
144+
# =========================================
145+
#
146+
# `.ConciseDateFormatter` doesn't have rcParams entries, but localization
147+
# can be accomplished by passing kwargs to `~.ConciseDateConverter` and
148+
# registering the datatypes you will use with the units registry:
149+
150+
import datetime
151+
152+
formats = ['%y', # ticks are mostly years
153+
'%b', # ticks are mostly months
154+
'%d', # ticks are mostly days
155+
'%H:%M', # hrs
156+
'%H:%M', # min
157+
'%S.%f', ] # secs
158+
# these can be the same, except offset by one level....
159+
zero_formats = [''] + formats[:-1]
160+
# ...except for ticks that are mostly hours, then its nice to have month-day
161+
zero_formats[3] = '%d-%b'
162+
offset_formats = ['',
163+
'%Y',
164+
'%b %Y',
165+
'%d %b %Y',
166+
'%d %b %Y',
167+
'%d %b %Y %H:%M', ]
168+
169+
converter = mdates.ConciseDateConverter(formats=formats,
170+
zero_formats=zero_formats,
171+
offset_formats=offset_formats)
172+
173+
munits.registry[np.datetime64] = converter
174+
munits.registry[datetime.date] = converter
175+
munits.registry[datetime.datetime] = converter
176+
177+
fig, axs = plt.subplots(3, 1, constrained_layout=True, figsize=(6, 6))
178+
for nn, ax in enumerate(axs):
179+
ax.plot(dates, y)
180+
ax.set_xlim(lims[nn])
181+
axs[0].set_title('Concise Date Formatter registered non-default')
182+
183+
plt.show()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.