Generative art from real atmospheric data. Daily artworks derived entirely from live weather patterns - pressure, wind, temperature - rendered as high-resolution digital art through the lens of abstract expressionism.
Live: art.jamestannahill.com
Every day, this system scans 54 weather points across the globe, identifies the 10 most visually dramatic atmospheric conditions, and generates original artwork for each. There are three rendering paths:
- Flux 1.1 Pro from a descriptive text prompt (most artists)
- Custom FLUX.1-dev LoRA fine-tunes for nine artists trained on their own canvas reproductions (Lesley Tannahill, Sam Francis, Hilma af Klint, Joan Mitchell, Willem de Kooning, Helen Frankenthaler, Gerhard Richter, Norman Lewis, Arshile Gorky)
- Bedrock Claude SVG for a parallel vector version of every piece
Users can select from 17 artist inspirations - each producing radically different visual interpretations of the same weather data across 7 canvas formats (square, landscape, portrait, cinematic, golden ratio).
A parallel pipeline extracts color palettes from Copernicus Sentinel-2 satellite imagery, building a seasonal archive of Earth's real colors as seen from 786 km above the surface.
Every piece is permanently archived, browsable via infinite-scroll artist galleries, and plotted on an interactive Mapbox globe.
Sam Francis* | Gerhard Richter* | Hilma af Klint* | Wassily Kandinsky | Helen Frankenthaler* | Piet Mondrian | Yayoi Kusama | Mark Rothko | Bridget Riley | Kazimir Malevich | Lesley Tannahill* | Arshile Gorky* | Willem de Kooning* | Joan Mitchell* | Mark Tobey | Peter Max | Norman Lewis*
Asterisked artists have a custom FLUX.1-dev LoRA fine-tune. See Custom LoRAs.
Nine artists are rendered through private FLUX.1-dev LoRA fine-tunes trained on hand-curated canvas reproductions, rather than from text prompts alone. Each artist's /artist/{key}/ page carries a "Model & Methodology" block documenting the training corpus, hyperparameters, and provenance.
| Artist | Source | Training Set | Replicate Model |
|---|---|---|---|
| Lesley Tannahill | lesleytannahill.com Selected Self-Portraits | 28 canvases | jtannahill/lora-lesley-tannahill |
| Sam Francis | samfrancis.com Works on Canvas | 31 canvases | jtannahill/lora-sam-francis |
| Hilma af Klint | WikiArt (Paintings for the Temple, Ten Largest, Swan, Dove, Atom Series, Altarpieces) | 27 canvases | jtannahill/lora-hilma-af-klint |
| Joan Mitchell | WikiArt (Vetheuil + New York periods, 1951-1992) | 60 canvases | jtannahill/lora-joan-mitchell |
| Willem de Kooning | Willem de Kooning Foundation (1916-1988) | 66 canvases | jtannahill/lora-willem-de-kooning |
| Helen Frankenthaler | WikiArt (Soak-Stain + Color Field works) | curated canvases | jtannahill/lora-helen-frankenthaler |
| Gerhard Richter | WikiArt (Abstrakte Bilder squeegee period) | curated canvases | jtannahill/lora-gerhard-richter |
| Norman Lewis | See the artist page's Model & Methodology block | curated canvases | jtannahill/lora-norman-lewis |
| Arshile Gorky | See the artist page's Model & Methodology block | curated canvases | jtannahill/lora-arshile-gorky |
All LoRAs use rank 32, 1500 training steps, learning rate 1e-4, trained on Lambda Cloud H100 in 12 minutes via $1-2 per training). Per-image captions encode title, medium, dimensions, and year. Trigger words follow the convention ostris/flux-dev-lora-trainer on Replicate ({artist}_style.
The weather_render Lambda dispatches via ARTIST_LORA_MODELS: when an artist key has a registered LoRA, the prompt is prepended with the trigger word and the call routes through replicate.com/predictions to the per-artist model instead of the public flux-1.1-pro endpoint. Inference cost is similar (~$0.04/piece).
Training scaffold lives in ~/lora-train/ (separate repo).
| Layer | Technology |
|---|---|
| Infrastructure | AWS CDK (TypeScript) |
| Orchestration | Step Functions, EventBridge (daily 06:00 UTC) |
| Weather Data | Open-Meteo API (GFS/NOAA model) |
| Satellite Imagery | Copernicus Sentinel Hub Process API (Sentinel-2 L2A) |
| Art Generation | Flux 1.1 Pro (PNG, most artists), FLUX.1-dev LoRA fine-tunes (9 artists), Amazon Bedrock Claude (SVG, parallel) |
| Color Extraction | Pillow median cut quantization |
| Storage | S3 (versioned), DynamoDB |
| CDN | CloudFront with OAC + CloudFront Function (index rewrite) |
| Templating | Jinja2 → static HTML |
| ML | Art critic (commentary scoring), weather forecaster, dynamic pricing |
| Newsletter | Resend (daily digest) |
| Social | RSS feed → dlvr.it (X/Instagram) |
| Runtime | Python 3.12 Lambda (16 functions) |
| Watermarking | Pillow + Fredoka font, on-demand at download, S3-cached |
| API | Lambda Function URLs (trigger + infinite scroll) |
| Mapping | Mapbox GL JS (dark globe, artwork markers) |
| Analytics | Google Analytics 4 |
EventBridge (daily 06:00 UTC)
└── Step Function (concurrency 2)
├── Weather Branch
│ ├── Weather Ingest (Open-Meteo → 54 global points → top 10 scored)
│ └── Weather Render ×10 (Flux PNG or Bedrock SVG, 7 canvas formats)
├── Satellite Branch
│ ├── Satellite Ingest (Sentinel Hub Process API → true-color JPEG)
│ └── Palette Extract (median cut → 5-7 colors → Bedrock mood brief)
├── ML Branch
│ ├── Art Critic (scores + commentary on generated pieces)
│ └── Weather Forecast (atmospheric condition predictions)
├── Newsletter + Social
│ └── Newsletter Digest (Resend → subscribers)
└── Site Rebuild (asset mirror)
└── Mirrors new weather/ + palettes/ files into the site/ prefix
The static HTML frontend now lives in the separate art-astro repo. That repo also owns sitemap.xml (via @astrojs/sitemap), robots.txt, and llms.txt (served from its public/ directory). The Jinja2 renderer in art-site-rebuild is retired; the Lambda survives only as an S3 asset mirror.
| Page | Path | Description |
|---|---|---|
| Homepage | / |
Latest generation + Generate button with artist selector |
| Artists | /artist/ |
Browse by artist - mosaic thumbnails from latest works |
| Artist Gallery | /artist/{key}/ |
Infinite scroll gallery via API |
| Archive | /weather/ |
All runs chronologically with artist labels |
| Run | /weather/{run_id}/ |
Single generation (10 pieces) |
| Artwork | /weather/{run_id}/{slug}/ |
Full artwork + rationale + metadata + print inquiry + OG preview |
| Map | /map/ |
Mapbox dark globe with all artwork markers |
| Studies | /studies/ |
Deep-dive artistic studies of compelling pieces |
| Palettes | /palettes/ |
Satellite color palettes by location |
| Print Shop | /prints/ |
Limited edition prints via theprintspace (Hahnemühle German Etching) |
| About | /about/ |
Project story, artist bio, how it works |
| Privacy | /privacy/ |
Privacy policy (GA4 disclosure) |
| Terms | /terms/ |
Terms of use (CC BY-NC-ND 4.0 details) |
| Function | Purpose |
|---|---|
art-weather-ingest |
Scans 54 global weather points, scores for visual drama |
art-weather-render |
Tri-mode art generation: Flux 1.1 Pro (PNG), per-artist FLUX.1-dev LoRA fine-tune (9 artists, dispatched via ARTIST_LORA_MODELS), or Bedrock Claude (SVG). PNG preview rendering (CairoSVG). |
art-satellite-ingest |
Sentinel Hub Process API → true-color imagery for 30 rotating locations |
art-palette-extract |
Color quantization + Bedrock mood descriptions |
art-critic |
ML commentary scoring on generated artworks |
art-weather-forecast |
Atmospheric condition predictions for upcoming generations |
art-newsletter-digest |
Daily newsletter via Resend to subscribers |
art-study-detector |
Identifies compelling pieces for deeper artistic studies |
art-study-admin |
Manages study generation and publishing workflow |
art-print-shop |
Print inquiry handling and theprintspace integration |
art-api-product |
Product catalog API for print shop listings |
art-site-rebuild |
Asset mirror only: copies new weather/ and palettes/ files into the site/ prefix. Jinja renderer retired; HTML, sitemap, robots.txt, and llms.txt are built by the art-astro repo. Times out at 900s on a full run, so large backfills need a direct copy of the changed keys into site/weather/ plus a CloudFront invalidation of /weather/*. |
art-image-resize |
Triggered by each preview-2048.png PUT. Builds WebP variants (480 / 960 / 1200 / 1920) from the upscaled preview-4k.png master when it exists (waiting up to 45s for it, since it lands just after the 2048 PNG), falling back to preview-2048.png. The 1200 width serves og:image and twitter:image. Also pre-warms watermarked 4K/8K downloads. Direct invoke supports {run_id, slug, force?} and {backfill: true, force?, prewarm_only?}. |
art-trigger |
Generate button endpoint (2-hour cooldown) |
art-api |
Paginated DynamoDB queries for infinite scroll galleries |
art-watermark-download |
Watermarks public PNG downloads (4K/8K) on demand. Caches to site/downloads/, returns 302 to CloudFront. Print-shop fulfillment uses the un-watermarked source path directly. |
Until 2026-09-23 the WebP previews were resized from preview-2048.png, which is only 768 to 1024px wide, so every "1920w" variant was really the small preview and heroes looked soft on retina screens. All 2,281 FLUX pieces were re-rendered from their 4K masters on 2026-09-23 and mirrored into site/weather/. Source selection is covered by tests/image_resize/test_best_source.py.
- Schema.org:
WebSite,VisualArtwork(per piece with geo, medium, license),AboutPage,Person - Open Graph + Twitter Cards: unique title, description, 1200px WebP preview image per artwork page
- RSS Feed:
/feed.xml- latest artworks for social syndication (dlvr.it → X/IG) - Canonical URLs: prevent duplicate content across runs
- robots.txt: allows all crawlers, sitemap reference (served from art-astro
public/) - sitemap.xml: generated by
@astrojs/sitemapin the art-astro repo, all pages + all artwork - llms.txt: structured for AI crawlers (ChatGPT, Claude, Perplexity), maintained in art-astro
public/ - Google Analytics 4: GA4 with privacy policy disclosure
| Asset | License |
|---|---|
| Artwork (SVG outputs) | CC BY-NC-ND 4.0 |
| Generative system (code) | All Rights Reserved |
| Weather data | Open-Meteo (GFS/NOAA) |
| Satellite imagery | Copernicus Sentinel-2 (ESA) |
For commercial licensing, prints, or collaboration: art@jamestannahill.com