diff --git a/src/charts/nvidia_revenue.py b/src/charts/nvidia_revenue.py new file mode 100644 index 0000000..03f461e --- /dev/null +++ b/src/charts/nvidia_revenue.py @@ -0,0 +1,152 @@ +"""NVIDIA Data Center Revenue Chart""" +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +from src.data.ai_infrastructure import nvidia_revenue, nvidia_revenue_meta +from src.utils.styling import get_theme, EXPORT_DPI, REVENUE, GRAY_DARK, AI_SPEND + + +def plot_nvidia_datacenter() -> str: + plt.rcParams.update(get_theme()) + fig, ax1 = plt.subplots(figsize=(14, 8)) + + # Filter data center revenue + quarters = [d["fiscal_quarter"] for d in nvidia_revenue] + dc_rev = [ + d.get( + "data_center_billions", + d.get("compute_billions", 0) + d.get("networking_billions", 0), + ) + for d in nvidia_revenue + ] + + # Calculate YoY growth + growth = [] + for i in range(len(dc_rev)): + if i >= 4: # Need previous year's same quarter + prev = dc_rev[i - 4] + if prev > 0: + growth.append(((dc_rev[i] - prev) / prev) * 100) + else: + growth.append(None) + else: + growth.append(None) + + # Plot DC revenue (left axis) + ax1.fill_between(range(len(dc_rev)), dc_rev, alpha=0.3, color=REVENUE) + line1 = ax1.plot( + range(len(dc_rev)), dc_rev, color=REVENUE, linewidth=2, label="Data Center Revenue" + ) + ax1.set_ylabel("Data Center Revenue ($B)", fontsize=12, color=REVENUE) + ax1.set_ylim(0, max(dc_rev) * 1.2) + + # Plot YoY growth (right axis) + ax2 = ax1.twinx() + growth_values = [g for g in growth if g is not None] + growth_indices = [i for i, g in enumerate(growth) if g is not None] + line2 = ax2.plot( + growth_indices, + growth_values, + color=AI_SPEND, + linewidth=2, + marker="o", + markersize=4, + label="YoY Growth Rate", + ) + ax2.set_ylabel("YoY Growth Rate (%)", fontsize=12, color=AI_SPEND) + ax2.set_ylim(-50, max(growth_values) * 1.1) + + # AI infrastructure buildout shading + ai_start_idx = 17 # FY2024 Q2 + ax1.axvspan(ai_start_idx - 0.5, len(dc_rev) - 0.5, alpha=0.1, color=REVENUE) + ax1.text( + ai_start_idx, + max(dc_rev) * 0.8, + "AI Infrastructure\nBuildout", + fontsize=10, + ha="center", + style="italic", + color=REVENUE, + ) + + # Annotations + ax1.annotate( + "AI demand surge\n(>$10B DC)", + xy=(17, dc_rev[17]), + xytext=(14, dc_rev[17] + 10), + arrowprops=dict(arrowstyle="->", color="gray", lw=1), + fontsize=9, + ha="center", + ) + + # FY2025 Q4 annotation (index 23, ~$39.3B) + ax1.annotate( + "$39.3B DC rev", + xy=(23, dc_rev[23]), + xytext=(20, dc_rev[23] + 5), + arrowprops=dict(arrowstyle="->", color="gray", lw=1), + fontsize=9, + ha="center", + ) + + # FY2027 Q1 annotation (index 28, ~$75.2B, decelerating) + ax1.annotate( + "$75.2B DC rev, 70.7% YoY", + xy=(28, dc_rev[28]), + xytext=(25, dc_rev[28] + 5), + arrowprops=dict(arrowstyle="->", color="gray", lw=1), + fontsize=9, + ha="center", + ) + + # Title and subtitle + ax1.set_title( + "NVIDIA Data Center Revenue \u2014 Growth and Deceleration", + fontsize=16, + fontweight="bold", + ) + fig.text( + 0.5, + 0.93, + "Quarterly revenue FY2020\u2013FY2027 | Growth rate: from 323% to ~70%", + fontsize=11, + ha="center", + style="italic", + color=GRAY_DARK, + ) + + ax1.set_xlabel("Quarter (FY2020-Q1 \u2192 FY2027-Q1)", fontsize=12) + ax1.grid(True, alpha=0.3) + + # Format x-axis + ax1.set_xticks(range(0, len(quarters), 4)) + ax1.set_xticklabels( + [q for i, q in enumerate(quarters) if i % 4 == 0], + rotation=45, + ha="right", + fontsize=8, + ) + + # Combined legend + lines1, labels1 = ax1.get_legend_handles_labels() + lines2, labels2 = ax2.get_legend_handles_labels() + ax1.legend(lines1 + lines2, labels1 + labels2, loc="upper left", fontsize=9) + + fig.savefig( + "output/charts/07_nvidia_datacenter.png", + dpi=EXPORT_DPI, + facecolor=fig.get_facecolor(), + edgecolor="none", + ) + plt.close(fig) + return "output/charts/07_nvidia_datacenter.png" + + +def main(): + path = plot_nvidia_datacenter() + print(f"Chart saved: {path}") + + +if __name__ == "__main__": + main()