Looking at my blog post stats by year
| blogging
I was curious about the shape of my blog over the
years, excluding Emacs News and my link-heavy
weekly/monthly reviews. It started off with lots
of little posts like the way other weblogs were
also quick links and notes. As weblogs morphed
into blogs with more text, I also settled down
into fewer, longer posts with lots of code
(analyzed by looking for <pre>
blocks). I wrote
much less after A+ was born. Interestingly, I've
been shifting towards longer posts with more
images.
- Blog posts exclude permalinks that match
emacs-news|review|week-ending
, which casts a bit of a wide net but should give me the general shape of things. - Total words per year and average words per post both exclude code snippets.
Here's how I got those numbers:
(append '(("Year" "Posts" "Total words" "Words per post" "Posts with pre" "Posts with images") hline) (cl-loop for i from 2001 to 2024 collect (let* ((default-directory (expand-file-name (number-to-string i) "~/proj/static-blog/blog")) (exclude (shell-quote-argument "emacs-news|review|week-ending")) (files (format "find . -name '*.html' | grep -v -e '%s' | " exclude)) (posts (string-to-number (string-trim (shell-command-to-string (concat files "wc -l"))))) (words (string-to-number (replace-regexp-in-string "TOTAL: " "" (shell-command-to-string (concat files "xargs ~/bin/count-words | grep TOTAL"))))) (posts-with-images (string-to-number (string-trim (shell-command-to-string (concat files "xargs grep -l '<img' | wc -l"))))) (posts-with-pre (string-to-number (string-trim (shell-command-to-string (concat files "xargs grep -l '<pre' | wc -l")))))) (list i posts words (/ words posts) posts-with-images posts-with-pre))))
Year | Posts | Total words | Words per post | Posts with pre | Posts with images |
---|---|---|---|---|---|
2001 | 3 | 438 | 146 | 0 | 0 |
2002 | 31 | 4336 | 139 | 0 | 0 |
2003 | 863 | 64953 | 75 | 0 | 59 |
2004 | 967 | 125789 | 130 | 2 | 98 |
2005 | 679 | 135334 | 199 | 4 | 40 |
2006 | 869 | 171042 | 196 | 19 | 42 |
2007 | 489 | 107011 | 218 | 33 | 32 |
2008 | 380 | 121158 | 318 | 85 | 57 |
2009 | 400 | 175692 | 439 | 81 | 20 |
2010 | 335 | 160289 | 478 | 93 | 19 |
2011 | 324 | 163274 | 503 | 93 | 28 |
2012 | 286 | 124300 | 434 | 111 | 12 |
2013 | 273 | 173021 | 633 | 172 | 11 |
2014 | 272 | 186788 | 686 | 138 | 30 |
2015 | 173 | 133682 | 772 | 82 | 36 |
2016 | 25 | 11560 | 462 | 13 | 6 |
2017 | 37 | 24063 | 650 | 6 | 2 |
2018 | 66 | 46827 | 709 | 7 | 8 |
2019 | 18 | 13054 | 725 | 3 | 6 |
2020 | 13 | 6791 | 522 | 4 | 5 |
2021 | 31 | 17389 | 560 | 8 | 16 |
2022 | 21 | 11264 | 536 | 4 | 9 |
2023 | 68 | 47188 | 693 | 26 | 52 |
2024 | 74 | 58439 | 789 | 27 | 40 |
And here's how I plotted the charts:
import pandas as pd import matplotlib.pyplot as plt df = pd.DataFrame(data[1:], columns=data[0]) # Create a figure with subplots fig, (ax1, ax4, ax2, ax3) = plt.subplots(4, 1, figsize=(10, 12)) fig.suptitle('Blog Statistics by Year', fontsize=16) # Plot Posts ax1.bar(df['Year'], df['Posts'], color='lightblue', label='Other posts') ax1.bar(df['Year'], df['Posts with pre'] , color='darkblue', label='With preformatted blocks') ax1.set_title('Number of posts per year') ax1.set_ylabel('Posts') ax1.legend() # Plot Posts ax4.bar(df['Year'], df['Posts'], color='lightblue', label='Other posts') ax4.bar(df['Year'], df['Posts with images'] , color='darkgreen', label='With images') ax4.set_title('Number of posts per year') ax4.set_ylabel('Posts') ax4.legend() # Plot Total Words ax2.bar(df['Year'], df['Total words'], color='lightblue') ax2.set_title('Total words per year') ax2.set_ylabel('Total words') # Plot Words per Post ax3.bar(df['Year'], df['Words per post'], color='lightblue') ax3.set_title('Average words per post') ax3.set_ylabel('Words per post') ax3.set_xlabel('Year') # Adjust layout and display plt.savefig(f)