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 6c1dcb5

Browse filesBrowse files
Update timeline example
1 parent 9faf231 commit 6c1dcb5
Copy full SHA for 6c1dcb5

File tree

Expand file treeCollapse file tree

2 files changed

+87
-45
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+87
-45
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
@@ -145,6 +145,7 @@ per-file-ignores =
145145
examples/lines_bars_and_markers/span_regions.py: E402
146146
examples/lines_bars_and_markers/stem_plot.py: E402
147147
examples/lines_bars_and_markers/step_demo.py: E402
148+
examples/lines_bars_and_markers/timeline.py: E402
148149
examples/misc/agg_buffer.py: E402
149150
examples/misc/anchored_artists.py: E501
150151
examples/misc/contour_manual.py: E501

‎examples/lines_bars_and_markers/timeline.py

Copy file name to clipboardExpand all lines: examples/lines_bars_and_markers/timeline.py
+86-45Lines changed: 86 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,57 +15,98 @@
1515
import matplotlib.dates as mdates
1616
from datetime import datetime
1717

18-
# A list of Matplotlib releases and their dates
19-
# Taken from https://api.github.com/repos/matplotlib/matplotlib/releases
20-
names = ['v2.2.2', 'v2.2.1', 'v2.2.0', 'v2.1.2', 'v2.1.1', 'v2.1.0', 'v2.0.2',
21-
'v2.0.1', 'v2.0.0', 'v1.5.3', 'v1.5.2', 'v1.5.1', 'v1.5.0', 'v1.4.3',
22-
'v1.4.2', 'v1.4.1', 'v1.4.0']
23-
24-
dates = ['2018-03-17T03:00:07Z', '2018-03-16T22:06:39Z',
25-
'2018-03-06T12:53:32Z', '2018-01-18T04:56:47Z',
26-
'2017-12-10T04:47:38Z', '2017-10-07T22:35:12Z',
27-
'2017-05-10T02:11:15Z', '2017-05-02T01:59:49Z',
28-
'2017-01-17T02:59:36Z', '2016-09-09T03:00:52Z',
29-
'2016-07-03T15:52:01Z', '2016-01-10T22:38:50Z',
30-
'2015-10-29T21:40:23Z', '2015-02-16T04:22:54Z',
31-
'2014-10-26T03:24:13Z', '2014-10-18T18:56:23Z',
32-
'2014-08-26T21:06:04Z']
33-
dates = [datetime.strptime(ii, "%Y-%m-%dT%H:%M:%SZ") for ii in dates]
18+
try:
19+
# Try to fetch a list of Matplotlib releases and their dates
20+
# from https://api.github.com/repos/matplotlib/matplotlib/releases
21+
import urllib.request
22+
import json
23+
24+
url = 'https://api.github.com/repos/matplotlib/matplotlib/releases'
25+
url += '?per_page=100'
26+
data = json.loads(urllib.request.urlopen(url, timeout=.4).read().decode())
27+
28+
dates = []
29+
names = []
30+
for item in data:
31+
if 'rc' not in item['tag_name'] and 'b' not in item['tag_name']:
32+
dates.append(item['published_at'].split("T")[0])
33+
names.append(item['tag_name'])
34+
except:
35+
# In case the above fails, e.g. because of missing internet connection
36+
# use the following lists as fallback.
37+
names = ['v2.2.4', 'v3.0.3', 'v3.0.2', 'v3.0.1', 'v3.0.0', 'v2.2.3',
38+
'v2.2.2', 'v2.2.1', 'v2.2.0', 'v2.1.2', 'v2.1.1', 'v2.1.0',
39+
'v2.0.2', 'v2.0.1', 'v2.0.0', 'v1.5.3', 'v1.5.2', 'v1.5.1',
40+
'v1.5.0', 'v1.4.3', 'v1.4.2', 'v1.4.1', 'v1.4.0']
41+
42+
dates = ['2019-02-26', '2019-02-26', '2018-11-10', '2018-11-10',
43+
'2018-09-18', '2018-08-10', '2018-03-17', '2018-03-16',
44+
'2018-03-06', '2018-01-18', '2017-12-10', '2017-10-07',
45+
'2017-05-10', '2017-05-02', '2017-01-17', '2016-09-09',
46+
'2016-07-03', '2016-01-10', '2015-10-29', '2015-02-16',
47+
'2014-10-26', '2014-10-18', '2014-08-26']
48+
49+
# Convert date strings (e.g. 2014-10-18) to datetime
50+
dates = [datetime.strptime(d, "%Y-%m-%d") for d in dates]
3451

3552
##############################################################################
36-
# Next, we'll iterate through each date and plot it on a horizontal line.
37-
# We'll add some styling to the text so that overlaps aren't as strong.
53+
# Next, we'll create a `~.Axes.stem` plot with some variation in levels as to
54+
# distinguish even close-by events.
55+
# For each event, we add a text label via `~.Axes.annotate`, which is offset
56+
# in units of points from the tip of the event line.
3857
#
3958
# Note that Matplotlib will automatically plot datetime inputs.
4059

41-
levels = np.array([-5, 5, -3, 3, -1, 1])
42-
fig, ax = plt.subplots(figsize=(8, 5))
43-
44-
# Create the base line
45-
start = min(dates)
46-
stop = max(dates)
47-
ax.plot((start, stop), (0, 0), 'k', alpha=.5)
48-
49-
# Iterate through releases annotating each one
50-
for ii, (iname, idate) in enumerate(zip(names, dates)):
51-
level = levels[ii % 6]
52-
vert = 'top' if level < 0 else 'bottom'
53-
54-
ax.scatter(idate, 0, s=100, facecolor='w', edgecolor='k', zorder=9999)
55-
# Plot a line up to the text
56-
ax.plot((idate, idate), (0, level), c='r', alpha=.7)
57-
# Give the text a faint background and align it properly
58-
ax.text(idate, level, iname,
59-
horizontalalignment='right', verticalalignment=vert, fontsize=14,
60-
backgroundcolor=(1., 1., 1., .3))
60+
61+
# Choose some nice levels
62+
levels = np.tile([-5, 5, -3, 3, -1, 1],
63+
int(np.ceil(len(dates)/6)))[:len(dates)]
64+
65+
# Create figure and plot a stem plot with the date
66+
fig, ax = plt.subplots(figsize=(8.8, 4), constrained_layout=True)
6167
ax.set(title="Matplotlib release dates")
62-
# Set the xticks formatting
63-
# format xaxis with 3 month intervals
64-
ax.get_xaxis().set_major_locator(mdates.MonthLocator(interval=3))
68+
69+
markerline, stemline, baseline = ax.stem(dates, levels,
70+
linefmt="C3-", basefmt="k-",
71+
use_line_collection=True)
72+
73+
plt.setp(markerline, mec="k", mfc="w", zorder=3)
74+
markerline.set_ydata(np.zeros(len(dates)))
75+
76+
# annotate lines
77+
vert = np.array(['top', 'bottom'])[(levels > 0).astype(int)]
78+
for d, l, r, va in zip(dates, levels, names, vert):
79+
ax.annotate(r, xy=(d, l), xytext=(-3, np.sign(l)*3),
80+
textcoords="offset points", va=va, ha="right")
81+
82+
# format xaxis with 4 month intervals
83+
ax.get_xaxis().set_major_locator(mdates.MonthLocator(interval=4))
6584
ax.get_xaxis().set_major_formatter(mdates.DateFormatter("%b %Y"))
66-
fig.autofmt_xdate()
85+
plt.setp(ax.get_xticklabels(), rotation=30, ha="right")
86+
87+
# remove y axis and spines
88+
ax.get_yaxis().set_visible(False)
89+
for spine in ["left", "top", "right"]:
90+
ax.spines[spine].set_visible(False)
6791

68-
# Remove components for a cleaner look
69-
plt.setp((ax.get_yticklabels() + ax.get_yticklines() +
70-
list(ax.spines.values())), visible=False)
92+
ax.margins(y=0.1)
7193
plt.show()
94+
95+
96+
#############################################################################
97+
#
98+
# ------------
99+
#
100+
# References
101+
# """"""""""
102+
#
103+
# The use of the following functions, methods and classes is shown
104+
# in this example:
105+
106+
import matplotlib
107+
matplotlib.axes.Axes.stem
108+
matplotlib.axes.Axes.annotate
109+
matplotlib.axis.Axis.set_major_locator
110+
matplotlib.axis.Axis.set_major_formatter
111+
matplotlib.dates.MonthLocator
112+
matplotlib.dates.DateFormatter

0 commit comments

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