This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass πΏ
π‘ The idea in one breath
Most weather apps keep you scrolling. PLOT does the opposite. π΅β‘οΈπ±
You pick a place (or share your location π). Real weather loads π¦οΈ. TabPFN, an open tabular foundation model π§ , reads your day like a row in a frost table and answers:
βΈοΈ Wait Β· πΆ Walk Β· πΏ Garden
Then it hands you three concrete steps and expects you to leave. The screen's job is under a minute. β±οΈ
| π Live demo | plot-touch-grass.onrender.com |
| π» Source | github.com/PranjalManhgaye/plot-touch-grass |
π οΈ What I Built
| Field | Value |
|---|---|
| πΏ Product | PLOT - outdoor action signal + checklist |
| π§ Brain |
TabPFN (tabpfn-client) |
| π Training data | 30,684 real daily rows, 12 US cities, 2018-2024 |
| π¦οΈ Weather | Open-Meteo ERA5 reanalysis + live forecast |
| βοΈ Hosting | Render free tier |
| β‘ Stack | FastAPI, static UI, no chat layer |
π₯ Who it's for: anyone with a yard, balcony, or park nearby who overthinks the forecast and under-leaves the house.
π¬ Demo
π₯ Screen recording: [https://www.youtube.com/watch?v=0zisIS7GLjg]
π Try it yourself: plot-touch-grass.onrender.com
β³ First load on Render free tier may take ~30s while the service wakes up.
πΈ Screenshots
ποΈ Hero - PLOT landing page

π¦οΈ Live weather - Open-Meteo fills the form
π― TabPFN signal - wait / walk / garden with confidence
βοΈ How it works (60 seconds)
flowchart LR
subgraph YOU["You"]
A["Pick city or use location"]
end
subgraph DATA["Open-Meteo"]
B["Today's temps, rain, wind, soil"]
C["92-day frost window"]
end
subgraph AI["TabPFN"]
D["Classify: wait, walk, garden"]
E["Class probabilities"]
end
subgraph OUT["Outside"]
F["3-step checklist"]
G["Phone down"]
end
A --> B
A --> C
B --> D
C --> D
D --> E
E --> F
F --> G
πΊοΈ User journey
sequenceDiagram
participant U as User
participant UI as PLOT UI
participant OM as Open-Meteo
participant T as TabPFN
participant Y as Your yard
U->>UI: Open site / pick Portland
UI->>OM: GET /api/weather
OM-->>UI: Real temps, frost lag, soil
U->>UI: Get outdoor signal
UI->>T: POST /api/check
T-->>UI: garden, 83% confidence
UI-->>U: Checklist (3 steps)
U->>Y: Goes outside
ποΈ Architecture
graph TB
subgraph Client["Browser"]
WEB["Static UI / web"]
end
subgraph RenderHost["Render - plot-touch-grass"]
API["FastAPI / backend/main.py"]
ENG["OutdoorEngine / TabPFNClassifier"]
CSV[("outdoor_history.csv - 30684 ERA5 rows")]
WX["weather.py - Open-Meteo + fallback"]
end
subgraph External["Open services"]
OM["Open-Meteo API"]
TP["Prior Labs TabPFN"]
end
WEB -->|/api/weather| API
WEB -->|/api/check| API
API --> WX
WX --> OM
API --> ENG
ENG --> CSV
ENG --> TP
π The data story (real, not synthetic)
This is the part I cared about most. No fake temperatures. β
flowchart TD
A["Open-Meteo Historical API - ERA5"] --> B["scripts/fetch_real_data.py"]
B --> C["12 cities x 7 years of daily rows"]
C --> D["Feature engineering"]
D --> D1["days_since_last_frost from min temp at 0C"]
D --> D2["soil_moisture, wind, daylight"]
D --> E["Labels via backend/labels.py"]
E --> F["outdoor_history.csv - 30684 rows"]
F --> G["TabPFN fit and predict"]
π Cities in the training set
| City | Climate | Rows |
|---|---|---|
| π² Portland, OR | Cool marine | ~2,557 |
| π§οΈ Seattle, WA | Marine west coast | ~2,557 |
| ποΈ Chicago, IL | Continental | ~2,557 |
| βοΈ Minneapolis, MN | Upper Midwest | ~2,557 |
| β°οΈ Denver, CO | High plains | ~2,557 |
| π½ New York, NY | Humid subtropical | ~2,557 |
| π¦ Boston, MA | Coastal temperate | ~2,557 |
| π³ Atlanta, GA | Warm humid | ~2,557 |
| π€ Austin, TX | Warm | ~2,557 |
| βοΈ Phoenix, AZ | Desert | ~2,557 |
| π΄ Miami, FL | Tropical humid | ~2,557 |
| π Los Angeles, CA | Mediterranean | ~2,557 |
π Label distribution (on real weather)
| Action | Meaning | Share |
|---|---|---|
| πΆ walk | Good to be outside, not a planting day | ~57% |
| βΈοΈ wait | Frost risk or bad conditions, prep indoors | ~30% |
| πΏ garden | Frost window + workable soil, hands in dirt | ~13% |
Labels come from transparent horticulture heuristics in backend/labels.py (frost-free days, precip, wind bounds). TabPFN learns patterns in the table, not chat prose. I'm upfront about that. π
π¨ How I Built It
1οΈβ£ Real training pipeline
python scripts/fetch_real_data.py
Pulls daily ERA5 weather from Open-Meteo for every city above. Regeneratable. Documented in data/DATA_SOURCES.md.
2οΈβ£ TabPFN as the classifier
from tabpfn_client import TabPFNClassifier
model = TabPFNClassifier()
model.fit(X_train, y_train) # real rows
proba = model.predict_proba(X_today) # wait / walk / garden
Open-weight tabular model. Swap it without rewriting the product. π
3οΈβ£ Live weather endpoint
GET /api/weather?lat=&lon= returns today's conditions + frost lag.
- π Primary: Open-Meteo forecast with
past_days=92for frost history - π‘οΈ Fallback: nearest city's real ERA5 row for today's calendar day (when API rate-limits on free hosting)
4οΈβ£ UI that stays out of the way
No chat bubble. No purple gradients. One brand (PLOT), one CTA, one result card. β¨
- ποΈ City presets across 12 climates
- π Use my location (browser geolocation)
- π Refresh live weather
- β Checklist that ends at the door
5οΈβ£ Deployed on Render
render.yaml blueprint, health check at /api/healthz, TABPFN_TOKEN in env (never committed). π
π» Code
PranjalManhgaye
/
plot-touch-grass
PLOT - TabPFN outdoor go-signal for Hacktoberfest Touch Grass
PLOT
Leave the screen. Tend the ground.
PLOT is a Hacktoberfest Week 1 (Touch Grass) project. It uses Prior Labs TabPFN on real weather data (Open-Meteo ERA5) to classify todayβs outdoor action as wait, walk, or garden β then gives a short checklist meant to end at your door.
Live demo
- App: https://plot-touch-grass.onrender.com
- Repo: https://github.com/PranjalManhgaye/plot-touch-grass
Pick a city or use your location β live weather loads β TabPFN predicts β go outside.
Real data (not synthetic)
What
Source
Training rows
30,684 daily observations, 12 US cities, 2018β2024
Weather
Open-Meteo ERA5 reanalysis
Frost lag
Computed from real daily min temps β€ 0 Β°C
Labels
Transparent horticulture heuristics (
backend/labels.py)
Live inputs
Open-Meteo forecast + 120-day archive
See data/DATA_SOURCES.md for full provenance.
Quick start
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # set TABPFN_TOKEN
PYTHONPATH=. uvicorn backend.main:app --reload --host 127.0.0.1 --portβ¦plot/
βββ backend/
β βββ engine.py # TabPFN + transparent baseline
β βββ weather.py # Open-Meteo live + ERA5 fallback
β βββ labels.py # Documented outdoor-action heuristics
β βββ main.py # FastAPI routes
βββ data/
β βββ outdoor_history.csv # 30,684 real ERA5 rows
βββ scripts/
β βββ fetch_real_data.py
βββ web/ # Static UI
π Why Does Open Innovation Matter?
Frost and planting decisions are tabular π. They belong in a spreadsheet, not a chat thread. π¬β
| π Closed approach | π± Open approach (PLOT) |
|---|---|
| Garden API locks your coordinates to a vendor | Open-Meteo: free ERA5, no key |
| Chat model guesses from prose | TabPFN: probabilities over features |
| Can't explain why without prompt engineering | garden: 83%, wait: 9%, walk: 8% |
| Per-token cost at scale | Tabular fit once, predict cheaply |
| Model swap = rewrite the app | Swap TabPFN version, keep the CSV |
π Privacy: we don't store your location. Weather is fetched per request. Training table ships with the repo and is auditable.
ποΈ Offline path: the CSV + open model path means this could run on a laptop in the backcountry with cached rows. That's the Touch Grass future I want.
A closed chat API wouldn't know what to do with days_since_last_frost: 208. TabPFN was built for exactly that column. π―
π What I'd tell judges
| πΏ Theme fit | Screen is the shortest part; checklist ends at the door |
| π§ Real open AI | TabPFN on 30k+ ERA5 rows, not a wrapper |
| π Honest labels | Heuristics documented, not pretending it's human survey data |
| π Shipped | Live URL, GitHub, Render deploy |
| π« No chatbot cosplay | Tabular foundation model where it actually belongs |
π€ My Agent Session
Built with TabPFN docs + Open-Meteo API. Happy to answer questions in the comments. π¬
π Prize Categories
- π§ Best Use of TabPFN - core classifier on real frost/weather tables
- βοΈ Best Use of Render - production deploy at plot-touch-grass.onrender.com
π Links
| Resource | URL |
|---|---|
| π Live app | plot-touch-grass.onrender.com |
| π» GitHub | PranjalManhgaye/plot-touch-grass |
| π¦οΈ Open-Meteo | open-meteo.com |
| π§ TabPFN | docs.priorlabs.ai |
| βοΈ Render | render.com |
Thanks for reading. Now go touch some grass. πΏπ

Top comments (7)
Nice Work!
solid work!
Great Build!!
Nice build.
Great work! The project looks impressive. π
Impressive !
Great project π