One of my favourite soccer analytics blog posts over the last few years is Ben Torvaney’s Tools for Tiny Teams1. Even though many soccer analytics departments have outgrown the “tiny” label, his insights remain strikingly relevant.
Boring Web Apps
In Tools for Tiny Teams, Ben highlights the value of “Boring Web Apps” – focusing on well-supported frameworks like Flask or Django, building on Postgres databases, and generally avoiding flashy but fragile new tech. He calls out how small technical teams can gain huge efficiencies by sticking to stable tools with excellent documentation and community support.
For tiny analytics squads, this approach is especially handy because you can rapidly prototype new tools while trusting that you won’t have to debug an obscure integration issue at 3 AM after a weekend game.
As your team grows (or even if it doesn’t), these practices continue to pay dividends. But it’s not just about “tiny teams” – it’s also about how we handle data in a context where the user base is often surprisingly small.
Big Data, Tiny Users
A related observation I’ve made in modern sports analytics is the paradox of big data, tiny user base. Typically, in most industries, the scale of an application’s data volume increases proportionally with its user base. That assumption underpins most web technology.
However, in sports, you might juggle massive amounts of tracking data – say, 30 FPS for entire leagues – while only serving insights to a relatively tiny operations staff. This inverts many common engineering assumptions and creates a unique opportunity to rethink industry standards and prioritize data analysis over unnecessary bells and whistles.
That’s where Streamlit excels. It sacrifices features that are crucial for high-concurrency, many-user applications in favour of attributes that make rapid, data-driven prototyping much simpler.
While Ben doesn’t mention Streamlit in Tools for Tiny Teams, I suspect it would be included in a future update. The framework shares many of the same principles: it lets you build fully functional applications without stepping outside the comfortable data science stack of Pandas, NumPy, and Matplotlib.
Introducing streamlit-soccer
However – soccer is a spatial invasion game and tracking data has become increasingly ubiquitous inside of team analytics department. Visualizing this data has always been a major pain point.
Native python libraries like mplsoccer have been great for static tracking data plots, but animations are painful. Writing a front-end in something like D3.js is the natural next step, but it adds a whole layer of complexity and probably a ton of technical debt.
That’s why I built streamlit-soccer. It’s a custom React component for Streamlit applications that visualizes soccer tracking data. It’s built on top of Pieter Robberechts’s d3-soccer package and Streamlit’s custom-component library.
You can find it on GitHub and a deployed example on Streamlit Cloud. And a video, below (Substack doesn’t allow me to embed it natively):
I’ve also got it on PyPi so you can install it like this:
pip install streamlit-soccer
Currently, streamlit-soccer is in version 0.0.1
, so it’s admittedly fragile and doesn’t do much beyond basic tracking animations. But if your workflow involves hefty tracking data and minimal external users, it could be precisely what you need to visualize tracking data without having to write a lick of Javascript!
Right now, it only supports one-way communication between Streamlit (Python) and React (Javascript), but it can support two-way message passing with minimal adjustments.
For example, you can attach event listeners to the player nodes to make them draggable. After dragging a player, you could feed the adjusted tracking frame back into python and have your pickled pitch-control model calculate a new surface and re-render.
What’s Next?
Since streamlit-soccer is so early in its lifecycle, I’m actively seeking contributors who want to build out new features or help stabilize it. Whether you’ve got ideas for advanced controls, event overlays, or performance optimizations, I’d love your input. Drop by the GitHub repo and open an issue or pull request.
I’m planning on using streamlit-soccer to build small proof-of-concept applications for tracking data modelling and visualization and attaching it to centralwinger.com, but I’d love to see it used in other ways too!
I referenced Ben’s article in my Béziers, Bivariates, and Beyond piece recently, which you should check out.