A year with my cargo bike

| decision, life

Summary: Life with a cargo bike has been working out really well for our family.

Stroller

I used to walk for an hour to get to some of A+'s playdates, pushing her in the Thule bike trailer / stroller that she still fit into. I liked bringing popsicles during the summer so that A+ could share them with her friends, so I often balanced a small cooler on top of the stroller and walked as briskly as I could. The popsicles were usually still reasonably cold by the time I got to the park. We'd spend a few hours playing there, and then there would be another hour's walk back. A+ usually napped on the way, so it was a chance for me to listen to podcasts.

Car

Sometimes we biked to the playdate instead. That was much faster in terms of getting there, even with a popsicle break halfway through. Those popsicles were only for us, since I couldn't bring a cooler on my bike. Also, A+ was usually too tired to bike back, or it was too dark for her to be safe biking on the busy streets between the park and our house, so we often waited in the mall parking lot for W- to pick up A+ and her bike in his car. Then I biked back by myself.

Dumped

We'd been considering cargo bikes for a while, and eventually things lined up to make it possible. It was a carefully-considered decision. I did a bunch of test rides using different models of cargo bikes. My height (or lack of it) ruled out many of the models designed for taller people. A+ was quite vocal about her preference for the suspension on the R&M Load cargo bikes, and she liked the view from the front-loaders more than the longtails. I rented the Load 75 and the Load 60 to try them out, accidentally tipping over onto the side an embarrassing number of times; A+ was safely buckled in but very grumpy about it.

When we confirmed that a cargo bike fit into our life, I bought a Riese & Müller Load 75 from Curbside Cycle. We picked the Load 75 over the Load 60 because the rain cover was nicer and the extra room could give us more years of use as A+ grows.

Loaded up

I love it. Biking is my favourite way to get around. There's just something so cheerful about it. A+ and I sing as we go around town. We smile at dogs in sweaters. She takes pictures of trees. Sometimes there are cargo bikes in front of us as we wait at the traffic light, and we wave and nod.

We got the Bakkie bag, too. It's designed to tow a kid's bike. That way, A+ can bike wherever she wants. When she gets tired, she can hop into the cargo bike and I can buckle her bike into the Bakkie bag, towing it all the way home. We've been able to go on more bike adventures by ourselves and together with W- because we don't have to worry about exceeding A+'s range.

Hot chocolate

Since we could get to the playground in 15 minutes instead of 60, it was a lot easier to bring snacks to share. We pretty much kept the playground kids well-supplied with free popsicles (and the occasional much-coveted ice cream treat) all summer, and the ice packs came in handy for treating the occasional bumps too. We even brought disposable cups and insulated bottles of hot water for making hot chocolate and instant apple cider in the colder months.

Potting mix

Aside from taking A+ to a wider range of places, we've also used it to bring several bags of potting mix or a propane tank home from the hardware store, carry other bulky items, and take lots of stuff to the community environment days for recycling/donation.

We are very lucky to have cargo biking as an option. When people ask me how much it is, I ruefully tell them, "Well, it's less than a second car." We weren't actually choosing between this and a second car; even though W- rarely uses his car these days, I'm too anxious to drive. My brain gets a little squirrelly and is prone to attentional hiccups. I don't want a moment of distraction to result in someone's death or serious injury. I'm still on alert when I bike, but it feels a lot more like something I can handle. And biking is so fast and convenient. I don't have to nudge A+ out of a playdate so that we can make it out before the subway gets packed like sardines, or shepherd A+ back home from the subway station ("I'm tiiiired.").

I got the bike in November 2023. Here's how much I biked over the past year:

Month KM
Nov 208
Dec 157
Jan 69
Feb 78
Mar 176
Apr 82
May 106
Jun 143
Jul 135
Aug 96
Sep 212
Oct 120
2024-11-04T14:04:00.159647 image/svg+xml Matplotlib v3.6.3, https://matplotlib.org/
Figure 1: Graph of kilometres by month

I was pleasantly surprised that even during the cold months (and A+'s reluctance to go outside if it was very cold or slushy), and even during the schoolweek, we still managed to get out on the bike.

2024-11-04T13:43:31.432403 image/svg+xml Matplotlib v3.6.3, https://matplotlib.org/
Figure 2: Kilometres by date

I got data from the ebike-connect site using Spookfox using the code below.

Javascript code for extracting distances and times
[...document.querySelectorAll('.activities__ride-menu')].map((o) => {
  return {
    date: o.querySelector('.activities__menu-details > span').textContent,
    distance: o.querySelector('.activities__menu-distance-text').textContent.trim(),
    time: o.querySelector('.activities__menu-details > span:nth-child(2) > span:nth-child(2)').textContent,
  }
});
Emacs Lisp to group distance by month
(let ((by-month (seq-group-by
  (lambda (row)
    (let ((date (plist-get row :date)))
      (when (string-match "[0-9][0-9]\\.\\([0-9][0-9]\\)\\.\\([0-9][0-9]\\) [0-9][0-9]:[0-9][0-9]"
                          date)
        (format "20%s-%s-01"
                (match-string 2 date)
                (match-string 1 date)))))
  trips)))
  (append
   '(("Month" "Distance")
     hline)
   (mapcar
    (lambda (row)
      (list (format-time-string "%b" (date-to-time (car row)))
            (format
             "%d"
             (round (apply '+
                           (mapcar (lambda (entry) (string-to-number (plist-get entry :distance)))
                                   (cdr row)))))))
    (reverse (seq-filter (lambda (o) (string< (car o) "2024-11")) by-month)))))
Emacs Lisp to group distance by date
(let ((by-day (seq-group-by
  (lambda (row)
    (let ((date (plist-get row :date)))
      (when (string-match "\\([0-9][0-9]\\)\\.\\([0-9][0-9]\\)\\.\\([0-9][0-9]\\) [0-9][0-9]:[0-9][0-9]"
                          date)
        (format "20%s-%s-%s"
                (match-string 3 date)
                (match-string 2 date)
                (match-string 1 date)))))
  trips)))
  (json-encode (mapcar
   (lambda (row)
     (cons (car row)
           (format
            "%d"
            (round (apply '+
                          (mapcar (lambda (entry) (string-to-number (plist-get entry :distance)))
                                  (cdr row)))))))
   (reverse (seq-filter (lambda (o) (string< (car o) "2024-11")) by-day)))))
Python code for making a bar graph of distance by month
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import seaborn as sns
import json

data = trips
df = pd.DataFrame(data, columns=["Month", "Distance"])
df.set_index('Month')
df['Distance'] = df['Distance'].astype(float)
plt.figure(figsize=(8, 6), dpi=100)
sns.barplot(data=df, y='Distance', x='Month')
plt.savefig('biking-distance-by-month.svg')
Python code for making a heatmap
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import seaborn as sns
import json

start_date = datetime.datetime(2023, 11, 1)
end_date = datetime.datetime(2024, 11, 1)
dates = pd.date_range(start=start_date, end=end_date, freq='D')
data = json.loads(trips)
df = pd.DataFrame.from_dict(data, orient='index')
df.index = pd.to_datetime(df.index)
df[0] = df[0].astype(float)
# Create calendar heatmap
plt.figure(figsize=(16, 3), dpi=100)
pivoted = df.pivot_table(index=df.index.day_name(), columns=df.index.strftime('%Y-%W'))
all_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
pivoted.index = pd.Categorical(pivoted.index, all_days, ordered=True)
pivoted = pivoted.sort_index()
heatmap = sns.heatmap(
    pivoted,
    cmap="crest",
    linewidths=0.5,
    linecolor='white'
)

# Set the x-axis tick labels to show only the months
month_labels = df.index.strftime('%b').unique()
month_ticks = [i * 4 for i in range(len(month_labels))]
plt.xticks(
    month_ticks,
    month_labels,
    rotation=90
)
tick_positions = [i + 0.5 for i in range(len(all_days))]
plt.yticks(tick_positions, all_days)
plt.title('Distance on dates')
plt.xlabel('November 2023 - November 2024')
plt.ylabel('')
plt.xticks(rotation=90)
plt.savefig('biking-by-day.svg')

I like our cargo bike a lot. I hope to ride it for many years to come.

View org source for this post
You can comment with Disqus or you can e-mail me at sacha@sachachua.com.