Repository navigation
Releases: stiles/pyfr24
Releases · stiles/pyfr24
Release list
Release v0.3.0
Added
--formatflag andformatsargument, taking a comma-separated list ofpng(default),svgandpdf. Each graphic is written once per format, so--format png,svgleavesmap.svgbesidemap.png. SVG keeps the route, the chrome and the type as vectors for editing in Illustrator, with the type left as live text rather than outlines; the basemap rides along as an embedded raster, since that's what tiles are.- Origin and destination are marked on the map with a dot and their airport code. Labels sit under the dot, since most routes run east to west and a label set alongside lands on the line, and they move above the dot or hug the panel edge where they'd otherwise overflow. These are the first and last fix, which is close to the runway rather than the terminal.
in_progressargument toplot_flight_map,enhanced_plot_flightandexport_flight_data, set from the summary record bysmart-export, which distinguishes an aircraft still flying from one whose track merely ran out.toplines.jsoncarriesin_progress, pluslast_position_timeandlast_position_time_readable.- A real export is committed under
examples/: the map, both charts andtoplines.jsonfrom a San Francisco to New York flight that held at 39,000 feet south of Buffalo, so the output can be seen without installing or holding an API token. The data files and SVGs are left out, sincepoints.geojsonandmap.svgalone would add 1.3 MB.examples/README.mdworks through why the dip under that hold is mostly a lost tailwind rather than braking. - The map is bordered in the same light gray as the chart gridlines, so it reads as a panel instead of bleeding into the page, and a map and a chart of the same flight sit together.
Changed
- Deks spell out the tracked duration: "4 hours, 2 minutes tracked" rather than "4 hr 2 min tracked", with singulars handled so an hour and a minute don't come out plural.
- Dropped
geopandasandshapelyfrom the dependencies. Both were there for a single coordinate transform, which the antimeridian fix had to replace anyway, and one of them drags in GDAL.numpyis now declared instead:vizimports it directly and it had been arriving only as a transitive dependency of matplotlib and pandas. - The version is defined once, in
pyfr24/__init__.py, andsetup.pyparses it from there rather than carrying a second copy. Two hand-maintained literals is what let 0.2.0 ship reporting itself as 1.0.0.publish.shnow bumps a single file, and a test asserts the packaged version matchespyfr24.__version__. python_requiresis now>=3.9. The package importszoneinfofor timezone conversion, which is standard library only from 3.9, so the advertised 3.8 support never worked. The CI matrix drops 3.8 and adds 3.12 and 3.13.- Publishing to PyPI happens once, in the release workflow.
publish.shuploaded with twine and then created a GitHub release that triggered a second upload, so every Publish run failed with "400 File already exists" after the package had already gone out. - Tests that call the live API are marked
integrationand deselected in CI, so the suite no longer depends on a given flight having operated on the day it runs.
Fixed
- Flights that cross the antimeridian are drawn across the Pacific rather than the long way around the world (#2). Longitude is unwrapped so the path stays continuous past 180 degrees, and the extent that produces is wider than the one world tile servers publish, so the basemap is now fetched a world at a time and composited. Contextily can't do this itself: it hands the bounds to mercantile, which clamps them, and reports success after rendering nothing past the world's edge. The projection is also worked out directly instead of through a CRS transform, which folds longitude back inside 180 and undoes the unwrapping.
- Maps and charts break where ADS-B coverage stops instead of ruling a straight line through the hole (#3). An Auckland-to-Los Angeles flight loses coverage over the South Pacific for hours, which the altitude chart drew as a slow, steady climb that never happened. The threshold scales with each flight's own median ping interval rather than being fixed, since cadence varies by region, and a break also has to cover ground, so an aircraft sitting at a gate between pings stays one line rather than fragmenting into dots.
- A missing altitude or speed reading is plotted as missing rather than as zero. Substituting zero drew a cliff to sea level in the middle of a cruise.
- A track that stops in the air is no longer labeled with the destination airport. A flight caught mid-air ends wherever the aircraft happened to be — DL691 was drawn with a dot and "KJFK" at 39,000 feet over Pennsylvania, two hundred miles short — and receivers routinely lose an aircraft before it lands. Above 5,000 feet the end of the line becomes an arrowhead turned the way the aircraft was heading, labeled "In flight" when the API says the flight hadn't landed and "Last contact" when the track simply ran out; the dek says "still in the air" for a flight in progress. Of 181 local exports, 42 ended at cruise altitude, so roughly one in four carried the wrong label.
- A landing time now settles whether a flight is still airborne, ahead of the
flight_endedflag. That flag marks a record as closed out rather than a flight as over, and Flightradar24 leaves it false for a while after touchdown: DL691 on Aug. 28, 2026 readflight_ended: falsenext to a landing time of 02:10 UTC, which would have had a parked aircraft reported as flying and its arrival time thrown away. toplines.jsonno longer reports an arrival time for a flight that hadn't landed.arrival_timefell back to the moment the aircraft was last seen, which for a flight in progress is a point over open country at cruise. It's now null, and the last-seen time is carried aslast_position_time.- A single implausible reading is dropped rather than drawn. NZ6 reported 30 knots at 35,000 feet between two readings near 500, which put a cliff to the floor of the speed chart; recovering from it would have taken 0.8 g. A reading goes only when the readings either side agree with each other and it departs from both by more than 200 knots or 5,000 feet, so a real and violent change, which plays out over several pings, is kept. Thirteen percent of local exports had at least one.
- The speed chart notes when much of a track was fixed by multilateration, whose speeds are inferred from signal timing at several receivers and wobble by hundreds of knots. QR739 had 847 such fixes out of 2,229, and no point-by-point filter can rescue that; the graphic now says the speeds are estimated instead.
tests/was listed in.gitignore, so only the handful of files committed before that line was added were ever in the repository or run by CI. New tests were silently untracked.
Release v0.2.1
Changed
osmis now the default basemap, replacingesri-light. OpenStreetMap labels cities and states at the zooms a cross-country route sits at, where the Esri gray canvas drops them, so a map reads without extra annotation.esri-lightremains available for a quieter frame.- OpenStreetMap is credited as "OpenStreetMap contributors" in the source line, the attribution its license asks for.
Fixed
- Mapbox backgrounds returned a 404 and rendered a bare route with no basemap. Mapbox style IDs carry a version suffix, so
--background mapbox-lightwas requesting the stylemapbox/light, which doesn't exist. Short names now resolve to the current version (lighttolight-v11,streetstostreets-v12and so on); versioned IDs and customowner/styleidstyles still pass through untouched. - A basemap that fails at tile-request time now falls back to the default rather than saving a map with nothing behind the route, and the source line is rewritten to credit the basemap actually drawn.
- Corrected
__version__, which reported 1.0.0 in the 0.2.0 release.
Release v0.2.0
Added
--aspectflag andaspectargument for16:9(default),3:2,4:3,1:1and9:16. The saved file matches the ratio exactly, and the map extent expands to fill the frame, so output size no longer varies with the direction of the route.- Maps and charts are laid out as finished graphics: bold headline, dek carrying an AP-style date and tracked duration, then a source line crediting Flightradar24 and the basemap. All three can be overridden with
headline,dekandsource. - Basemap options
esri-light(new default),esri-dark,esri-street,esri-natgeoandopentopo, none of which need an API key. - Mapbox backgrounds via
--background mapbox-<style>, readingMAPBOX_TOKENorMAPBOX_ACCESS_TOKEN. - Type follows the house style guide: CNN Sans Display where installed, falling back to Roboto, Inter and the system sans-serif.
Removed
- The
carto-lightandcarto-darkbackgrounds. CARTO withdrew anonymous access and now serves tiles watermarked "API key required." Both keys warn and fall back to the nearest Esri layer rather than failing.
Changed
- Moved map and chart rendering out of
client.pyinto a newpyfr24/viz.pymodule. The speed and altitude charts now share oneplot_series_chartfunction instead of duplicating ~150 lines each.FR24APImethods keep their existing signatures.
Fixed
- OpenStreetMap backgrounds rendered an "Access blocked" placeholder. Contextily identifies itself with a random hex string, which violates the OSM tile usage policy, so the tile server returned the notice image with a 200 status. Pyfr24 now sends an identifying user agent.
- Maps ignored the requested orientation.
set_aspect('equal')combined with a tight bounding box cropped the canvas to the data, andreset_extent=Falselet contextily widen the axes to the tile boundary, so a Miami-to-Los Angeles route came out 2.88:1 and a Bellingham-to-Los Angeles route 0.46:1. - Timezone label on speed and altitude charts rendered as "Time ()" for UTC data. The label now uses the requested IANA zone, falling back to the timestamp's abbreviation or UTC offset, and sits below the axis instead of overlapping the plotted line.
- Overlapping x-axis time labels on flights of roughly 4 to 8 hours. Tick spacing is now chosen from the flight duration to target about five labels, rather than switching between fixed 30-minute and hourly steps at an 8-hour cutoff.
- Map figures were never closed, leaking them across batch exports.
Release v0.1.10
Added
--versionflag to CLI to display current package version
Fixed
- Critical bug fix:
flight-idscommand now works correctly- Was calling non-existent
/api/flight-idsendpoint (returned 404) - Now uses
/api/flight-summary/lightwithregistrationsparameter - Successfully retrieves all flight instances for a given aircraft registration and date range
- Was calling non-existent
- Fixed undefined
labelsargument insmart-exportinteractive selection that could cause AttributeError - Improved error handling for flight lookup by registration
v0.1.9
What's Included in this release:
Enhanced Visualizations:
- Professional chart design with clean typography
- Multiple map backgrounds (CartoDB, ESRI satellite/topo, OSM)
- Smart time formatting and intelligent tick intervals
Timezone conversion:
--timezoneflag for CLI and API- Automatic DST handling
- Readable timestamp formatting
Better charts:
- Publication-ready speed and altitude profiles
- Human-readable time labels (11:30 AM vs 11:30:00)
- Comma-separated altitude values (35,000 ft)
- Timezone indicators on charts
0.1.7
Added
smart-exportCLI command for interactive export by flight number and date.- Automatic output directory naming for exports.
toplines.jsonsummary file in each export directory.- Progress messages for summary, track fetching, and export steps.
Fixed
- Correct date range handling for summary queries.
Improved
- User feedback and workflow for CLI exports.
Version 0.1.6
v0.1.6 chore: bump version to 0.1.6 and update changelogs
v0.1.5
v0.1.4
Added
- Map visualization enhancements:
- Customizable orientation options (16:9 horizontal, 9:16 vertical, or auto-detect)
- Improved flight path styling with clean orange line (#f18851)
- Adjusted figure dimensions for better display
- Added Read the Docs documentation setup
- Configuration files for automatic builds
- Initial documentation structure
- API reference framework
Changed
- Updated map output to use 16:9 aspect ratio by default
- Improved CLI help text for visualization options
- Enhanced README with comprehensive examples for map customization