{"spec_id":"histogram-stepwise","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nhistogram-stepwise: Step Histogram\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 84/100 | Updated: 2026-05-12\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import *\n\n\nLetsPlot.setup_html()\n\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\"]\n\n# Data - Generate two distributions for comparison (temperature readings)\nnp.random.seed(42)\nmorning_temps = np.random.normal(loc=18, scale=4, size=500)\nafternoon_temps = np.random.normal(loc=26, scale=5, size=500)\n\n# Compute histogram bins manually for step representation\nbins = 30\nall_data = np.concatenate([morning_temps, afternoon_temps])\nbin_edges = np.linspace(all_data.min(), all_data.max(), bins + 1)\n\n# Calculate histogram counts for each distribution\nmorning_counts, _ = np.histogram(morning_temps, bins=bin_edges)\nafternoon_counts, _ = np.histogram(afternoon_temps, bins=bin_edges)\n\n# Create step data: duplicate each point for step appearance\nstep_data = []\nfor counts, label in [(morning_counts, \"Morning\"), (afternoon_counts, \"Afternoon\")]:\n    for i in range(len(counts)):\n        step_data.append({\"x\": bin_edges[i], \"y\": counts[i], \"period\": label})\n        step_data.append({\"x\": bin_edges[i + 1], \"y\": counts[i], \"period\": label})\n\ndf_step = pd.DataFrame(step_data)\n\n# Plot - Step histogram using geom_line\nplot = (\n    ggplot(df_step, aes(x=\"x\", y=\"y\", color=\"period\"))\n    + geom_line(size=2.5)\n    + scale_color_manual(values=IMPRINT[:2])\n    + labs(x=\"Temperature (°C)\", y=\"Frequency\", title=\"histogram-stepwise · letsplot · anyplot.ai\", color=\"Time Period\")\n    + theme_minimal()\n    + theme(\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        panel_grid_major=element_line(color=INK_SOFT, size=0.3),\n        panel_grid_minor=element_blank(),\n        axis_title=element_text(size=20, color=INK),\n        axis_text=element_text(size=16, color=INK_SOFT),\n        axis_line=element_line(color=INK_SOFT),\n        plot_title=element_text(size=24, color=INK),\n        legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n        legend_text=element_text(size=16, color=INK_SOFT),\n        legend_title=element_text(size=18, color=INK),\n        legend_position=\"right\",\n    )\n    + ggsize(1600, 900)\n)\n\n# Save PNG (scale=3 gives 4800x2700)\nggsave(plot, f\"plot-{THEME}.png\", scale=3, path=\".\")\n\n# Save HTML for interactivity\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}