{"spec_id":"indicator-ema","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nindicator-ema: Exponential Moving Average (EMA) Indicator Chart\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 84/100 | Updated: 2026-05-19\n\"\"\"\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    element_rect,\n    element_text,\n    geom_line,\n    geom_point,\n    ggplot,\n    labs,\n    scale_color_manual,\n    scale_x_datetime,\n    theme,\n    theme_minimal,\n)\n\n\n# Data - Generate synthetic stock price data with EMAs\nnp.random.seed(42)\n\n# Generate 120 trading days\nn_days = 120\ndates = pd.date_range(start=\"2024-01-02\", periods=n_days, freq=\"B\")\n\n# Generate realistic stock price using random walk with drift\ninitial_price = 150.0\nreturns = np.random.normal(0.0008, 0.018, n_days)\nprice = initial_price * np.cumprod(1 + returns)\n\n# Calculate EMAs using pandas ewm\nema_12 = pd.Series(price).ewm(span=12, adjust=False).mean().values\nema_26 = pd.Series(price).ewm(span=26, adjust=False).mean().values\n\n# Create long-format DataFrame for plotnine\ndf_price = pd.DataFrame({\"date\": dates, \"value\": price, \"series\": \"Close Price\"})\ndf_ema12 = pd.DataFrame({\"date\": dates, \"value\": ema_12, \"series\": \"EMA-12\"})\ndf_ema26 = pd.DataFrame({\"date\": dates, \"value\": ema_26, \"series\": \"EMA-26\"})\ndf = pd.concat([df_price, df_ema12, df_ema26], ignore_index=True)\n\n# Define colors - Python Blue for price, distinct colors for EMAs\ncolors = {\"Close Price\": \"#306998\", \"EMA-12\": \"#E24A33\", \"EMA-26\": \"#FFD43B\"}\n\n# Find crossover points (where EMA-12 crosses EMA-26)\ncrossover_indices = []\nfor i in range(1, len(ema_12)):\n    if (ema_12[i - 1] <= ema_26[i - 1] and ema_12[i] > ema_26[i]) or (\n        ema_12[i - 1] >= ema_26[i - 1] and ema_12[i] < ema_26[i]\n    ):\n        crossover_indices.append(i)\n\ndf_crossovers = pd.DataFrame({\"date\": dates[crossover_indices], \"value\": ema_12[crossover_indices]})\n\n# Plot\nplot = (\n    ggplot(df, aes(x=\"date\", y=\"value\", color=\"series\"))\n    + geom_line(data=df[df[\"series\"] == \"Close Price\"], size=1.8, alpha=0.9)\n    + geom_line(data=df[df[\"series\"] == \"EMA-12\"], size=1.2, alpha=0.85)\n    + geom_line(data=df[df[\"series\"] == \"EMA-26\"], size=1.2, alpha=0.85)\n    + geom_point(df_crossovers, aes(x=\"date\", y=\"value\"), color=\"#2CA02C\", size=5, alpha=1.0, inherit_aes=False)\n    + scale_color_manual(values=colors)\n    + scale_x_datetime(date_breaks=\"1 month\", date_labels=\"%b %Y\")\n    + labs(title=\"indicator-ema \\u00b7 plotnine \\u00b7 pyplots.ai\", x=\"Date\", y=\"Price ($)\", color=\"Series\")\n    + theme_minimal()\n    + theme(\n        figure_size=(16, 9),\n        plot_title=element_text(size=24, weight=\"bold\"),\n        axis_title=element_text(size=20),\n        axis_text=element_text(size=16),\n        axis_text_x=element_text(angle=45, ha=\"right\"),\n        legend_title=element_text(size=18),\n        legend_text=element_text(size=16),\n        legend_position=\"right\",\n        legend_background=element_rect(fill=\"white\", alpha=0.8),\n    )\n)\n\n# Save\nplot.save(\"plot.png\", dpi=300, verbose=False)\n"}