All weather data comes from the NOAA GFS 0.25-degree global model, produced by NCEP (National Centers for Environmental Prediction). GFS runs four cycles per day at 00Z, 06Z, 12Z, and 18Z. Each cycle produces forecasts out to 384 hours (16 days).
| Parameter | Value |
|---|---|
| Horizontal resolution | 0.25° × 0.25° (~28 km at equator) |
| Vertical levels used | 20 pressure levels: 1000, 975, 950, 925, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150 hPa |
| Temporal resolution | Hourly to f120, then 3-hourly to f384 (209 forecast hours total) |
GRIB2 files are downloaded from the NOAA GFS Big Data Program on AWS S3
(noaa-gfs-bdp-pds). Only the required variables and pressure levels are
extracted using byte-range HTTP requests against the GRIB2 index (.idx) files,
minimizing download volume.
The system maintains two GFS cycles simultaneously:
A background scheduler checks for new GFS cycles every 2 minutes. GFS data typically becomes available approximately 4.5 hours after the synoptic time (e.g., the 00Z cycle appears around 04:30 UTC). When a new cycle is detected, the system begins downloading all 209 forecast hours. Each forecast hour is downloaded as a GRIB2 file, then immediately processed into NumPy cube arrays.
Once the incoming cycle is complete (or ≥95% downloaded), it is promoted to current. The old current cycle is deleted from disk.
| Variable | GFS Field | Levels |
|---|---|---|
| Temperature | TMP | 20 pressure levels |
| Relative Humidity | RH | 20 pressure levels |
| U-wind component | UGRD | 20 pressure levels |
| V-wind component | VGRD | 20 pressure levels |
| Low cloud cover | LCDC | Low cloud layer |
| Mid cloud cover | MCDC | Mid cloud layer |
| High cloud cover | HCDC | High cloud layer |
| Convective cloud cover | TCDC (conv) | Convective cloud layer |
| Cloud boundary pressures | PRES | 12 fields (bot/top for low/mid/high/conv) |
| Precipitation rate | PRATE | Surface |
| Freezing level height | HGT (0°C isotherm) | Isotherm level |
| Lifted Index | 4LFTX | Surface |
Terrain elevation comes from the ETOPO 2022 global relief model (NOAA NCEI),
at 60 arc-second resolution (~1.85 km). The dataset is stored as a memory-mapped
int16 binary file (~466 MB) for fast random-access lookups along any route.
Airports, navaids, and waypoints are stored in a SQLite database:
GRAMET is a Python/Flask web application. The frontend sends route parameters (departure, destination, waypoints, time, airspeed) to the backend, which slices the pre-computed weather cubes along the great-circle route, interpolates to a fine flight-level grid, and renders the cross-section chart using Matplotlib.
GRIB2 files are decoded using xarray with the cfgrib engine
for 3D pressure-level fields, and eccodes for 2D cloud layer and surface fields.
Each forecast hour is converted to a set of .npy (NumPy binary) arrays
organized by cycle and forecast hour:
These cubes are memory-mapped at render time for fast access without loading entire arrays into RAM.
For each route point (typically 50–200 points along the great circle), the system performs bilinear interpolation from the 0.25° GFS grid to extract temperature, humidity, wind, and cloud data. The result is a 2D cross-section: route distance (x-axis) vs. flight level (y-axis).
The vertical axis uses a piecewise-linear compression to allocate more visual space to lower altitudes where most weather occurs:
| Flight Level Range | Scale (px/FL) |
|---|---|
| FL 0 – FL 100 | 2.0 (most expanded) |
| FL 100 – FL 200 | 1.5 |
| FL 200 – FL 300 | 1.1 |
| FL 300 – FL 450 | 0.67 |
| FL 450 – FL 600 | 0.4 (most compressed) |
Flight levels are computed from pressure using the ICAO standard atmosphere barometric formula:
where P is the atmospheric pressure in hPa, and 1013.25 hPa is the ISA sea-level standard pressure. The result is in flight levels (hundreds of feet).
Cloud presence is determined by GFS cloud layer coverage percentages (LCDC, MCDC, HCDC) within GFS-defined pressure layer boundaries. RH and CLWMR are NOT used for cloud presence.
For each forecast hour, GFS provides four cloud layers with coverage percentage and boundary pressures:
| Layer | Coverage Field | Boundary Pressures |
|---|---|---|
| Low clouds | LCDC (0–100%) | PRES low bottom / top |
| Mid clouds | MCDC (0–100%) | PRES mid bottom / top |
| High clouds | HCDC (0–100%) | PRES high bottom / top |
| Convective (CB/TCU) | TCDC conv (0–100%) | PRES conv bottom / top |
GFS boundary pressures can sometimes be invalid. The following filters are applied:
Cloud opacity scales linearly with coverage:
Perlin noise is added for organic cloud edges and texture, using multi-octave smooth noise (4 octaves).
Cumulonimbus clouds are rendered with a distinct cauliflower/metaball shape using procedurally-generated overlapping circles. Key features:
where:
Isolated cells are narrow (factor 0.3×), while dense MCS (mesoscale convective system) regions are wide (factor 1.4×). CB clouds have a slight rose tint (red channel at full brightness, green/blue channels reduced by 15–20) to distinguish them from stratiform clouds.
Temperature contour lines are drawn every 10°C (or 20°F) from −60°C to +20°C. Lines are green dashed. Labels are placed at the horizontal center of the chart, vertically aligned where each isotherm crosses that x-position.
The 0°C isotherm receives special treatment: red, thicker line (2.5 px vs. 1.2 px for other isotherms), and a bold label. This line is critical for determining the boundary between rain and snow, and the icing envelope.
Each wind barb station shows a magenta temperature label in the selected unit (°C or °F), interpolated to the barb's flight level.
Wind barbs are placed on a grid of 4 rows × ~11 columns, evenly distributed across the cross-section in compressed Y-axis space. Each barb shows wind direction and speed using the standard meteorological convention:
U and V wind components from GFS (m/s) are converted to knots (× 1.94384) and interpolated to each barb's flight level.
Each wind barb station includes a WMO standard sky coverage circle (0–8 oktas). Coverage is derived from the appropriate GFS cloud layer based on altitude:
| Flight Level | Cloud Layer Used |
|---|---|
| FL < 65 | LCDC (Low Cloud Cover) |
| FL 65 – 200 | MCDC (Mid Cloud Cover) |
| FL ≥ 200 | HCDC (High Cloud Cover) |
Coverage percentage is converted to oktas: oktas = round(coverage / 12.5),
clamped to 0–8. The oktas circles follow WMO symbology (empty = 0, quarter-filled = 2,
half-filled = 4, fully filled = 8, etc.).
Wind speed contour lines ( brown dashed) are drawn from 50 kt to 300 kt in 25 kt increments. Wind speed is computed as:
where U is the east-west (zonal) wind component and V is the north-south (meridional) wind component, both in m/s as provided by GFS. The factor 1.94384 converts from m/s to knots.
Icing intensity is computed using the IENG (Icing ENGine) formula, which combines a layered icing index and a convective icing index, weighted by GFS cloud layer coverage.
Valid for temperatures between −14°C and 0°C, with a peak at −7°C:
where T is temperature in °C. Outside the −14°C to 0°C range, IENGLYR = 0.
Based on the difference in saturation vapor density between the convective cloud base and the point of interest. Valid for temperatures between −20°C and 0°C (253.15 K to 273.15 K):
where:
Saturation vapor density is computed via the Magnus formula for saturation vapor pressure:
where:
where layered_cover = LCDC + MCDC + HCDC (capped at 100%), and
conv_cover = convective TCDC.
| Severity | Threshold | Display |
|---|---|---|
| Moderate | IENG ≥ 30 | Blue semi-transparent fill with contour outline |
| Severe | IENG ≥ 80 | Dark blue semi-transparent fill with contour outline |
Turbulence is assessed using the E parameter, which combines horizontal and vertical wind shear:
where:
VWS is computed from central differences in U and V wind components across adjacent flight levels:
where:
HWS is computed from central differences in U and V along the route (horizontal direction):
where:
| Severity | E Range | Display |
|---|---|---|
| Moderate | 80 ≤ E < 160 | Light brown semi-transparent fill |
| Severe | E ≥ 160 | Darker brown semi-transparent fill |
Fields are Gaussian-smoothed (σ = 2) before display to reduce noise and produce coherent regions.
Thunderstorm potential is assessed using the GFS Best 4-Layer Lifted Index (4LFTX), a surface field that measures atmospheric instability. Negative values indicate convective potential; more negative = more unstable.
Lightning bolt symbols (⚡) are placed along the route where LI indicates thunderstorm likelihood. Both color and size vary by severity:
| LI Range | Category | Symbol |
|---|---|---|
| LI ≥ −0.5 | No thunderstorm | (no symbol) |
| −3.5 ≤ LI < −0.5 | Unlikely TS | ⚡ small |
| −5.5 ≤ LI < −3.5 | Possibly TS | ⚡ medium |
| −6.5 ≤ LI < −5.5 | Probably TS | ⚡ medium-large |
| −8.0 ≤ LI < −6.5 | Severe TS | ⚡ large |
| LI < −8.0 | Violent TS | ⚡ largest |
Symbols are placed above terrain at approximately FL 20 (or 15 FL above terrain, whichever is higher). Spacing is approximately every 25th route point to avoid overlap.
Precipitation rate is from the GFS PRATE surface field (kg/m²/s). Points with PRATE < 0.00001 kg/m²/s are considered dry.
Precipitation intensity (0–1) is computed on a logarithmic scale:
where:
Higher intensity produces more numerous, thicker, and more opaque precipitation symbols.
Blue vertical streaks from near terrain up to the freezing level. Each precipitation point generates 2–8 streaks (more with higher intensity) with random offsets for a natural look. Streak opacity ranges from 0.3 (light) to 0.8 (heavy).
❄ Snowflake glyphs above the freezing level, up to 60 FL above it. Snowflakes have a white outline for visibility and are tinted light blue with a blue edge. Size and number scale with intensity.
The rain/snow boundary is determined by the GFS freezing level height (0°C isotherm geopotential height), converted to flight level via the barometric formula. Where this field is unavailable, a default of FL 100 is used.
Terrain elevation comes from ETOPO 2022 (60 arc-second global relief), accessed via a memory-mapped binary raster for fast lookups.
The dark brown filled area shows the terrain elevation directly along the route centerline (great-circle path). Elevation in meters is converted to flight level using the barometric formula. No smoothing is applied.
A lighter brown area shows the maximum terrain within ±5 NM perpendicular to the route. This buffer helps pilots assess terrain clearance in the vicinity of the route, not just directly underneath. Perpendicular samples are taken at intervals along the route, and the maximum elevation is reported.
The terrain profile is outlined with a thin dark line () for visual clarity.
The chart background transitions between blue sky (day) and dark blue-black (night) based on actual solar position along the route.
Solar altitude is computed for each route point at the corresponding time, using the solar declination and hour angle. Civil twilight (solar altitude between −6° and 0°) produces a smooth transition:
The night overlay maximum opacity is 220/255 (~86%), preserving some visibility of underlying weather features.
where δ is the solar declination (degrees) and DOY is the day of the year (1–365). The offset 81 centers the cycle so that δ = 0 at the spring equinox.
When sunrise or sunset occurs during the flight, a curve shows the terminator altitude across the chart. The sunrise curve is orange, and the sunset curve is purple. Higher altitudes see sunrise earlier and sunset later due to the geometric horizon dip:
where R = 6,371 km (Earth radius) and h = altitude in meters.
The tropopause is detected using the WMO lapse-rate definition: the lowest level above FL 150 where the temperature lapse rate falls below 2°C/km and remains below that threshold over the next 2 km of altitude (~65 FL levels).
where ΔT is the temperature change (°C) and Δz is the altitude change (km). A negative lapse rate (temperature increasing with altitude) indicates a temperature inversion, which is common at the tropopause.
Displayed as an orange dash-dot line with a "Tropopause" label. The line is smoothed with a uniform filter for display.
Important — Read Before Use
This tool is provided for informational and educational purposes only. It is not a certified aviation weather briefing product and must not be used as the sole basis for any flight planning or operational decisions.
The forecast data may be inaccurate, outdated, incomplete, or corrupted. The algorithms used to process and display this data may contain errors. Terrain data, route calculations, and derived parameters (icing, turbulence, thunderstorm potential) are approximations that may not reflect actual conditions.
Always obtain an official weather briefing from an approved aviation weather service before any flight. As pilot in command, you are solely responsible for assessing weather conditions and making go/no-go decisions. No information presented by this tool should substitute for proper pre-flight planning and professional meteorological guidance.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR OPERATORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE USE OF THIS TOOL.
When you generate a GRAMET chart, we log the following information:
We look up the approximate geographic location of your IP address (country, city, region, ISP) using the ip-api.com service. This lookup is performed once per unique IP and the result is cached locally. We do not share your IP address with any other third parties.
This site does not set any cookies for regular users. No tracking cookies, no analytics cookies, no advertising cookies. The only cookie used is a session authentication cookie for the site administrator, which is never set for regular visitors.
We collect this data for the sole purpose of understanding how the tool is used — which routes are popular, how many people use it, and basic server analytics. We do not sell, share, or transfer your data to any third parties (except the one-time IP geolocation lookup described above). We do not use your data for advertising, profiling, or any purpose other than aggregate usage statistics.
The legal basis for this processing under GDPR is legitimate interest (Article 6(1)(f)) — maintaining basic analytics for a free, non-commercial tool.
Visit logs are retained indefinitely in a local SQLite database on our server. IP geolocation cache entries are retained indefinitely. We may periodically delete old records at our discretion.
Under GDPR, you have the right to:
To exercise any of these rights, contact us at haushofer@gmail.com.
This site is operated as a personal, non-commercial project. For questions or concerns, contact haushofer@gmail.com.