Last active
February 22, 2026 10:53
-
-
Save cavedave/db907afb75ebac0c15c933d611861f2c to your computer and use it in GitHub Desktop.
Irelands alcohol consumption over time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import pandas as pd | |
| url = "https://sdmx.oecd.org/public/rest/data/OECD.ELS.HD,DSD_HEALTH_LVNG@DF_HEALTH_LVNG_AC,1.0/.A.....?dimensionAtObservation=AllDimensions&format=csvfilewithlabels&startPeriod=1960" | |
| df = pd.read_csv( | |
| url, | |
| storage_options={ | |
| "User-Agent": "Mozilla/5.0" | |
| } | |
| ) | |
| # Keep only USA rows (country code column is usually REF_AREA) | |
| usa = df[df["REF_AREA"] == "USA"].copy() | |
| usa.head() | |
| import matplotlib.pyplot as plt | |
| # --- Define columns for OECD dataframe --- | |
| time_col = "TIME_PERIOD" | |
| value_col = "OBS_VALUE" | |
| # --- Make sure year/value are numeric and sorted --- | |
| usa = usa.copy() | |
| usa[time_col] = pd.to_numeric(usa[time_col], errors="coerce") | |
| usa[value_col] = pd.to_numeric(usa[value_col], errors="coerce") | |
| usa = usa.dropna(subset=[time_col, value_col]).sort_values(time_col) | |
| # Optional: cast year to int for cleaner matching | |
| usa[time_col] = usa[time_col].astype(int) | |
| # --- Color Palette (Modern "Journalist" Look) --- | |
| LINE_COLOR = "#1B4F72" # Deep Navy | |
| HIGHLIGHT_COLOR = "#CB4335" # Muted Red for events | |
| GRID_COLOR = "#EAECEE" | |
| match_year = 1987 | |
| latest_year = int(usa[time_col].iloc[-1]) | |
| y_match = float(usa.loc[usa[time_col] == match_year, value_col].iloc[0]) | |
| y_latest = float(usa.loc[usa[time_col] == latest_year, value_col].iloc[0]) | |
| fig, ax = plt.subplots(figsize=(11, 6), facecolor='white') | |
| # 1. Comparison Line (1987 level) | |
| #ax.hlines(y=y_match, xmin=1987, xmax=latest_year, | |
| # colors='gray', linestyles='--', alpha=0.3, linewidth=1, zorder=1) | |
| # 2. Main Line | |
| ax.plot(usa[time_col], usa[value_col], color=LINE_COLOR, | |
| linewidth=3.5, solid_capstyle="round", zorder=3) | |
| # 3. Event Markers (placeholders for now) | |
| events = [ | |
| (1984, "Drinking Age 21 law", "bottom", -2.3), # Added 'bottom' for va | |
| (1991, "Federal alcohol\n tax increase","bottom", -0.9), # Added 'bottom' for va | |
| (2008, "Great Recession", "top", -0.9), | |
| (2020, "COVID-19", "bottom", -1.5) | |
| #(2022, "Minimum Pricing", "bottom", -1.0) # placeholder | |
| ] | |
| for year, label, va, offset in events: | |
| # Skip if year not present | |
| if year not in set(usa[time_col].values): | |
| continue | |
| y_val = float(usa.loc[usa[time_col] == year, value_col].iloc[0]) | |
| ax.axvline(year, color=HIGHLIGHT_COLOR, linestyle="--", linewidth=1, alpha=0.4, zorder=2) | |
| ax.text(year, y_val + offset, label, color=HIGHLIGHT_COLOR, | |
| fontweight='bold', fontsize=9, ha='center', va=va) | |
| # 4. Key Data Points | |
| peak_i = usa[value_col].idxmax() | |
| peak_year = int(usa.loc[peak_i, time_col]) | |
| peak_val = float(usa.loc[peak_i, value_col]) | |
| ax.scatter([peak_year, latest_year], [peak_val, y_latest], | |
| color=LINE_COLOR, s=70, edgecolors='white', zorder=5) | |
| # 5. Clean Annotations | |
| #ax.annotate(f"Peak: {peak_val:.1f}L", | |
| # xy=(peak_year, peak_val), xytext=(peak_year-2, peak_val+0.6), | |
| # fontweight='bold', fontsize=11) | |
| ax.annotate(f"Peak: {peak_year} ({peak_val:.1f}L)", | |
| xy=(peak_year, peak_val), | |
| xytext=(peak_year-15, peak_val-0.15), | |
| arrowprops=dict(arrowstyle="->", color="gray", lw=1), | |
| fontweight='bold', fontsize=11, ha='left', va='bottom') | |
| #ax.annotate(f"Back to {match_year} levels ({y_latest:.1f}L)", | |
| # xy=(latest_year, y_latest), xytext=(latest_year-9, y_latest-1.2), | |
| # arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=.2', color='gray'), | |
| # fontsize=10) | |
| # Current (latest) level | |
| latest_year = int(usa[time_col].iloc[-1]) # 2022 | |
| latest_val = float(usa[value_col].iloc[-1]) # 9.5 | |
| # Exact historical match(es) you found | |
| y_1970 = float(usa.loc[usa[time_col] == 1970, value_col].iloc[0]) | |
| # Near match in 1990s | |
| #y_1988 = float(usa.loc[usa[time_col] == 1988, value_col].iloc[0]) | |
| # Horizontal comparison line at current level | |
| ax.hlines(y=latest_val, xmin=1970, xmax=latest_year, | |
| colors="gray", linestyles="--", alpha=0.35, linewidth=1.2, zorder=1) | |
| # Highlight the comparison points y_1988, | |
| ax.scatter([1970, latest_year], [y_1970, latest_val], | |
| s=55, color=LINE_COLOR, edgecolors="white", zorder=6) | |
| # Label / callout | |
| ax.annotate("2022 matches 1970 (9.5L)", | |
| xy=(latest_year, latest_val), | |
| xytext=(latest_year-16, latest_val-1.1), | |
| arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2", color="gray"), | |
| fontsize=10, ha="left") | |
| # 6. Title and Labels (placeholder text) | |
| plt.title("Americans’ Average Alcohol Consumption", | |
| fontsize=20, fontweight='bold', pad=25, loc='left', color="#2C3E50") | |
| ax.set_ylabel("Litres per capita per year (age 15+)", fontsize=11, fontweight='bold', alpha=0.7) | |
| ax.grid(True, axis='y', alpha=0.3, color=GRID_COLOR) | |
| ax.spines["top"].set_visible(False) | |
| ax.spines["right"].set_visible(False) | |
| # Footer | |
| plt.figtext(0.9, 0.001, "Data: OECD Graph: @iamreddave", ha="right", fontsize=9, alpha=0.5) | |
| plt.tight_layout() | |
| plt.savefig("usa_alcohol_oecd.png", dpi=300, bbox_inches="tight") | |
| plt.show() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import pandas as pd | |
| url = "https://sdmx.oecd.org/public/rest/data/OECD.ELS.HD,DSD_HEALTH_LVNG@DF_HEALTH_LVNG_AC,1.0/.A.....?dimensionAtObservation=AllDimensions&format=csvfilewithlabels&startPeriod=1960" | |
| df = pd.read_csv( | |
| url, | |
| storage_options={ | |
| "User-Agent": "Mozilla/5.0" | |
| } | |
| ) | |
| # --- Color Palette (Modern "Journalist" Look) --- | |
| LINE_COLOR = "#1B4F72" # Deep Navy | |
| HIGHLIGHT_COLOR = "#CB4335" # Muted Red for events | |
| GRID_COLOR = "#EAECEE" | |
| match_year = 1987 | |
| latest_year = int(ireland[time_col].iloc[-1]) | |
| y_match = float(ireland.loc[ireland[time_col] == match_year, value_col].iloc[0]) | |
| y_latest = float(ireland.loc[ireland[time_col] == latest_year, value_col].iloc[0]) | |
| fig, ax = plt.subplots(figsize=(11, 6), facecolor='white') | |
| # 1. Comparison Line (1987 level) | |
| ax.hlines(y=y_match, xmin=1987, xmax=latest_year, | |
| colors='gray', linestyles='--', alpha=0.3, linewidth=1, zorder=1) | |
| # 2. Main Line | |
| ax.plot(ireland[time_col], ireland[value_col], color=LINE_COLOR, | |
| linewidth=3.5, solid_capstyle="round", zorder=3) | |
| # 3. Event Markers (Moved Smoking Ban down) | |
| events = [ | |
| (2004, "Smoking Ban", "bottom", -8.8), # Negative offset to move it DOWN | |
| (2008, "Economic Crash", "top", -6.3), | |
| (2020, "COVID-19", "bottom", -5.) | |
| ] | |
| for year, label, va, offset in events: | |
| y_val = float(ireland.loc[ireland[time_col] == year, value_col].iloc[0]) | |
| ax.axvline(year, color=HIGHLIGHT_COLOR, linestyle="--", linewidth=1, alpha=0.4, zorder=2) | |
| ax.text(year, y_val + offset, label, color=HIGHLIGHT_COLOR, | |
| fontweight='bold', fontsize=9, ha='center', va=va) | |
| # 4. Key Data Points | |
| peak_i = ireland[value_col].idxmax() | |
| peak_year = int(ireland.loc[peak_i, time_col]) | |
| peak_val = float(ireland.loc[peak_i, value_col]) | |
| ax.scatter([peak_year, latest_year], [peak_val, y_latest], | |
| color=LINE_COLOR, s=70, edgecolors='white', zorder=5) | |
| # 5. Clean Annotations | |
| ax.annotate(f"Peak: {peak_val:.1f}L", xy=(peak_year, peak_val), xytext=(peak_year-2, peak_val+0.6), | |
| fontweight='bold', fontsize=11) | |
| ax.annotate(f"Back to {match_year} levels ({y_latest:.1f}L)", | |
| xy=(latest_year, y_latest), xytext=(latest_year-9, y_latest-1.2), | |
| arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2", color="gray"), | |
| fontsize=10) | |
| # 6. Title and Labels (Centered title option) | |
| plt.title("Ireland's Alcohol Consumption: A 25-Year Decline", | |
| fontsize=20, fontweight='bold', pad=25, loc='left', color="#2C3E50") | |
| ax.set_ylabel("Litres per capita (age 15+)", fontsize=11, fontweight='bold', alpha=0.7) | |
| ax.grid(True, axis='y', alpha=0.3, color=GRID_COLOR) | |
| ax.spines["top"].set_visible(False) | |
| ax.spines["right"].set_visible(False) | |
| # Footer | |
| plt.figtext(0.9, 0.001, "Data: OECD • Visual: @iamreddave", ha="right", fontsize=9, alpha=0.5) | |
| plt.tight_layout() | |
| plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
