Skip to content

Visualizing GPS Satellite Orbits

In this example we'll show how to visualize the orbits of GPS satellites using Brahe. We'll download the latest TLE data for the GPS constellation from CelesTrak, propagate each satellite for one orbit, and create an interactive 3D plot showing their trajectories around Earth.

This example is similar to the Downloading & Visualizing TLE Data For GPS Satellites example, but but adds in propagation for one full orbit before visualization.


Initialize Earth Orientation Parameters

Before starting, we need to import brahe and ensure that we have Earth orientation parameters initialized. We'll use initialize_eop(), which provides a CachingEOPProvider to deliver up-to-date Earth orientation parameters.

1
2
3
4
import time
import brahe as bh

bh.initialize_eop()

Download GPS TLEs

We'll use the CelesTrak dataset to fetch the latest TLE data for all GPS satellites. The get_tles_as_propagators function downloads the data and creates SGP4 propagators in one step:

propagators = bh.datasets.celestrak.get_tles_as_propagators("gps-ops", 60.0)

Propagate orbits

Next, we'll propagate each satellite for one full orbit based on its semi-major axis:

1
2
3
4
# Propagate each satellite one orbit
for prop in propagators:
    orbital_period = bh.orbital_period(prop.semi_major_axis)
    prop.propagate_to(prop.epoch + orbital_period)

The line

    orbital_period = bh.orbital_period(prop.semi_major_axis)
computes the or orbital period of the satellite by converting the semi-major axis associated with the SGP4Propagator into an orbital period using Brahe's orbital_period function.

It then propagates the satellite to one full orbit past its epoch using the propagate_to method to ensure that the trajectory contains position data for one complete orbit.

Visualize in 3D

We'll create an interactive 3D visualization of the entire GPS constellation using Plotly. We'll use the Natural Earth 50m texture for a realistic Earth representation:

fig = bh.plot_trajectory_3d(
    [
        {
            "trajectory": prop.trajectory,
            "mode": "markers",
            "size": 2,
            "label": prop.get_name(),
        }
        for prop in propagators
    ],
    units="km",
    show_earth=True,
    earth_texture="natural_earth_50m",
    backend="plotly",
    view_azimuth=45.0,
    view_elevation=30.0,
    view_distance=2.0,
)

The resulting plot shows the complete GPS constellation orbiting Earth. The interactive visualization allows you to rotate, zoom, and pan to explore the satellite positions from different angles.

Full Code Example

visualizing_gps.py
import time
import brahe as bh

bh.initialize_eop()

# Download TLE data for all GPS satellites from CelesTrak
# The get_tles_as_propagators function:
#   - Downloads latest TLE data (cached for 6 hours)
#   - Parses each TLE into an SGP4 propagator
#   - Sets default propagation step size (60 seconds)
print("Downloading GPS TLEs from CelesTrak...")
start_time = time.time()
propagators = bh.datasets.celestrak.get_tles_as_propagators("gps-ops", 60.0)
elapsed = time.time() - start_time
print(
    f"Initialized propagators for {len(propagators)} GPS satellites in {elapsed:.2f} seconds."
)

ts = time.time()
# Propagate each satellite one orbit
for prop in propagators:
    orbital_period = bh.orbital_period(prop.semi_major_axis)
    prop.propagate_to(prop.epoch + orbital_period)
te = time.time() - ts
print(f"Propagated all satellites to one orbit in {te:.2f} seconds.")

# Create interactive 3D plot with Earth texture
print("\nCreating 3D visualization of satellites...")
ts = time.time()
fig = bh.plot_trajectory_3d(
    [
        {
            "trajectory": prop.trajectory,
            "mode": "markers",
            "size": 2,
            "label": prop.get_name(),
        }
        for prop in propagators
    ],
    units="km",
    show_earth=True,
    earth_texture="natural_earth_50m",
    backend="plotly",
    view_azimuth=45.0,
    view_elevation=30.0,
    view_distance=2.0,
)
te = time.time() - ts
print(f"Created base 3D plot in {te:.2f} seconds.")

See Also