Groups
Summary
User supplied summary for the plot
Number of space launches from GCAT that reached Earth orbit, by country and year.
No topics yet. Start the conversation.
Description
The below description is supplied in free-text by the user
Space launches ๐
Overview of space launches up to at least earth orbit.
Source: GCAT: General Catalog of Artifical Space Objects by J. McDowell
Last 10 launches
- Oct 2026 Falcon 9 from South Base, Vandenberg Space Force Base, California (US)
- Oct 2026 GSLV Mk II from Satish Dhawan Space Ctr, Sriharikota, Andhra Pradesh, India (IN)
- Oct 2026 Falcon 9 from South Base, Vandenberg Space Force Base, California (US)
- Oct 2026 Chang Zheng 8A from Hainan Shangye Hangtian Fashe Chang (Hainan Commercial Space Launch Site) (CN)
- Oct 2026 Falcon 9 from South Base, Vandenberg Space Force Base, California (US)
- Oct 2026 Chang Zheng 4B from Jiuquan Space Center, Nei Monggol Zizhiqu, China (CN)
- Oct 2026 Chang Zheng 6A from Taiyuan weixing fashe zhongxin (CN)
- Oct 2026 Electron from Rocket Lab Launch Complex 1, Onenui Station, Mahia Peninsula (NZ)
- Oct 2026 Gushenxing 1 from Huang Hai CZ-11 launch zone (CN)
- Oct 2026 Falcon 9 from Cape Canaveral Air Station, Florida (US)
Source code
import inspect
import sys
import pandas as pd
import requests
from novem import Plot
# Retrieve data for Launches and Launch Sites
URL_LAUNCHES = 'https://planet4589.org/space/gcat/tsv/launch/launch.tsv'
URL_LAUNCH_SITES = 'https://planet4589.org/space/gcat/tsv/tables/sites.tsv'
COUNTRY_MAP = {
"US": "US",
"TTPI": "US", # Trust Territory of the Pacific Islands
"UM67": "US", # United States Minor Outlying Islands
"UM79": "US", # United States Minor Outlying Islands
"PCZ": "US", # Pacific Trust Territory
"RU": "RU",
"SU": "RU", # USSR
"CN": "CN",
}
COUNTRY_ORDER = ["US", "CN", "RU", "Others"]
# Only the columns the chart needs, with fixed dtypes. The full launch table
# is 33 columns and 76k rows; loading all of it with type inference pushed the
# job past the runner's memory limit and it got killed.
LAUNCH_COLS = {
"Launch_JD": "float64",
"Launch_Date": "string",
"LV_Type": "string",
"Launch_Site": "string",
"LaunchCode": "string",
}
SITE_COLS = {"#Site": "string", "StateCode": "string", "Name": "string"}
def read_tsv(url, cols):
# Stream the response straight into the parser instead of buffering the whole file
with requests.get(url, stream=True, timeout=120) as r:
r.raise_for_status()
r.raw.decode_content = True
return pd.read_csv(r.raw, sep="\t", usecols=list(cols), dtype=cols)
def load_data():
launches = read_tsv(URL_LAUNCHES, LAUNCH_COLS)
sites = read_tsv(URL_LAUNCH_SITES, SITE_COLS)
return launches.merge(sites, left_on="Launch_Site", right_on="#Site", how="left")
def clean_data(df):
# Keep only orbital launches (LaunchCode starts with O) before the heavier parsing below
df = df[df["LaunchCode"].str.startswith("O", na=False)].copy()
# Extract Year from messy String
df['Date'] = pd.to_datetime(df['Launch_Date'].str.rstrip("?").str.split().str[:3].str.join(" "), errors='coerce')
df['Year'] = df['Date'].dt.year
# Apply mapping, send everything else to "Others"
df["Country"] = df["StateCode"].map(COUNTRY_MAP).fillna("Others")
df["Country"] = pd.Categorical(
df["Country"], categories=COUNTRY_ORDER, ordered=True
)
return df
df = load_data()
df_space = clean_data(df)
novem_data_table = df_space.pivot_table(index='Year', columns='Country', aggfunc='size', observed=False).fillna(0)
plt = Plot('ex-space-launch')
plt.data = novem_data_table
plt.type = 'sbar'
plt.name = 'Dawn of a new space age ๐'
plt.summary = 'Number of space launches from GCAT that reached Earth orbit, by country and year.'
plt.shared = 'public'
# Description includes source, markup table and this python code itself
plt.description = '''# Space launches ๐
Overview of space launches up to at least earth orbit.
Source: *GCAT: General Catalog of Artifical Space Objects* by J. McDowell\n
## Last 10 launches
'''
df_last_10 = df_space.sort_values(by='Launch_JD', ascending=False).head(10)
df_last_10_table = '\n'.join(
f"- {row['Date'].strftime('%d. %b %Y')} {row['LV_Type']} from {row['Name']} ({row['StateCode']}) "
for _, row in df_last_10.iterrows()
)
plt.description += df_last_10_table
plt.description += '\n\n## Source code\n\n'
plt.description += '\n\n```python' + ' ' + inspect.getsource(sys.modules[__name__]) + '```'