A Python App for Analyzing Immigration Enforcement Data

Summary: I created an open-source app that lets you see how immigration enforcement in the US has changed over time. Please check it out and share!

Immigration Enforcement has been in the news lately. This caused me to ask questions like:

  • How is immigration enforcement normally measured?
  • What was the baseline?
  • How has it changed recently?

I originally tried to answer these questions with official statistics (i.e. those published by government agencies). But I found those datasets difficult to work with. Specifically, a lot of them were in Excel workbooks and PDF files, which are hard to analyze with code.

I eventually discovered the Immigration Detention Quick Facts page from the Transactional Records Access Clearninghouse (TRAC). I was particularly interested in their ICE Detainees page, which offers a lot of raw data. TRAC’s immigration data is frequently cited by major news sources, so I feel comfortable relying on it.

Unfortunately, TRAC’s Quick Facts page only provides two visualizations of the data on their ICE Detainees page. I found myself wishing their site offered more ways to explore and interpret the data.

I decided to build an open-source tool to visualize all the data on TRAC’s ICE Detainees page. The tool is a web app built using Python. You can view it here. The github repo for the project is here.

This tool has the potential to inform the public about an important issue, so I ask that you share it.

Key Concepts

The data on TRAC’s ICE Detainees page has three concepts: Date, Arresting Authority and Criminality. Below is my understanding of each term.

Date. “Date” means “The number of detainees in ICE’s custody, nationwide, on the given date.” That is, it does not mean “The number of people who were arrested on the given date.”

There are typically 1-3 data points added each month. The app fetches the latest data when it is loaded, and caches it for 15 minutes. This means that the app should normally display the most current data.

Arresting Authority. Two agencies arrest people for immigration violations: Immigration and Customs Enforcement (ICE) and Customs and Border Protection (CBP). ICE typically operates inside the country, and CBP normally works at the border.

Taken together, Date and Arresting Authority let you see which agency has arrested more of the people who are in ICE’s custody, and how that ratio has changed over time.

Criminality. Each detainee has a criminal status. There are three possible values:

  • Convicted Criminal
  • Pending Criminal Charges
  • Other Immigration Violator

This allows you to see what percentage of people detained by ICE are convicted criminals, and how that proportion has changed over time.

With all these permutations (arresting authority, criminality and percentage vs. count), you can see why I felt limited by the two graphs that TRAC provides for this data!

Example Graphs

The app lets you create eight different graphs of the data. Below are two that I found particularly interesting.

Detainee Count Over Time

President Trump took office in January 2025. At that time there were about 39k people detained by ICE and CBP. Six months later that number is about 58k. That’s a 57% increase in six months, and is (just barely) the highest number in the dataset.

Equally interesting is the agency-level data: since Trump took office ICE detentions are sharply up, but CBP detentions are down. I am not sure why CBP detentions are down.

The graph has a large dip at the start, which I assume is due to Covid-19.

Criminality of ICE Detainees over Time

Now that we know there is a recent spike in arrests by ICE, it’s natural to ask: “Who are they arresting?”

TRAC’s ICE Detainees dataset only provides one attribute about each detainee: their criminal status. Setting the display to “Percent” we can see how the makeup of criminal status of those arrested by ICE has changed over time.

Before the start of Trump’s second administration, the percentage of people detained by ICE with criminal convictions ranged between 62% and 86%. When Trump took office in January, that figure was at 62% – the lowest to date. Since then, the percentage has declined each month, reaching just 36% today.

Conclusion

Like most of my open source work, this app has two goals:

  1. To share analytical results that I find interesting.
  2. To share the code I wrote that made the analysis possible.

In this post I walked through two of the eight graphs that the app produces. You can see the other graphs here. As a reminder, the app updates automatically when TRAC produces new data.

The repo containing the app’s code is here. Feel free to use it as a starting point for your own projects. If you’re interested in a tutorial on how the app works, I’d be happy to write one up—just let me know!

While comments on my blog are closed, I welcome hearing from readers. Use this form to contact me.

Ari Lamstein

Ari Lamstein

I’m a software engineer who focuses on data projects.

I most recently worked as a Staff Data Science Engineer at a marketing analytics consultancy. While there I developed internal tools for our data scientists, ran workshops on data science and mentored data scientists on software engineering.

I have also created several open source projects.