Created
June 17, 2020 23:19
-
-
Save jsundram/ef0543b7c86128faba2c81b887459eaf to your computer and use it in GitHub Desktop.
Histogram of Dates by Day of Year -- https://stackoverflow.com/questions/62391648/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from datetime import datetime, timedelta | |
import random | |
import matplotlib.pyplot as plt | |
import matplotlib.dates as dates | |
def make_data(): | |
random.seed(0) # Make it repeatable | |
s = datetime(2020, 1, 1) # Pick a leap year! | |
days = [s + timedelta(days=i) for i in range(366)] | |
values = [random.randint(5, 30) for _ in days] | |
return days, values | |
def plot_by_day(days, values): | |
plt.style.use('Solarize_Light2') | |
fig = plt.figure(figsize=(20, 4), dpi=150) | |
ax = fig.add_subplot(111) | |
# add space for a second x-axis (not sure what a good value for bottom is) | |
fig.subplots_adjust(bottom=0.2) | |
ax.bar(days, values, align='edge', width=1, linewidth=0, alpha=.8) | |
ax2 = ax.twiny() | |
# Time hierarchy: Month / day (1/15), then day (8/22) | |
# Axis 2: Month | |
ax2.xaxis.set_major_locator(dates.MonthLocator()) | |
ax2.xaxis.set_major_formatter(dates.DateFormatter('%b')) | |
# Axis 1: Major (Days 1/15) | |
ax.xaxis.set_major_locator(dates.DayLocator(bymonthday=[1, 15])) | |
ax.xaxis.set_major_formatter(dates.DateFormatter('%-d')) | |
ax.xaxis.set_tick_params(labelsize=8) | |
ax.set_xlim(days[0], days[-1] + timedelta(hours=23)) | |
# Axis 1: Minor (Days 8 / 22) | |
ax.xaxis.set_minor_locator(dates.DayLocator(bymonthday=[8, 22])) | |
ax.xaxis.set_minor_formatter(dates.DateFormatter('%-d')) | |
ax.xaxis.set_tick_params(which="minor", labelsize=5) | |
# This is a lot of work just to move the second axis to the bottom | |
# of the chart (we made room for it with subplots_adjust above) | |
ax2.set_xlim(ax.get_xlim()) | |
ax2.spines["bottom"].set_position(("axes", -0.05)) # position of text. | |
ax2.spines["bottom"].set_visible(False) # don't show the axis line | |
ax2.xaxis.set_ticks_position("bottom") | |
ax2.xaxis.set_label_position("bottom") | |
ax2.xaxis.set_tick_params(grid_visible=False) # already have ax's grid | |
for label in ax2.xaxis.get_ticklabels(): | |
label.set_horizontalalignment('left') | |
# ax2.patch.set_visible(False) | |
# for sp in ax2.spines.values(): sp.set_visible(False) | |
# just go with it and use title twice. | |
ax.set_title("Day of Year Chart") | |
ax.set_title( | |
"{:,} data points".format(len(values)), | |
loc='right', fontsize=8, color='gray') | |
ax2.set_xlabel("Date") | |
ax.set_ylabel("Count") | |
fig.savefig( | |
'plot_by_day.png', | |
facecolor=fig.get_facecolor(), | |
edgecolor='none' | |
) | |
def main(): | |
days, values = make_data() | |
plot_by_day(days, values) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output looks like this: