|
54 | 54 | # Convert date strings (e.g. 2014-10-18) to datetime
|
55 | 55 | dates= [datetime.strptime(d,"%Y-%m-%d")fordindates]
|
56 | 56 |
|
| 57 | +dates,names=zip(*sorted(zip(dates,names)))# Sort by increasing date. |
| 58 | + |
57 | 59 | # %%
|
58 | 60 | # Next, we'll create a stem plot with some variation in levels as to
|
59 | 61 | # distinguish even close-by events. We add markers on the baseline for visual
|
|
64 | 66 | #
|
65 | 67 | # Note that Matplotlib will automatically plot datetime inputs.
|
66 | 68 |
|
67 |
| - |
68 |
| -# Choose some nice levels |
69 |
| -levels=np.tile([-5,5,-3,3,-1,1], |
70 |
| -int(np.ceil(len(dates)/6)))[:len(dates)] |
71 |
| - |
72 |
| -# Create figure and plot a stem plot with the date |
| 69 | +# Choose some nice levels: alternate minor releases between top and bottom, and |
| 70 | +# progressievly shorten the stems for bugfix releases. |
| 71 | +levels= [] |
| 72 | +major_minor_releases=sorted({name[:4]fornameinnames}) |
| 73 | +fornameinnames: |
| 74 | +major_minor=name[:4] |
| 75 | +bugfix=int(name[5]) |
| 76 | +h=1+0.8* (5-bugfix) |
| 77 | +level=hifmajor_minor_releases.index(major_minor)%2==0else-h |
| 78 | +levels.append(level) |
| 79 | + |
| 80 | +# The figure and the axes. |
73 | 81 | fig,ax=plt.subplots(figsize=(8.8,4),layout="constrained")
|
74 | 82 | ax.set(title="Matplotlib release dates")
|
75 | 83 |
|
76 |
| -ax.vlines(dates,0,levels,color="tab:red")# The vertical stems. |
77 |
| -ax.plot(dates,np.zeros_like(dates),"-o", |
78 |
| -color="k",markerfacecolor="w")# Baseline and markers on it. |
79 |
| - |
80 |
| -# annotate lines |
| 84 | +# The vertical stems. |
| 85 | +ax.vlines(dates,0,levels, |
| 86 | +color=[("tab:red",1ifname.endswith(".0")else.5)fornameinnames]) |
| 87 | +# The baseline. |
| 88 | +ax.axhline(0,c="k") |
| 89 | +# The markers on the baseline. |
| 90 | +minor_dates= [datefordate,nameinzip(dates,names)ifname[-1]=='0'] |
| 91 | +bugfix_dates= [datefordate,nameinzip(dates,names)ifname[-1]!='0'] |
| 92 | +ax.plot(bugfix_dates,np.zeros_like(bugfix_dates),"ko",mfc="white") |
| 93 | +ax.plot(minor_dates,np.zeros_like(minor_dates),"ko",mfc="tab:red") |
| 94 | + |
| 95 | +# Annotate the lines. |
81 | 96 | ford,l,rinzip(dates,levels,names):
|
82 | 97 | ax.annotate(r,xy=(d,l),
|
83 | 98 | xytext=(-3,np.sign(l)*3),textcoords="offset points",
|
84 |
| -horizontalalignment="right", |
85 |
| -verticalalignment="bottom"ifl>0else"top") |
| 99 | +verticalalignment="bottom"ifl>0else"top", |
| 100 | +bbox=dict(boxstyle='square',pad=0,lw=0,fc=(1,1,1,0.7))) |
86 | 101 |
|
87 |
| -# format x-axis with 4-month intervals |
88 |
| -ax.xaxis.set_major_locator(mdates.MonthLocator(interval=4)) |
89 |
| -ax.xaxis.set_major_formatter(mdates.DateFormatter("%b %Y")) |
90 |
| -plt.setp(ax.get_xticklabels(),rotation=30,ha="right") |
| 102 | +ax.yaxis.set(major_locator=mdates.YearLocator(), |
| 103 | +major_formatter=mdates.DateFormatter("%Y")) |
91 | 104 |
|
92 |
| -#removey-axis and spines |
| 105 | +#Remove they-axis andsomespines. |
93 | 106 | ax.yaxis.set_visible(False)
|
94 | 107 | ax.spines[["left","top","right"]].set_visible(False)
|
95 | 108 |
|
|