Massive new hawk migration spot

While most Broad-winged Hawks are but a few weeks away from Missouri, the first sightings this year have been trickling in this week as spring migration is off to an early start.

Meanwhile in Colombia, my friend Diego Solarte and his team just concluded counting 373,621 raptors, mostly Broad-winged and Swainson’s Hawks, over one month at a new field station near Ibagué, in the department of Tolima. In the first week they counted 34,108, in the second a whopping 214,582, in the third week 39,587 and finally 58,344 raptors in the last week. Pretty nice! So given that I was working with some eBird data on North American birds at the time, I decided to compare Diego’s counts from Tolima to all Broad-winged and Swainson’s Hawk counts in North America during spring migration, just to put it into perspective.

What I found was that this new site gets close to the total count of raptors that get entered into eBird* in all of North America in the spring! Check at the yearly totals below.

His team has recently started a new raptor counting station in a critical migratory corridor of the central Andes, where many migratory raptors are threatened by illegal hunting. Despite the global COVID-19 outbreak, they have now concluded one month of fieldwork. While the station is up and running, they have yet to reach their campaign funding goal.

If you can, please consider donating to their GoFundMe campaign at the following link:

This project offers highly effective “bang-for-your-conservation-buck”: it is a small grassroots organization led by dedicated local birders and biologists, and a few dollars go a long way - especially now due to the recent spike in exchange rate.

And for a glimpse of what they’ve been seeing, check out one incredible checklist from the other week (

While this peek into the data was done out of curiosity alone, I am really looking forward to see their real analyses and reports.

*There are a lot of reasons why simple summary statistics like on this plot don’t capture the exact number of hawks in the USA and Canada during spring migration. For example, not all hawk monitoring places submit all their data to eBird. Next, eBird data comes from birders, so if two birders who are out by themselves see the same kettle of hawks, but from different places or at different times of day, those data would be entered in eBird twice. There are lots of tricky modelling techniques that take the peculiarities of eBird data into account, and I am not attempting to replicate any of these. Also, eBird is growing every year, with more and more people reporting, so that is likely why the last five years show increasing numbers in North America.


eBird Basic Dataset. Version: EBD_relOct-2019. Cornell Lab of Ornithology, Ithaca, New York. 2019.

Below is my R code for the plot (this works only if you have the eBird Basic Dataset downloaded).


bwha<-bwha %>% filter(country_code %in% c("US", "CA") &
bwha$observation_date<-parse_date_time(bwha$observation_date, orders = c("Ymd"))
bwha<-bwha %>% filter(month<6)
bwha_spring_counts<-bwha %>% group_by(year) %>% summarise(total=sum(observation_count))

swha<-swha %>% filter(country_code %in% c("US", "CA") &
swha$observation_date<-parse_date_time(swha$observation_date, orders = c("Ymd"))
swha<-swha %>% filter(month<6)
swha_spring_counts<-swha %>% group_by(year) %>% summarise(total=sum(observation_count))

s$Species<-"Swainson's Hawk"
b$Species<-"Broad-winged Hawk"
all<-rbind(s, b)

#now make those plots

p1=ggplot(all, aes(x=as.factor(year), y=total, fill=Species))+
  geom_col(position = "stack", color="black")+
  scale_y_continuous("Spring Migration Total Counts", 
  scale_fill_manual(values=c('goldenrod1', 'goldenrod'))+
  theme_minimal()+theme(legend.position="left", panel.grid.major.x = element_blank(),
                        panel.grid.minor.x = element_blank(),
                        axis.title.x = element_blank())+
  ggtitle("USA and Canada")
p2=ggplot(data.frame('year'=as.factor(2020),'total'=373621), aes(x=year, y=total))+
  geom_col(fill='blue', color="black")+
  theme_minimal()+theme(legend.position="none", panel.grid.major.x = element_blank(),
                        panel.grid.minor.x = element_blank(),
                        axis.title.x = element_blank(),
                        axis.title.y.left =  element_blank(),
                        axis.text.y.left =  element_blank())+
  ggtitle("Tolima, Colombia")

world <- ne_countries(scale = "medium", returnclass = "sf")
col <- ne_states(country = "colombia", returnclass = "sf")
p3=ggplot(data = world %>% filter( region_un=="Americas")) +
  xlab("Longitude") + ylab("Latitude") +
  theme(panel.background = element_blank(),
        legend.position = "none",
        axis.ticks = element_blank(),
        axis.text = element_blank(),
        axis.title = element_blank())+
  geom_sf(data = world %>% filter(name %in% c("United States", "Canada")), 
  geom_sf(data = col %>% filter( name_es=="Tolima"), fill="blue")+ #whoops this is so small
  geom_point(aes(x = -75.2568182, y = 4.4122862), size = 3, 
             shape = 23, fill = "blue") 

lay <- rbind(c(1,1,1,2,3,3))
grid.arrange(p1, p2,p3, layout_matrix=lay)

Back to blog