Goal of the tool:
To let anyone see when a species is observed — by hour of day and by month — for any iNaturalist project, place, user or species, without downloading data or writing code.
Niche it fills in the iNaturalist ecosystem:
The Explore page answers where and what, but not when within the day. Time-of-day distribution is visible only by opening observations one at a time or exporting a CSV and charting it yourself. This closes that gap for people who do not work in R or Python. The month chart overlaps somewhat with existing seasonality views, but sits alongside the hourly one so both can be read together under the same filters.
Is there a commercial component, or do you plan to include one in the future? Are donations requested?
No. Free, no account, no donations requested, and none planned. It is a personal project.
What sort of data (if any) does your app collect from its users?
No user data is collected by the app itself. Posit (shinyapps.io) collects server-side usage metrics — session duration and connection counts — for billing purposes, as documented in their privacy policy. No analytics, cookies or logging of queries are introduced by the app code.
Link to your iNaturalist profile:
https://www.inaturalist.org/people/andreferrari
Description:
Pick any combination of place, project, taxonomic group, species, observer and quality grade, and the app fetches those observations and charts them by hour of day and by month. After loading, you can further filter by group, season and moon phase without re-querying. There is also a table and a map.
A few things worth knowing:
- Queries are capped at 10,000 observations. A live count and time estimate appear before you commit, so you know what you are asking for.
- Only observations with an exact recorded time appear in the hourly chart. The app reports how many were excluded, since that difference can be substantial.
- Where an unusual share of records falls between 00:00 and 01:00, a warning appears. Cameras with an unset clock and records whose time was never entered tend to default to midnight, and the API does not distinguish a measured time from a presumed one.
- Seasons follow the hemisphere, detected from the data rather than assumed.
- Interface in English and Portuguese, including common names.
Built with R and Shiny, using Leaflet via CDN for the map. Pagination uses id_above rather than page, which avoids the 10,000-record ceiling on the standard paging parameters.
https://andreferrari.shinyapps.io/inat_patterns/
Discussion questions or areas seeking feedback:
- The midnight warning is a heuristic — three times the uniform expectation, minimum twenty records. Is that threshold sensible, and are there legitimate cases where a genuine midnight concentration would trigger it wrongly?
- Is there interest in overlaying sunrise and sunset times, so the hourly chart could be read against day length rather than clock time? That seems more meaningful for activity patterns but adds a dependency.
- The moon phase filter uses an approximate astronomical formula, accurate to about a day. Good enough, or worth the precision?
- Anything that would make this more useful to identifiers rather than observers? I built it from an observer’s perspective and suspect I am missing something obvious.

