Skip to content

Instantly share code, notes, and snippets.

@cavedave
Created March 1, 2026 01:15
Show Gist options
  • Select an option

  • Save cavedave/319e760ece78b98c5ab1c3830d72cabc to your computer and use it in GitHub Desktop.

Select an option

Save cavedave/319e760ece78b98c5ab1c3830d72cabc to your computer and use it in GitHub Desktop.
"""
Extract coal electricity generation (TWh) by year from Ember data.
China coal can use monthly or yearly data; World uses yearly.
"""
import argparse
import pandas as pd
from pathlib import Path
DATA_FILE = Path(__file__).resolve().parent / "yearly_full_release_long_format.csv"
MONTHLY_DATA_URL = (
"https://storage.googleapis.com/emb-prod-bkt-publicdata/public-downloads/"
"monthly_full_release_long_format.csv"
)
def load_data(csv_path: str | Path | None = None) -> pd.DataFrame:
"""Load Ember yearly long-format CSV."""
path = Path(csv_path) if csv_path else DATA_FILE
return pd.read_csv(path, low_memory=False)
def load_monthly_data(url_or_path: str | Path | None = None) -> pd.DataFrame:
"""Load Ember monthly long-format CSV from URL or local path."""
if url_or_path is None:
url_or_path = MONTHLY_DATA_URL
return pd.read_csv(url_or_path, low_memory=False)
def get_china_coal_by_year(
csv_path: str | Path | None = None,
source: str = "monthly",
) -> pd.DataFrame:
"""
Extract China electricity generation from coal (TWh) for each year in the data.
Returns a DataFrame with columns: Year, Coal_TWh.
source: "monthly" (default) – load monthly CSV, sum by year (can include 2025);
"yearly" – load yearly CSV.
csv_path: For monthly, URL or path to monthly CSV (None = default URL).
For yearly, path to yearly CSV (None = default DATA_FILE).
"""
if source == "yearly":
df = load_data(csv_path)
china_coal = df[
(df["Area"] == "China")
& (df["Variable"] == "Coal")
& (df["Unit"] == "TWh")
].copy()
result = china_coal[["Year", "Value"]].sort_values("Year").reset_index(drop=True)
result = result.rename(columns={"Value": "Coal_TWh"})
return result
# monthly: load monthly data, derive Year from Date, sum by year
df = load_monthly_data(csv_path)
china_coal = df[
(df["Area"] == "China")
& (df["Variable"] == "Coal")
& (df["Unit"] == "TWh")
].copy()
china_coal["Date"] = pd.to_datetime(china_coal["Date"])
china_coal["Year"] = china_coal["Date"].dt.year
result = (
china_coal.groupby("Year")["Value"]
.sum()
.reset_index()
.sort_values("Year")
.reset_index(drop=True)
)
result = result.rename(columns={"Value": "Coal_TWh"})
return result
def get_china_coal_percentage_by_year(
csv_path: str | Path | None = None,
source: str = "monthly",
) -> pd.DataFrame:
"""
China coal and total generation by year, with coal as % of total.
Returns DataFrame with columns: Year, Coal_TWh, Total_TWh, Percentage_Coal.
Uses monthly data (source ignored for now; yearly file has no Total Generation).
"""
df = load_monthly_data(csv_path)
df["Date"] = pd.to_datetime(df["Date"])
df["Year"] = df["Date"].dt.year
china = df[
(df["Area"] == "China")
& (df["Unit"] == "TWh")
& (df["Variable"].isin(["Coal", "Total Generation"]))
].copy()
by_year_var = china.groupby(["Year", "Variable"])["Value"].sum().reset_index()
coal = by_year_var[by_year_var["Variable"] == "Coal"][["Year", "Value"]].rename(columns={"Value": "Coal_TWh"})
total = by_year_var[by_year_var["Variable"] == "Total Generation"][["Year", "Value"]].rename(columns={"Value": "Total_TWh"})
merged = pd.merge(coal, total, on="Year", how="inner")
merged["Percentage_Coal"] = (merged["Coal_TWh"] / merged["Total_TWh"]).replace(0, pd.NA) * 100
return merged.sort_values("Year").reset_index(drop=True)
def plot_china_coal_percentage(
start_year: int = 2015,
csv_path: str | Path | None = None,
source: str = "monthly",
save_path: str | Path | None = None,
) -> None:
"""
Plot China's yearly coal percentage of total electricity generation.
"""
import matplotlib
if save_path is not None:
matplotlib.use("Agg")
import matplotlib.pyplot as plt
merged_df = get_china_coal_percentage_by_year(csv_path=csv_path, source=source)
merged_df = merged_df[merged_df["Year"] >= start_year].copy()
if merged_df.empty:
return
plt.figure(figsize=(12, 6))
plt.plot(merged_df["Year"], merged_df["Percentage_Coal"], marker="o", linestyle="-", color="black")
plt.title("China's Yearly Coal Percentage in Total Electricity Generation", fontsize=16)
plt.xlabel("Year")
plt.ylabel("Percentage of Total Generation from Coal (%)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.xticks(merged_df["Year"].astype(int).unique(), rotation=45)
plt.ylim(0, merged_df["Percentage_Coal"].max() * 1.05)
plt.tight_layout(rect=[0, 0.06, 1, 1])
plt.gcf().text(0.99, 0.02, "data: ember-energy by @iamredave", fontsize=9, ha="right", va="bottom")
if save_path is not None:
plt.savefig(save_path, dpi=150)
plt.close()
print("Saved plot to", save_path)
else:
plt.show()
def get_china_solar_by_year(csv_path: str | Path | None = None) -> pd.DataFrame:
"""
China solar electricity generation (TWh) by year from monthly data.
Returns DataFrame with columns: Year, Solar_TWh.
"""
df = load_monthly_data(csv_path)
solar = df[
(df["Area"] == "China")
& (df["Variable"] == "Solar")
& (df["Unit"] == "TWh")
].copy()
solar["Date"] = pd.to_datetime(solar["Date"])
solar["Year"] = solar["Date"].dt.year
result = (
solar.groupby("Year")["Value"]
.sum()
.reset_index()
.sort_values("Year")
.reset_index(drop=True)
)
result = result.rename(columns={"Value": "Solar_TWh"})
return result
def plot_china_solar(
start_year: int = 2015,
csv_path: str | Path | None = None,
save_path: str | Path | None = None,
) -> None:
"""
Plot China solar electricity generation by year (TWh), same style as coal plot.
"""
import matplotlib
if save_path is not None:
matplotlib.use("Agg")
import matplotlib.pyplot as plt
df = get_china_solar_by_year(csv_path)
df = df[df["Year"] >= start_year].copy()
if df.empty:
return
plt.figure(figsize=(12, 6))
plt.plot(
df["Year"],
df["Solar_TWh"],
marker="o",
linestyle="-",
color="#CC5500",
)
plt.title("China Solar Electricity Generation Per Year", fontsize=16)
plt.xlabel("Year")
plt.ylabel("Annual Generation (TWh)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.xticks(df["Year"].astype(int).unique(), rotation=45)
plt.ylim(0, df["Solar_TWh"].max() * 1.05)
plt.tight_layout(rect=[0, 0.06, 1, 1])
plt.gcf().text(0.99, 0.02, "data: ember-energy by @iamredave", fontsize=9, ha="right", va="bottom")
if save_path is not None:
plt.savefig(save_path, dpi=150)
plt.close()
print("Saved plot to", save_path)
else:
plt.show()
def get_india_solar_by_year(csv_path: str | Path | None = None) -> pd.DataFrame:
"""
India solar electricity generation (TWh) by year from monthly data.
Returns DataFrame with columns: Year, Solar_TWh.
"""
df = load_monthly_data(csv_path)
solar = df[
(df["Area"] == "India")
& (df["Variable"] == "Solar")
& (df["Unit"] == "TWh")
].copy()
solar["Date"] = pd.to_datetime(solar["Date"])
solar["Year"] = solar["Date"].dt.year
result = (
solar.groupby("Year")["Value"]
.sum()
.reset_index()
.sort_values("Year")
.reset_index(drop=True)
)
result = result.rename(columns={"Value": "Solar_TWh"})
return result
def plot_india_solar(
start_year: int = 2015,
csv_path: str | Path | None = None,
save_path: str | Path | None = None,
) -> None:
"""
Plot India solar electricity generation by year (TWh), same style as China solar.
"""
import matplotlib
if save_path is not None:
matplotlib.use("Agg")
import matplotlib.pyplot as plt
df = get_india_solar_by_year(csv_path)
df = df[df["Year"] >= start_year].copy()
if df.empty:
return
plt.figure(figsize=(12, 6))
plt.plot(
df["Year"],
df["Solar_TWh"],
marker="o",
linestyle="-",
color="#CC5500",
)
plt.title("India Solar Electricity Generation Per Year", fontsize=16)
plt.xlabel("Year")
plt.ylabel("Annual Generation (TWh)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.xticks(df["Year"].astype(int).unique(), rotation=45)
plt.ylim(0, df["Solar_TWh"].max() * 1.05)
plt.tight_layout(rect=[0, 0.06, 1, 1])
plt.gcf().text(0.99, 0.02, "data: ember-energy by @iamredave", fontsize=9, ha="right", va="bottom")
if save_path is not None:
plt.savefig(save_path, dpi=150)
plt.close()
print("Saved plot to", save_path)
else:
plt.show()
def get_pakistan_solar_by_year(csv_path: str | Path | None = None) -> pd.DataFrame:
"""
Pakistan solar electricity generation (TWh) by year from monthly data.
Returns DataFrame with columns: Year, Solar_TWh.
"""
df = load_monthly_data(csv_path)
solar = df[
(df["Area"] == "Pakistan")
& (df["Variable"] == "Solar")
& (df["Unit"] == "TWh")
].copy()
solar["Date"] = pd.to_datetime(solar["Date"])
solar["Year"] = solar["Date"].dt.year
result = (
solar.groupby("Year")["Value"]
.sum()
.reset_index()
.sort_values("Year")
.reset_index(drop=True)
)
result = result.rename(columns={"Value": "Solar_TWh"})
return result
def plot_pakistan_solar(
start_year: int = 2015,
csv_path: str | Path | None = None,
save_path: str | Path | None = None,
) -> None:
"""
Plot Pakistan solar electricity generation by year (TWh), same style as China/India solar.
"""
import matplotlib
if save_path is not None:
matplotlib.use("Agg")
import matplotlib.pyplot as plt
df = get_pakistan_solar_by_year(csv_path)
df = df[df["Year"] >= start_year].copy()
if df.empty:
return
plt.figure(figsize=(12, 6))
plt.plot(
df["Year"],
df["Solar_TWh"],
marker="o",
linestyle="-",
color="#CC5500",
)
plt.title("Pakistan Solar Electricity Generation Per Year", fontsize=16)
plt.xlabel("Year")
plt.ylabel("Annual Generation (TWh)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.xticks(df["Year"].astype(int).unique(), rotation=45)
plt.ylim(0, df["Solar_TWh"].max() * 1.05)
plt.tight_layout(rect=[0, 0.06, 1, 1])
plt.gcf().text(0.99, 0.02, "data: ember-energy by @iamredave", fontsize=9, ha="right", va="bottom")
if save_path is not None:
plt.savefig(save_path, dpi=150)
plt.close()
print("Saved plot to", save_path)
else:
plt.show()
def plot_china_coal(
start_year: int = 2015,
csv_path: str | Path | None = None,
source: str = "monthly",
save_path: str | Path | None = None,
) -> None:
"""
Plot China coal electricity generation by year (TWh).
source: "monthly" (default) or "yearly". csv_path: monthly URL/path or yearly path.
If save_path is set, saves the figure to that file instead of showing interactively.
"""
import matplotlib
if save_path is not None:
matplotlib.use("Agg")
import matplotlib.pyplot as plt
df = get_china_coal_by_year(csv_path=csv_path, source=source)
df = df[df["Year"] >= start_year].copy()
if df.empty:
return
plt.figure(figsize=(12, 6))
plt.plot(
df["Year"],
df["Coal_TWh"],
marker="o",
linestyle="-",
color="black",
)
plt.title("China Coal Electricity Generation Per Year", fontsize=16)
plt.xlabel("Year")
plt.ylabel("Annual Generation (TWh)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.xticks(df["Year"].astype(int).unique(), rotation=45)
plt.tight_layout(rect=[0, 0.06, 1, 1])
plt.gcf().text(0.99, 0.02, "data: ember-energy by @iamredave", fontsize=9, ha="right", va="bottom")
if save_path is not None:
plt.savefig(save_path, dpi=150)
plt.close()
print("Saved plot to", save_path)
else:
plt.show()
def get_india_coal_by_year(csv_path: str | Path | None = None) -> pd.DataFrame:
"""
India electricity generation from coal (TWh) by year from monthly data.
Returns a DataFrame with columns: Year, Coal_TWh.
"""
df = load_monthly_data(csv_path)
india_coal = df[
(df["Area"] == "India")
& (df["Variable"] == "Coal")
& (df["Unit"] == "TWh")
].copy()
india_coal["Date"] = pd.to_datetime(india_coal["Date"])
india_coal["Year"] = india_coal["Date"].dt.year
result = (
india_coal.groupby("Year")["Value"]
.sum()
.reset_index()
.sort_values("Year")
.reset_index(drop=True)
)
result = result.rename(columns={"Value": "Coal_TWh"})
return result
def plot_india_coal(
start_year: int = 2015,
csv_path: str | Path | None = None,
save_path: str | Path | None = None,
) -> None:
"""
Plot India coal electricity generation by year (TWh), same style as China coal plot.
"""
import matplotlib
if save_path is not None:
matplotlib.use("Agg")
import matplotlib.pyplot as plt
df = get_india_coal_by_year(csv_path)
df = df[df["Year"] >= start_year].copy()
if df.empty:
return
plt.figure(figsize=(12, 6))
plt.plot(
df["Year"],
df["Coal_TWh"],
marker="o",
linestyle="-",
color="black",
)
plt.title("India Coal Electricity Generation Per Year", fontsize=16)
plt.xlabel("Year")
plt.ylabel("Annual Generation (TWh)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.xticks(df["Year"].astype(int).unique(), rotation=45)
plt.tight_layout(rect=[0, 0.06, 1, 1])
plt.gcf().text(0.99, 0.02, "data: ember-energy by @iamredave", fontsize=9, ha="right", va="bottom")
if save_path is not None:
plt.savefig(save_path, dpi=150)
plt.close()
print("Saved plot to", save_path)
else:
plt.show()
def get_australia_coal_by_year(csv_path: str | Path | None = None) -> pd.DataFrame:
"""
Australia electricity generation from coal (TWh) by year from monthly data.
Only includes years with 12 months of data (excludes partial years like 2026).
Returns a DataFrame with columns: Year, Coal_TWh.
"""
df = load_monthly_data(csv_path)
aus_coal = df[
(df["Area"] == "Australia")
& (df["Variable"] == "Coal")
& (df["Unit"] == "TWh")
].copy()
aus_coal["Date"] = pd.to_datetime(aus_coal["Date"])
aus_coal["Year"] = aus_coal["Date"].dt.year
months_per_year = aus_coal.groupby("Year")["Date"].apply(lambda x: x.dt.month.nunique())
full_years = months_per_year[months_per_year == 12].index
aus_coal_full = aus_coal[aus_coal["Year"].isin(full_years)]
result = (
aus_coal_full.groupby("Year")["Value"]
.sum()
.reset_index()
.sort_values("Year")
.reset_index(drop=True)
)
result = result.rename(columns={"Value": "Coal_TWh"})
return result
def plot_australia_coal(
start_year: int = 2015,
csv_path: str | Path | None = None,
save_path: str | Path | None = None,
) -> None:
"""
Plot Australia coal electricity generation by year (TWh), same style with blue line.
"""
import matplotlib
if save_path is not None:
matplotlib.use("Agg")
import matplotlib.pyplot as plt
df = get_australia_coal_by_year(csv_path)
df = df[df["Year"] >= start_year].copy()
if df.empty:
return
plt.figure(figsize=(12, 6))
plt.plot(
df["Year"],
df["Coal_TWh"],
marker="o",
linestyle="-",
color="#2563EB",
)
plt.title("Australia Coal Electricity Generation Per Year", fontsize=16)
plt.xlabel("Year")
plt.ylabel("Annual Generation (TWh)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.xticks(df["Year"].astype(int).unique(), rotation=45)
plt.tight_layout(rect=[0, 0.06, 1, 1])
plt.gcf().text(0.99, 0.02, "data: ember-energy by @iamredave", fontsize=9, ha="right", va="bottom")
if save_path is not None:
plt.savefig(save_path, dpi=150)
plt.close()
print("Saved plot to", save_path)
else:
plt.show()
def get_china_fossil_vs_renewables_by_year(csv_path: str | Path | None = None) -> pd.DataFrame:
"""
China electricity by year: Coal+Gas (fossil) and Solar+Wind+Hydro (renewables), TWh.
Returns DataFrame with columns: Year, Fossil_TWh, Renewables_TWh.
"""
df = load_monthly_data(csv_path)
df["Date"] = pd.to_datetime(df["Date"])
df["Year"] = df["Date"].dt.year
china = df[
(df["Area"] == "China")
& (df["Unit"] == "TWh")
& (df["Variable"].isin(["Coal", "Gas", "Solar", "Wind", "Hydro"]))
].copy()
by_year_var = china.groupby(["Year", "Variable"])["Value"].sum().reset_index()
fossil_vars = ["Coal", "Gas"]
renew_vars = ["Solar", "Wind", "Hydro"]
fossil = by_year_var[by_year_var["Variable"].isin(fossil_vars)].groupby("Year")["Value"].sum().reset_index().rename(columns={"Value": "Fossil_TWh"})
renew = by_year_var[by_year_var["Variable"].isin(renew_vars)].groupby("Year")["Value"].sum().reset_index().rename(columns={"Value": "Renewables_TWh"})
merged = pd.merge(fossil, renew, on="Year", how="outer").fillna(0)
return merged.sort_values("Year").reset_index(drop=True)
def plot_china_fossil_vs_renewables(
start_year: int = 2015,
csv_path: str | Path | None = None,
save_path: str | Path | None = None,
) -> None:
"""
Plot China: Coal+Gas vs Solar+Wind+Hydro (TWh per year), same style as other graphs.
"""
import matplotlib
if save_path is not None:
matplotlib.use("Agg")
import matplotlib.pyplot as plt
df = get_china_fossil_vs_renewables_by_year(csv_path)
df = df[df["Year"] >= start_year].copy()
if df.empty:
return
plt.figure(figsize=(12, 6))
plt.plot(df["Year"], df["Fossil_TWh"], marker="o", linestyle="-", color="black", label="Coal + Gas")
plt.plot(df["Year"], df["Renewables_TWh"], marker="o", linestyle="-", color="#CC5500", label="Solar + Wind + Hydro")
plt.title("China Electricity: Fossil (Coal+Gas) vs Renewables (Solar+Wind+Hydro)", fontsize=16)
plt.xlabel("Year")
plt.ylabel("Annual Generation (TWh)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.xticks(df["Year"].astype(int).unique(), rotation=45)
plt.legend()
ymax = max(df["Fossil_TWh"].max(), df["Renewables_TWh"].max()) * 1.05
plt.ylim(0, ymax)
plt.tight_layout(rect=[0, 0.06, 1, 1])
plt.gcf().text(0.99, 0.02, "data: ember-energy by @iamredave", fontsize=9, ha="right", va="bottom")
if save_path is not None:
plt.savefig(save_path, dpi=150)
plt.close()
print("Saved plot to", save_path)
else:
plt.show()
def get_china_fossil_vs_renewables_pct_by_year(csv_path: str | Path | None = None) -> pd.DataFrame:
"""
China electricity by year: Coal+Gas and Solar+Wind+Hydro as % of total generation.
Returns DataFrame with columns: Year, Fossil_Pct, Renewables_Pct.
"""
df = load_monthly_data(csv_path)
df["Date"] = pd.to_datetime(df["Date"])
df["Year"] = df["Date"].dt.year
china = df[
(df["Area"] == "China")
& (df["Unit"] == "TWh")
& (df["Variable"].isin(["Coal", "Gas", "Solar", "Wind", "Hydro", "Total Generation"]))
].copy()
by_year_var = china.groupby(["Year", "Variable"])["Value"].sum().reset_index()
fossil_vars = ["Coal", "Gas"]
renew_vars = ["Solar", "Wind", "Hydro"]
fossil = by_year_var[by_year_var["Variable"].isin(fossil_vars)].groupby("Year")["Value"].sum().reset_index().rename(columns={"Value": "Fossil_TWh"})
renew = by_year_var[by_year_var["Variable"].isin(renew_vars)].groupby("Year")["Value"].sum().reset_index().rename(columns={"Value": "Renewables_TWh"})
total = by_year_var[by_year_var["Variable"] == "Total Generation"][["Year", "Value"]].rename(columns={"Value": "Total_TWh"})
merged = pd.merge(fossil, renew, on="Year", how="outer").fillna(0)
merged = pd.merge(merged, total, on="Year", how="inner")
merged["Fossil_Pct"] = (merged["Fossil_TWh"] / merged["Total_TWh"]) * 100
merged["Renewables_Pct"] = (merged["Renewables_TWh"] / merged["Total_TWh"]) * 100
return merged[["Year", "Fossil_Pct", "Renewables_Pct"]].sort_values("Year").reset_index(drop=True)
def plot_china_fossil_vs_renewables_pct(
start_year: int = 2015,
csv_path: str | Path | None = None,
save_path: str | Path | None = None,
) -> None:
"""
Plot China: Coal+Gas and Solar+Wind+Hydro as % of total electricity, same style.
"""
import matplotlib
if save_path is not None:
matplotlib.use("Agg")
import matplotlib.pyplot as plt
df = get_china_fossil_vs_renewables_pct_by_year(csv_path)
df = df[df["Year"] >= start_year].copy()
if df.empty:
return
plt.figure(figsize=(12, 6))
plt.plot(df["Year"], df["Fossil_Pct"], marker="o", linestyle="-", color="black", label="Coal + Gas")
plt.plot(df["Year"], df["Renewables_Pct"], marker="o", linestyle="-", color="#CC5500", label="Solar + Wind + Hydro")
plt.title("China Electricity: Fossil vs Renewables (% of Total Generation)", fontsize=16)
plt.xlabel("Year")
plt.ylabel("Percentage of Total Generation (%)")
plt.grid(True, linestyle="--", alpha=0.6)
plt.xticks(df["Year"].astype(int).unique(), rotation=45)
plt.legend()
ymax = max(df["Fossil_Pct"].max(), df["Renewables_Pct"].max()) * 1.05
plt.ylim(0, ymax)
plt.tight_layout(rect=[0, 0.06, 1, 1])
plt.gcf().text(0.99, 0.02, "data: ember-energy by @iamredave", fontsize=9, ha="right", va="bottom")
if save_path is not None:
plt.savefig(save_path, dpi=150)
plt.close()
print("Saved plot to", save_path)
else:
plt.show()
def get_world_coal_by_year(csv_path: str | Path | None = None) -> pd.DataFrame:
"""
Extract World electricity generation from coal (TWh) for each year in the data.
Returns a DataFrame with columns: Year, Coal_TWh.
If 2025 is not present in the data, prints a message to that effect.
"""
df = load_data(csv_path)
world_coal = df[
(df["Area"] == "World")
& (df["Variable"] == "Coal")
& (df["Unit"] == "TWh")
].copy()
result = world_coal[["Year", "Value"]].sort_values("Year").reset_index(drop=True)
result = result.rename(columns={"Value": "Coal_TWh"})
years = result["Year"].astype(int).tolist()
if 2025 not in years:
print("2025 is not present in the World coal data. Latest year available:", max(years) if years else "N/A")
return result
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Extract coal electricity by year (China / World)")
parser.add_argument(
"--plot",
action="store_true",
help="Plot China coal generation by year (from 2015 by default)",
)
parser.add_argument(
"--start-year",
type=int,
default=2015,
help="Start year for China coal plot (default: 2015)",
)
parser.add_argument(
"--save",
metavar="FILE",
help="Save China coal plot to FILE (e.g. china_coal.png) instead of showing",
)
parser.add_argument(
"--yearly",
action="store_true",
help="Use yearly file for China coal (default: use monthly data)",
)
parser.add_argument(
"--monthly-file",
metavar="PATH",
help="Path to local monthly CSV for China (default: fetch from Ember URL)",
)
parser.add_argument(
"--plot-pct",
action="store_true",
help="Plot China coal percentage of total generation",
)
parser.add_argument(
"--save-pct",
metavar="FILE",
help="Save China coal percentage plot to FILE (e.g. china_coal_pct.png)",
)
parser.add_argument(
"--plot-solar",
action="store_true",
help="Plot China solar generation by year",
)
parser.add_argument(
"--save-solar",
metavar="FILE",
help="Save China solar plot to FILE (e.g. china_solar.png)",
)
parser.add_argument(
"--plot-india-coal",
action="store_true",
help="Plot India coal generation by year",
)
parser.add_argument(
"--save-india-coal",
metavar="FILE",
help="Save India coal plot to FILE (e.g. india_coal.png)",
)
parser.add_argument(
"--plot-india-solar",
action="store_true",
help="Plot India solar generation by year",
)
parser.add_argument(
"--save-india-solar",
metavar="FILE",
help="Save India solar plot to FILE (e.g. india_solar.png)",
)
parser.add_argument(
"--plot-pakistan-solar",
action="store_true",
help="Plot Pakistan solar generation by year",
)
parser.add_argument(
"--save-pakistan-solar",
metavar="FILE",
help="Save Pakistan solar plot to FILE (e.g. pakistan_solar.png)",
)
parser.add_argument(
"--plot-australia-coal",
action="store_true",
help="Plot Australia coal generation by year",
)
parser.add_argument(
"--save-australia-coal",
metavar="FILE",
help="Save Australia coal plot to FILE (e.g. australia_coal.png)",
)
parser.add_argument(
"--save-australia-coal-heat",
metavar="FILE",
help="Save Australia coal heatmap to FILE (e.g. coal_aus_heat.png)",
)
parser.add_argument(
"--plot-fossil-renewables",
action="store_true",
help="Plot China Coal+Gas vs Solar+Wind+Hydro",
)
parser.add_argument(
"--save-fossil-renewables",
metavar="FILE",
help="Save China fossil vs renewables plot to FILE",
)
parser.add_argument(
"--plot-fossil-renewables-pct",
action="store_true",
help="Plot China fossil vs renewables as %% of total generation",
)
parser.add_argument(
"--save-fossil-renewables-pct",
metavar="FILE",
help="Save China fossil vs renewables %% plot to FILE",
)
args = parser.parse_args()
china_source = "yearly" if args.yearly else "monthly"
china_path = None if args.yearly else args.monthly_file
print("=" * 60)
print("China – coal electricity generation by year (TWh)")
if china_source == "monthly":
print("(from monthly data, summed by year)")
print("=" * 60)
china = get_china_coal_by_year(csv_path=china_path, source=china_source)
print(china.to_string(index=False))
print()
print("=" * 60)
print("World – coal electricity generation by year (TWh)")
print("=" * 60)
world = get_world_coal_by_year()
print(world.to_string(index=False))
if 2025 not in world["Year"].astype(int).tolist():
print("\nNote: 2025 is not present in the World coal data.")
print()
print("Done.")
if args.plot or args.save:
save_path = Path(args.save) if args.save else None
plot_china_coal(
start_year=args.start_year,
csv_path=china_path,
source=china_source,
save_path=save_path,
)
if args.plot_pct or args.save_pct:
pct_save = Path(args.save_pct) if args.save_pct else None
plot_china_coal_percentage(
start_year=args.start_year,
csv_path=china_path,
source=china_source,
save_path=pct_save,
)
if args.plot_solar or args.save_solar:
solar_save = Path(args.save_solar) if args.save_solar else None
plot_china_solar(
start_year=args.start_year,
csv_path=china_path,
save_path=solar_save,
)
if args.plot_india_coal or args.save_india_coal:
india_coal_save = Path(args.save_india_coal) if args.save_india_coal else None
plot_india_coal(
start_year=args.start_year,
csv_path=china_path,
save_path=india_coal_save,
)
if args.plot_india_solar or args.save_india_solar:
india_solar_save = Path(args.save_india_solar) if args.save_india_solar else None
plot_india_solar(
start_year=args.start_year,
csv_path=china_path,
save_path=india_solar_save,
)
if args.plot_pakistan_solar or args.save_pakistan_solar:
pakistan_solar_save = Path(args.save_pakistan_solar) if args.save_pakistan_solar else None
plot_pakistan_solar(
start_year=args.start_year,
csv_path=china_path,
save_path=pakistan_solar_save,
)
if args.plot_australia_coal or args.save_australia_coal:
australia_coal_save = Path(args.save_australia_coal) if args.save_australia_coal else None
plot_australia_coal(
start_year=args.start_year,
csv_path=china_path,
save_path=australia_coal_save,
)
if args.save_australia_coal_heat:
from coal_aus_heat import plot_australia_coal_heatmap
plot_australia_coal_heatmap(csv_path=china_path, save_path=Path(args.save_australia_coal_heat))
if args.plot_fossil_renewables or args.save_fossil_renewables:
fr_save = Path(args.save_fossil_renewables) if args.save_fossil_renewables else None
plot_china_fossil_vs_renewables(
start_year=args.start_year,
csv_path=china_path,
save_path=fr_save,
)
if args.plot_fossil_renewables_pct or args.save_fossil_renewables_pct:
fr_pct_save = Path(args.save_fossil_renewables_pct) if args.save_fossil_renewables_pct else None
plot_china_fossil_vs_renewables_pct(
start_year=args.start_year,
csv_path=china_path,
save_path=fr_pct_save,
)
@cavedave
Copy link
Author

cavedave commented Mar 1, 2026

australia_coal

@cavedave
Copy link
Author

cavedave commented Mar 1, 2026

coal_aus_heat

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment