GeistHaus
log in · sign up

https://nsaunders.wordpress.com/feed

rss
10 posts
Polling state
Status active
Last polled May 19, 2026 02:26 UTC
Next poll May 19, 2026 23:59 UTC
Poll interval 86400s
Last-Modified Sun, 05 Apr 2026 00:45:58 GMT

Posts

What’s changed?
environmentspace scienceworld newsartemis iiclimateextinction
Andy Saunders writes: A couple of things come to mind. The planet on the right contains, on average, around 70% fewer animals than the planet on the left. The atmosphere of the planet on the right also contains around 100 ppm, or 30%, more CO2 than the planet on the left. It seems to me … Continue reading What’s changed?
Show full content

Andy Saunders writes:

Left – Apollo 17, 1972
Right – Artemis II, 2026

Two photographs taken by one of us, of all of us, over half a century apart.

What's changed? pic.twitter.com/it1Ab2GVdz

— Andy Saunders – Apollo Remastered (@AndySaunders_1) April 3, 2026

A couple of things come to mind. The planet on the right contains, on average, around 70% fewer animals than the planet on the left.

The atmosphere of the planet on the right also contains around 100 ppm, or 30%, more CO2 than the planet on the left.

It seems to me that in many ways, humankind as a whole has not protected our Blue Marble very well in the 50-odd years between these images. Perhaps the next generation can do better.

nsaunders
http://nsaunders.wordpress.com/?p=5737
Extensions
Creating custom (non-Font Awesome) icons for a Jekyll-based website
computingprogrammingsoftwarechirpyfontjekyllthemes
This one is pretty niche even by my standards. Notes largely for my own benefit, but they may be useful if you: I’ll assume that you have git-cloned jekyll-theme-chirpy, run bundle and are able to serve the site on a local machine by running bundle exec jekyll serve. On opening 127.0.0.1:4000 in a browser, the … Continue reading Creating custom (non-Font Awesome) icons for a Jekyll-based website
Show full content

This one is pretty niche even by my standards. Notes largely for my own benefit, but they may be useful if you:

  • are creating a Jekyll-based website or blog
  • specifically, a site using the Chirpy theme or one based on it
  • and you want to add, at the bottom of the left sidebar, a custom icon i.e. one that cannot be added to the contact.yml file using a Font Awesome icon

I’ll assume that you have git-cloned jekyll-theme-chirpy, run bundle and are able to serve the site on a local machine by running bundle exec jekyll serve. On opening 127.0.0.1:4000 in a browser, the bottom of the left sidebar looks something like this:

The icons for Github, X/Twitter, mail and RSS are provided via Font Awesome. They are specified in the contact.yml file, like so:

- type: github
  icon: "fab fa-github"

Which is great – but what if you’d like to add a link to a resource that doesn’t have a Font Awesome icon? Specifically, in my case, a link to my iNaturalist profile? Here are the steps.

1. Locate or prepare your icon in SVG format

There are SVG files of the iNaturalist icon online – here for example – but I found that some of them didn’t work well in subsequent steps, and I wanted grayscale. So I downloaded a PNG file, converted it to grayscale and then used an online PNG to SVG conversion tool. There are several of these available and I found that they all work differently and again, don’t always generate files that work well in later steps. I used this one with the ‘Internal 1’ filter.

The final result:

2. Convert the SVG file to a font

Conversion to font is achieved using the tool IconMoon. Click on ‘Import Icons’ at the top of the page and upload your SVG file. By default it will be named ‘Untitled Set’. Next, click on ‘Generate Font’ at the bottom of the page. You’ll see a page with a preview of your icon. If all looks good, click on ‘Download’ at the bottom of the page, which downloads a ZIP file named icomoon.zip.

3. Copy the font icon files to the appropriate locations

Unzipping the ZIP file from step 2 generates a folder, icomoon, with a number of files and sub-folders inside.

Copy the folder named fonts to the assets folder of your local jekyll-theme-chirpy git clone.

Copy the file named style.css to the assets/css folder of your local jekyll-theme-chirpy git clone.

4. Edit files

Now we need to edit three files in our local jekyll-theme-chirpy.

4.1 _includes/head.html

Somewhere between the <head> tags – near the bottom is good – add these lines:

<!-- Web Font -->
  <link rel="stylesheet" href="{{ site.data.origin[type].webfonts | relative_url }}">
  <link rel="stylesheet" href="{{ '/assets/css/style.css' | relative_url }}">

4.2 style.css

Edit the top of this file so as the path to fonts is relative. It should look like this:

@font-face {
  font-family: 'icomoon';
  src: url('../fonts/icomoon.eot?ptv5da');
  src: url('../fonts/icomoon.eot?ptv5da#iefix') format('embedded-opentype'),
    url('../fonts/icomoon.ttf?ptv5da') format('truetype'),
    url('../fonts/icomoon.woff?ptv5da') format('woff'),
    url('../fonts/icomoon.svg?ptv5da#icomoon') format('svg');
  font-weight: normal;
  font-style: normal;
  font-display: block;
}

Note that further down, we have the specification for the icon font:

.icon-inat4:before {
  content: "\e900";
}

My SVG file was named inat4.svg and so the icon font is also named inat4. This is also important for the final edit.

4.3 contact.yml

Edit contact.yml, placing the specification for your custom icon in your desired order. Mine comes last: I’ve removed the icons and links for X/Twitter, email and RSS, and added an icon and link for Stack Overflow. So the full set, including my custom iNaturalist icon, looks like this:

- type: linkedin
  icon: 'fab fa-linkedin'   # icons powered by <https://fontawesome.com/>
  url:  'https://www.linkedin.com/in/nfwsaunders/'

- type: github
  icon: "fab fa-github"

- type: stack-overflow
  icon: 'fab fa-stack-overflow'
  url:  'https://stackoverflow.com/users/89482/neilfws'                  

- type: inaturalist
  icon: 'icon-inat4'
  url:  'https://www.inaturalist.org/people/neilfws'                  

5. We’re done!

If everything goes to plan you can fire up the local Jekyll server, open the site in a browser and there is your custom icon and link:

Last words

With thanks to user lamininA1: most of the instructions in this post are taken directly from their contribution to this discussion.

nsaunders
http://nsaunders.wordpress.com/?p=5711
Extensions
Directional markers in R/leaflet
programmingRstatisticsgeospatialgpsleafletrstatstutorial
So you have used the excellent exiftool to extract all of the GPS-related information from a directory of photos in JPG format and write to a CSV file: You’ve used R/leaflet to plot coordinates (latitude and longitude) before, but what about that tag named GPSImgDirection? It would be nice to have some kind of marker … Continue reading Directional markers in R/leaflet
Show full content

So you have used the excellent exiftool to extract all of the GPS-related information from a directory of photos in JPG format and write to a CSV file:

exiftool '-*GPS*' -ext jpg -csv . > outfile.csv

You’ve used R/leaflet to plot coordinates (latitude and longitude) before, but what about that tag named GPSImgDirection? It would be nice to have some kind of marker which indicates the direction in which you were facing when the photo was taken.

For me, a Google search provided hints but not one single, obvious straightforward solution to this problem (the generative AI effect? time will tell…), so here’s what I’ve put together from several sources, in particular this StackOverflow post.

The key points are:

  • use awesomeIcons() to create a directional icon which can be rotated
  • add the icons to your map using addAwesomeMarkers()

Here’s some example code which uses the Font Awesome icon long-arrow-up. Since “up” (north) corresponds to zero degrees, applying a rotation corresponding to GPSImgDirection should result in the correct orientation for the marker. The GPS-related tags in this case come from an iPhone 13.

library(readr)
library(leaflet)
library(sp)

outfile <- read_csv("outfile.csv")

# create dataset
# ugly but it works
dataset <- outfile %>% 
  mutate(GPSLatitude = str_replace(GPSLatitude, " deg", "d"), 
         GPSLatitude = GPSLatitude %>% 
         char2dms() %>% 
           as.numeric(), 
         GPSLongitude = str_replace(GPSLongitude, " deg", "d"), 
         GPSLongitude = GPSLongitude %>% 
           char2dms() %>% 
           as.numeric(),
         GPSHPositioningError = str_replace(GPSHPositioningError, " m", ""),
         GPSHPositioningError = GPSHPositioningError %>% 
           as.numeric()) %>% 
  select(latitude = GPSLatitude, 
         longitude = GPSLongitude, 
         GPSTimeStamp, 
         GPSImgDirection, 
         GPSHPositioningError)

# create the marker icons
icons <- awesomeIcons(iconRotate = dataset$GPSImgDirection,
                      icon = "long-arrow-up",
                      library = "fa",
                      markerColor = "white", 
                      squareMarker = TRUE)

# create map
# can filter on positioning error if desired
leaflet(data = dataset %>%
  addProviderTiles(provider = providers$CartoDB.Positron) %>%
  addAwesomeMarkers(icon = icons, label = ~GPSTimeStamp)

Here’s a screenshot of the resulting interactive map.

nsaunders
http://nsaunders.wordpress.com/?p=5702
Extensions
Brief thoughts on: iNaturalist
ecologyeducationenvironmentrailsweb resourcesinaturalist
Let me say first: I was wrong! My profile shows that I created my account at iNaturalist in August 2008, the year that the site was launched. I created a lot of accounts in those days. At the time, the site was essentially a hobby project powered by Ruby on Rails. There were a lot … Continue reading Brief thoughts on: iNaturalist
Show full content

Let me say first: I was wrong!

My profile shows that I created my account at iNaturalist in August 2008, the year that the site was launched. I created a lot of accounts in those days. At the time, the site was essentially a hobby project powered by Ruby on Rails. There were a lot of those in 2008 – I made some myself – and very few of them lasted long. I liked the ideas behind iNaturalist but I didn’t think it would succeed.

Fast-forward to around 2022/23 when I decided to revisit the site. What do I find? A thriving community with millions of biodiversity observations, which feeds into other important resources such as the Atlas of Living Australia. A site that makes me want to contribute, because it’s both enjoyable and useful.

My year in review isn’t huge, compared with people who contribute daily, or as part of their day job, but I still feel good about it. It’s one of the few sites that seems to espouse the values from the “Golden Age of the Web” (2008-2010) – data online, freely-available, validated by experts, for the good of all. Wikipedia is another that comes to mind as does Stack Exchange and, to a lesser degree, YouTube.

Feeling jaded by the AI hype cycle? Try the AI-powered iNaturalist camera, which can identify many organisms with high accuracy almost as soon as you point your phone at them. Amazing.

If you enjoy walking in nature, recording things what you see and finding out what they are, and you haven’t tried iNaturalist yet, give it a go. I’d even go so far as to say that it can have mental health benefits.

nsaunders
http://nsaunders.wordpress.com/?p=5690
Extensions
Using R/anomalize to identify delays in games of Australian Rules football
Rsportstatisticsaflanomalizetime-series
In which we generate a dataset of game durations, do a little exploratory data analysis and then try to identify unusual instances and their causes. In my Twitter-whinge-post, I mentioned that one of its last redeeming features is the AFL statistics community. I always feel the need to apologise for the sports-related posts to long-time … Continue reading Using R/anomalize to identify delays in games of Australian Rules football
Show full content

In which we generate a dataset of game durations, do a little exploratory data analysis and then try to identify unusual instances and their causes.

In my Twitter-whinge-post, I mentioned that one of its last redeeming features is the AFL statistics community. I always feel the need to apologise for the sports-related posts to long-time followers of this blog, but here’s the thing: sport can provide rich datasets, generate numerous interesting questions and can be a fun way to practice your data analysis skills.

For example, Emlyn writes:

Trying to come up with a list of games affected by in-game delay in the past 5 seasons. What have I missed?

M – MEL v WCE 2021
M – MEL v BRI 2023
M – MEL v COL 2024
M – GEE v HAW 2024

W – CAR v GWS 2025
W – COL v GCS 2025
W – COL v RIC 2024

— Emlyn Breese (@EmlynBreese) October 27, 2025

and I immediately think (1) is there a dataset with the duration of quarters in AFL games, (2) if not, can we make one, (3) why limit ourselves to recent seasons and (4) this sounds like a job for one of my favourite R packages, anomalize.

The dataset

AFL games are played over four quarters which typically take around 30 minutes each. So far as I know, the duration of quarters is not available via the fitzRoy package, nor did I find a dataset online.

So here is some quick, dirty and brittle code that uses rvest to scrape the data from AFL Tables, and here is the resulting dataset in CSV format, with the quarter durations in seconds. We have quarter duration data from 2001 onwards. The first few rows look like this:

  url                                                              match_id match_date    Q1    Q2    Q3    Q4
  <chr>                                                               <dbl> <date>     <dbl> <dbl> <dbl> <dbl>
1 https://afltables.com/afl/stats/games/2001/051220010330.html  51220010330 2001-03-30  2094  1623  1842  2004
2 https://afltables.com/afl/stats/games/2001/041020010331.html  41020010331 2001-03-31  1722  1882  1816  1704
3 https://afltables.com/afl/stats/games/2001/071520010331.html  71520010331 2001-03-31  1772  1872  1978  1738
4 https://afltables.com/afl/stats/games/2001/030820010331.html  30820010331 2001-03-31  1783  2035  1926  1916
5 https://afltables.com/afl/stats/games/2001/131920010331.html 131920010331 2001-03-31  1611  1751  2100  1814
6 https://afltables.com/afl/stats/games/2001/011620010401.html  11620010401 2001-04-01  1779  1686  1871  1755

Exploratory Data Analysis (EDA)

There are many good options for EDA using R. I like the simplicity of skimr.

skimr::skim(afl_quarter_lengths, starts_with("Q"))
── Data Summary ────────────────────────
                           Values             
Name                       afl_quarter_lengths
Number of rows             4926               
Number of columns          7                  
_______________________                       
Column type frequency:                        
  numeric                  4                  
________________________                      
Group variables            None               

── Variable type: numeric ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  skim_variable n_missing complete_rate  mean   sd   p0  p25  p50  p75 p100 hist 
1 Q1                   17         0.997 1810. 134. 1213 1725 1807 1895 2571 ▁▅▇▁▁
2 Q2                   17         0.997 1817. 138. 1216 1730 1816 1906 2429 ▁▂▇▂▁
3 Q3                   17         0.997 1830. 142. 1223 1743 1828 1919 2395 ▁▂▇▃▁
4 Q4                   17         0.997 1820. 152. 1201 1728 1814 1911 3956 ▃▇▁▁▁

Not too many missing values, good.

We can look at the distribution of quarter lengths by season.


library(tidyverse)
library(lubridate)
theme_set(theme_bw())

afl_quarter_lengths %>%
  pivot_longer(4:7) %>%
  mutate(season = year(match_date)) %>%
  ggplot(aes(season, value)) +
  geom_boxplot(aes(group = season)) +
  facet_wrap(~name) + 
  labs(x = "Season",
       y = "Duration (seconds)",
       title = "Duration of quarters in AFL games 2021-2025",
       subtitle = "data from afltables.com")

Of note: (1) season 2020 was affected by COVID and the length of quarters was reduced; (2) the last 5 seasons have seen a steady increase in quarter lengths, albeit by a median change of only around 100 seconds or so; (3) we can already see potential outliers.

The increase in game length seems to be of concern to AFL House, if almost no one else, so we can look at that. We can argue about the best way to process and visualise, but let’s just calculate the total game time, mean and median values by season, omit season 2020 and plot as points.

afl_quarter_lengths %>% 
  mutate(season = year(match_date),
         total = Q1 + Q2 + Q3 + Q4) %>% 
  group_by(season) %>%
  summarise(`mean duration` = mean(total, na.rm = TRUE),
            `median duration` = median(total, na.rm = TRUE)) %>%
  pivot_longer(-season) %>%
  filter(season != 2020) %>%
  ggplot(aes(season, value)) +
  geom_point() +
  facet_wrap(~name) +
  geom_smooth() +
  labs(x = "Season",
       y = "Duration (seconds)",
       title = "Mean and median AFL game duration 2001-2025",
       subtitle = "data from afltables.com")

Arguably an upward trend, especially in recent seasons. It’s worth noting that the gap between shortest and longest mean or median values is roughly 10 minutes, over a 2 1/2 hour game.

Using anomalize

Now let’s use anomalize to look for unusually short or long quarters. We can follow along with the quick start guide, making a few alterations to avoid error messages – see comments in the code below. Whether these are good practice for time series analysis would require more research but for now, they look to be generating interesting results.

library(tibbletime)

afl_quarter_lengths_anomalized <- afl_quarter_lengths %>%
  pivot_longer(4:7) %>%
  # remove missing values and the COVID-affected season 2020
  filter(!is.na(value),
         year(match_date) != 2020) %>%
  # group data by quarter
  group_by(name) %>%
  # convert to tibbletime
  as_tbl_time(index = match_date) %>%
  # required to prevent Error in `reconstruct()`
  as_period("1 day") %>%
  time_decompose(value, merge = TRUE) %>%
  anomalize(remainder) %>%
  time_recompose()

afl_quarter_lengths_anomalized %>%
  plot_anomalies()

The code above throws some warnings about “Index not ordered”, which we can ignore as the match dates are in ascending order. Well, we have anomalies – six in total. The plot_anomalies() method is pretty good, but we can exert more control over the plot using ggplot2 methods – either by modifying the output from plot_anomalies() or working with the output data frame.

afl_quarter_lengths_anomalized %>%
  ggplot(aes(match_date, value)) +
  geom_point(aes(color = anomaly)) +
  facet_wrap(~name) +
  scale_color_manual(values = c("grey80", "red3")) + 
  theme(legend.position = "top") +
  labs(x = "Match date",
       y = "Duration (seconds)",
       title = "Anomalous quarter lengths in AFL games 2001-2025",
       subtitle = "data from afltables.com")

We can also experiment with different algorithms for time series decomposition and anomaly detection. This, for example, finds 8 anomalies.

afl_quarter_lengths_anomalized_tw <- afl_quarter_lengths %>%
  pivot_longer(4:7) %>%
  filter(!is.na(value),
         year(match_date) != 2020) %>%
  group_by(name) %>%
  as_tbl_time(index = match_date) %>%
  as_period("1 day") %>%
  time_decompose(value, merge = TRUE, method = "twitter") %>%
  anomalize(remainder, method = "gesd") %>%
  time_recompose()

afl_quarter_lengths_anomalized_tw %>%
  plot_anomalies()

Reasons for game delays

Staying with the method that found 8 anomalies, we can filter the output data, visit the match URL at AFL Tables and then do some online research to see whether match reports indicate reasons for the delay. I’ve manually tacked that information on to the table below, with a link to the source.

afl_quarter_lengths_anomalized_tw %>%
  filter(anomaly == "Yes") %>%
  select(url, match_id, name, match_date)

  url                                                              match_id name  match_date  delay_reason
1 https://afltables.com/afl/stats/games/2018/141620180628.html 141620180628 Q1    2018-06-28  injury
2 https://afltables.com/afl/stats/games/2023/011220230701.html  11220230701 Q1    2023-07-01  injury
3 https://afltables.com/afl/stats/games/2024/192120240914.html 192120240914 Q1    2024-09-14  injury
4 https://afltables.com/afl/stats/games/2014/011920140810.html  11920140810 Q2    2014-08-10  injury
5 https://afltables.com/afl/stats/games/2001/030920010901.html  30920010901 Q3    2001-09-01  injury
6 https://afltables.com/afl/stats/games/2021/111820210809.html 111820210809 Q4    2021-08-09  weather
7 https://afltables.com/afl/stats/games/2022/091620220325.html  91620220325 Q4    2022-03-25  goal celebration
8 https://afltables.com/afl/stats/games/2024/041120240823.html  41120240823 Q4    2024-08-23  weather

For example, the first game in 2018 was held between the Sydney Swans and the Richmond Tigers and we learn that “Conca’s 100th game ends with sickening injury“. “Conca’s left leg was trapped underneath Lance Franklin midway through the first quarter, with the Tigers midfielder in agony as he was treated by the club’s medical team […] The game was stopped for several minutes“. Checks out.

What’s that, “goal celebration”? My personal favourite game delay, I was there!

Missing anomalies

What about delays which occurred during quarter time breaks, you ask? Good question and the answer is, we don’t have that data, sorry.

How about Round 2 2023, Brisbane Lions versus Melbourne Demons at The Gabba, when “The 2032 Olympic venue suddenly fell into darkness with 12 minutes left in the fourth quarter with the Lions 40 points ahead of the Demons”, delaying the game for 35 minutes? For some reason AFL Tables has the fourth quarter of this game listed as 31 minutes 54 seconds, proving once again that analysis is only as good as the data.

That’s it.

Hope you enjoyed it.

nsaunders
http://nsaunders.wordpress.com/?p=5647
Extensions
Brief thoughts on: the slow death of Twitter
networkingpersonalfriendfeedmicrobloggingsocial networkingtwitter
Why am I still there? I joined Twitter (I will never say ‘X’), unbelievably, in March 2008. I was sceptical of “microblogging” at the time but in those days, I was willing to try anything once. Back then I was a research scientist and as it turned out, there was a sizeable community of scientists … Continue reading Brief thoughts on: the slow death of Twitter
Show full content

Why am I still there?

I joined Twitter (I will never say ‘X’), unbelievably, in March 2008. I was sceptical of “microblogging” at the time but in those days, I was willing to try anything once. Back then I was a research scientist and as it turned out, there was a sizeable community of scientists posting useful and interesting content. Sure, it was something of a time sink and perhaps we spent a little too long there. Yet somehow, interesting and relevant material seemed to “float to the top”. Where it really shone was the conference hashtag and when the API was readily available to all, we were able to generate some pretty nifty summaries of scientific meetings.

At some point though, many tools go from being a time sink to a waste of time. Back in 2010 when it became clear that my favourite online space, FriendFeed, was to be shut down, there was no sentimentality on my part. Delete account, archive data, move on.

Twitter is not shutting down, at least so far as we know and not right now, but it has become a waste of time. The Twitter experience today goes something like this. Navigate the clunky login process: new sign-up links placed inexplicably above the sign-in for registered accounts, the two pages with username on one, password on the other, the occasional security theatre of “suspicious activity” which is apparently resolved by entering a username rather than an email address. Grimace at the “X” splash screen, then grimace again at the default and inaptly-named “for you” feed.

We’re in and – there’s nothing there. Well maybe that’s harsh. There are still a few people that I follow, and some of them are still posting regular content. Is it unmissable content? Rarely. Accessible elsewhere? Yes. Does Twitter function as it used to, as an alert service? Not really. Direct messaging? Almost two years since I received one.

Is there engagement around the content? Barely any. So many people have left the platform that the network effect, required to boost and amplify the interesting items, has gone. Well done everyone – your principled stand has only served to make the platform even worse for those who chose to stay.

What would I miss, were I to “deactivate” my account (deletion, of course is not offered)? I still get a laugh out of News or Fall Song? and Scarred for Life. I still get occasional insights from the AFL statistics community – although nothing that I couldn’t read via their blogs.

I wouldn’t miss the sense of “why am I even doing this” that accompanies every login, nor the deafening silence which greets most of my increasingly ‘old man yells at cloud‘ posts. I doubt that I’d even bother to download my data before leaving, since I’ve never viewed Twitter as archival. Whatever became of that Library of Congress proposal anyway? I wouldn’t migrate to Mastodon (if it’s a social media tool beloved of academics, you can bet that it’s unusable), nor Bluesky (the anti-Twitter echo chamber).

All of which thinking out loud leads me to think that in the very near future, I’ll be saying goodbye to Twitter. It was useful and fun, until it wasn’t.

nsaunders
http://nsaunders.wordpress.com/?p=5594
Extensions
Brief thoughts on: the new Australian Bureau of Meteorology website
australiaaustralian newsweb resourcesBoMdesignweatherwebsite
For those outside of Australia, the BOM website is where many Australians access weather information. It’s very popular with millions of visits per day, especially to the rain radar, and “the BOM” is even part of everyday language and culture. So much so that an attempt to prevent use of the acronym generated widespread criticism. … Continue reading Brief thoughts on: the new Australian Bureau of Meteorology website
Show full content

For those outside of Australia, the BOM website is where many Australians access weather information. It’s very popular with millions of visits per day, especially to the rain radar, and “the BOM” is even part of everyday language and culture. So much so that an attempt to prevent use of the acronym generated widespread criticism.

The recent redesign of the site, the first in over a decade, has proven controversial. My thoughts, as someone who uses many websites and even designed a few back in the day:

  • I don’t think the overall look is terrible, although there is rather too much whitespace for my liking. It’s instantly recognisable as a site built using Drupal which, long-time readers may recall, powered the Nodalpoint bioinformatics forum.
  • $4.1 million – sounds like a lot of money but that’s how governments do things. Why use in-house expertise when you can pay an external consultant 3x the daily rate of the internal employee tasked with telling them everything that they need to know. Yes, I am writing from experience.
  • There are a couple of obvious flaws that I would fix. The part of the entry page shown below is not visible in the desktop version of the site unless the user scrolls down to the bottom of the page.

Yet it contains two of the most important links: information about the new site and the rain radar. The latter is probably the most used feature of the BOM website. So how about moving those links to a menu at the top of the page.

  • I’d also highlight that the best way to use the new site is simply to add your location to the favourites. It requires a change in mindset from the old website – “select your radar from the map of all radars” – to the new – “search for your location and you’ll see the rain, no need to think about the radar itself”.

That results in what I think is really quite a nice summary page with most of the relevant information for where the user lives, including the all-important rain radar.

With more details available from the “More weather” link.

Negative feedback seems to be the default response to website redesign. The cynic in me suggests that it’s more newsworthy than positive feedback. We’re told that “social media and radio talkback [are] awash with criticism”. I note that the new website itself provides ample opportunity to send feedback, and that might be a more productive route than screaming into the online echo chamber.

In grumpy old man mode I also wrote:

<grumbling luddite>all these complaints are to be expected when people use AI instead of brains</grumbling luddite>

— Neil Saunders (@neilfws) October 28, 2025

but I do fear that more and more, we are creating a world where people expect “answers on a plate”, and become less-adept problem solvers as a result.

nsaunders
http://nsaunders.wordpress.com/?p=5618
Extensions
Still here. Still writing occasional posts for a tiny audience.
australiaaustralian newsRsportstatisticsaflfitzroyrstats
It’s been a while because, reasons. I’m still alive, still enjoying recreational R programming and still writing the occasional post. Like this one. Sam Lord writes on the site formerly known as Twitter: I bet that we can answer that using R/fitzRoy. Here’s one attempt. A rare feat? Well, there are… …56 players, of 2 … Continue reading Still here. Still writing occasional posts for a tiny audience.
Show full content

It’s been a while because, reasons.

I’m still alive, still enjoying recreational R programming and still writing the occasional post. Like this one.

Sam Lord writes on the site formerly known as Twitter:

Jaspa Fletcher has worn two different numbers in his consecutive Grand Final wins with the @brisbanelions – #28 (2024) and #3 (2025).

Surely a rare feat @sirswampthing? pic.twitter.com/lSEY42lVZf

— Sam Lord (@slord81) September 30, 2025

I bet that we can answer that using R/fitzRoy. Here’s one attempt.

library(dplyr)
library(fitzRoy)

afldata_processed <- afldata %>% 
  # only Grand Finals and only those with jumper numbers
  filter(Round == "GF", 
         Jumper.No. != "") %>% 
  # calculate score margin 
  mutate(Margin = case_when(Playing.for == Home.team ~ Home.score - Away.score, 
                            Playing.for == Away.team ~ Away.score - Home.score) %>%
  # only winners!
  filter(Margin > 0) %>% 
  # players with > 1 jumper number but played one team
  group_by(First.name, Surname, ID) %>% 
  filter(n_distinct(Jumper.No.) > 1, 
         n_distinct(Playing.for) == 1)  %>% 
  ungroup() %>% 
  distinct(Season, ID, First.name, Surname, Playing.for, Jumper.No., Margin) %>% 
  arrange(ID, First.name, Surname) %>% 
  # label Seasons with same ID if consecutive 
  group_by(ID) %>% 
  mutate(conseq = cumsum(c(1, diff(Season) != 1))) %>% 
  group_by(ID, conseq) %>% 
  # find players who played 2 or more consecutive seasons with different jumper numbers 
  filter(n() > 1, 
         n_distinct(Jumper.No.) > 1) %>% 
  ungroup()

A rare feat? Well, there are…


afldata_processed %>% 
  distinct(ID) %>%
  nrow()

# [1] 56

…56 players, of 2 480 to have ever played in a V/AFL Grand Final. So yes, somewhat rare.

In the AFL era (defined here as 1990 onwards), there are just…

afldata_processed %>%
  filter(Season > 1989) %>%
  select(-conseq)

# A tibble: 4 × 7
  Season    ID First.name Surname  Playing.for    Jumper.No. Margin
   <int> <int> <chr>      <chr>    <chr>               <dbl>  <int>
1   2019 12661 Liam       Baker    Richmond               48     89
2   2020 12661 Liam       Baker    Richmond                7     31
3   2024 13072 Jaspa      Fletcher Brisbane Lions         28     60
4   2025 13072 Jaspa      Fletcher Brisbane Lions          3     47

…two players to have played in winning consecutive Grand Finals wearing different numbers. You can add Hawthorn’s Andrew Collins (1988-1989) to the list if you want to define the “modern era” as post-1981. All in agreement with the replies to Sam’s post, well done everyone.

Looking more closely at the data, we see that most of the games played in different jumpers were VFL games in the 1920s and 1930s, particularly involving Collingwood. Changing numbers (in all games) seems to have been much more common in the past than it is now.

library(ggplot2)

afldata_processed %>%
  count(Season, Playing.for) %>%
  ggplot(aes(Season, n)) +
    geom_col() +
    facet_wrap(~Playing.for) +
    labs(y = "Count",
         title = "Count of players with different numbers in consecutive \
         winning V/AFL Grand Finals",
         subtitle = "by team and season") +
theme_bw()

Update: you can see the full dataset at Github.

nsaunders
http://nsaunders.wordpress.com/?p=5599
Extensions
Pattern recognition in Google Maps
australiaaustralian newsenvironmentaviangoogle mapsinfluenza
Headline: Second farm in the Hawkesbury region confirmed to have bird flu as biosecurity zone widened. Quite rightly, the news organisation chooses not to name the farm, nor reveal its location. However, they do include several aerial photographs including this one. Somewhat distinctive? Indeed, a little scrolling around the Hawkesbury region in Google Maps, with … Continue reading Pattern recognition in Google Maps
Show full content

Headline: Second farm in the Hawkesbury region confirmed to have bird flu as biosecurity zone widened.

Quite rightly, the news organisation chooses not to name the farm, nor reveal its location. However, they do include several aerial photographs including this one.

Somewhat distinctive? Indeed, a little scrolling around the Hawkesbury region in Google Maps, with a focus on areas of likely farmland, soon reveals a candidate location.

Mind what you post. It may easier to identify than you think.

nsaunders
http://nsaunders.wordpress.com/?p=5583
Extensions
Data discovery: seasonal speed
Rstatisticshealthrstatswalkingxml
Just writing this one quickly as it’s been hanging around my browser tabs for weeks… I wrote Taking steps (in XML) almost 7 years ago and once in a while, I still grab Apple Health data from my phone and play around with it in R for a few minutes. Sometimes, curve fitting to a cloud … Continue reading Data discovery: seasonal speed
Show full content

Just writing this one quickly as it’s been hanging around my browser tabs for weeks…

I wrote Taking steps (in XML) almost 7 years ago and once in a while, I still grab Apple Health data from my phone and play around with it in R for a few minutes. Sometimes, curve fitting to a cloud of points generates a surprise.

library(tidyverse)
library(xml2)
theme_set(theme_bw())

health_data <- read_xml("~/Documents/apple_health_export/export.xml")

ws <- xml_find_all(health_data, ".//Record[@type='HKQuantityTypeIdentifierWalkingSpeed']") %>% 
    map(xml_attrs) %>% 
    map_df(as.list)

ws %>% 
    mutate(Date = ymd_hms(creationDate), 
                  value = as.numeric(value)) %>% 
    ggplot(aes(Date, value)) + 
    geom_point(size = 1, alpha = 0.2, color = "grey70", fill = "grey70") + 
    geom_smooth() + 
    labs(y = "Walking speed (km/h)", 
    title = "Walking speed data", 
    subtitle = "Apple Health 2020 - 2023")

Result:

Huh. Looks seasonal. Looks faster in the (southern) winter. Has that been reported before? Sure has.

It didn’t impress everyone but I thought it was interesting.

nsaunders
http://nsaunders.wordpress.com/?p=5566
Extensions