{"spec_id":"histogram-overlapping","library":"bokeh","language":"python","code":"\"\"\" anyplot.ai\nhistogram-overlapping: Overlapping Histograms\nLibrary: bokeh 3.9.2 | Python 3.13.15\nQuality: 93/100 | Updated: 2026-08-18\n\"\"\"\n\nimport os\nimport sys\n\n\n# Prevent local bokeh.py from being treated as bokeh module\nsys.path = [p for p in sys.path if p not in (\"\", \".\", os.getcwd())]\n\nimport time\nfrom pathlib import Path\n\nimport numpy as np\nfrom bokeh.io import output_file, save\nfrom bokeh.models import ColumnDataSource, HoverTool, Span\nfrom bokeh.plotting import figure\nfrom selenium import webdriver\nfrom selenium.webdriver.chrome.options import Options\n\n\n# Theme tokens\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\n# Imprint palette (canonical order)\nBRAND = \"#009E73\"  # Position 1 - first series\nCOLOR_2 = \"#C475FD\"  # Position 2\nCOLOR_3 = \"#4467A3\"  # Position 3\n\n# Data - network latency (ms) across cloud regions\nrng = np.random.default_rng(7)\nus_east = rng.normal(38, 9, 220)\neu_west = rng.normal(64, 14, 220)\nap_south = rng.normal(96, 18, 220)\n\n# Compute histogram bins (aligned across all groups)\nall_data = np.concatenate([us_east, eu_west, ap_south])\nbins = np.linspace(all_data.min() - 5, all_data.max() + 5, 32)\n\n# Compute histogram values\nus_hist, edges = np.histogram(us_east, bins=bins)\neu_hist, _ = np.histogram(eu_west, bins=bins)\nap_hist, _ = np.histogram(ap_south, bins=bins)\n\n# Prepare data for ColumnDataSource\nbin_centers = (edges[:-1] + edges[1:]) / 2\n\n# Per-group means, used for the dashed focal-point markers below\nus_mean = float(us_east.mean())\neu_mean = float(eu_west.mean())\nap_mean = float(ap_south.mean())\n\ndata = {\n    \"bin_left\": edges[:-1],\n    \"bin_right\": edges[1:],\n    \"bin_center\": bin_centers,\n    \"us_count\": us_hist,\n    \"eu_count\": eu_hist,\n    \"ap_count\": ap_hist,\n}\n\nsource = ColumnDataSource(data)\n\n# Create figure (3200 x 1800 px, canonical landscape canvas)\np = figure(\n    width=3200,\n    height=1800,\n    title=\"histogram-overlapping · python · bokeh · anyplot.ai\",\n    x_axis_label=\"Latency (ms)\",\n    y_axis_label=\"Frequency\",\n    tools=\"pan,wheel_zoom,box_zoom,reset,hover\",\n    toolbar_location=None,  # default toolbar adds ~30-50px above the plot,\n    # shrinking the saved PNG below the canonical height\n    min_border_bottom=160,\n    min_border_left=180,\n    min_border_top=110,\n    min_border_right=50,\n)\n\n# Plot overlapping histograms\nus_render = p.quad(\n    top=\"us_count\",\n    bottom=0,\n    left=\"bin_left\",\n    right=\"bin_right\",\n    source=source,\n    fill_color=BRAND,\n    fill_alpha=0.5,\n    line_color=BRAND,\n    line_width=2,\n    line_alpha=0.8,\n    legend_label=\"US-East\",\n    muted_alpha=0.05,\n)\n\neu_render = p.quad(\n    top=\"eu_count\",\n    bottom=0,\n    left=\"bin_left\",\n    right=\"bin_right\",\n    source=source,\n    fill_color=COLOR_2,\n    fill_alpha=0.5,\n    line_color=COLOR_2,\n    line_width=2,\n    line_alpha=0.8,\n    legend_label=\"EU-West\",\n    muted_alpha=0.05,\n)\n\nap_render = p.quad(\n    top=\"ap_count\",\n    bottom=0,\n    left=\"bin_left\",\n    right=\"bin_right\",\n    source=source,\n    fill_color=COLOR_3,\n    fill_alpha=0.5,\n    line_color=COLOR_3,\n    line_width=2,\n    line_alpha=0.8,\n    legend_label=\"AP-South\",\n    muted_alpha=0.05,\n)\n\n# Dashed mean markers - a subtle focal point per region, distinguishing the\n# central tendency of each distribution beyond the raw overlapping bars\nfor mean_val, color in ((us_mean, BRAND), (eu_mean, COLOR_2), (ap_mean, COLOR_3)):\n    p.add_layout(\n        Span(location=mean_val, dimension=\"height\", line_color=color, line_dash=\"dashed\", line_width=3, line_alpha=0.9)\n    )\n\n# Configure hover tool\nhover = p.select_one(HoverTool)\nhover.tooltips = [\n    (\"Range\", \"@bin_left ms - @bin_right ms\"),\n    (\"US-East\", \"@us_count\"),\n    (\"EU-West\", \"@eu_count\"),\n    (\"AP-South\", \"@ap_count\"),\n]\n\n# Configure text sizes for the 3200x1800 canvas\np.title.text_font_size = \"50pt\"\np.xaxis.axis_label_text_font_size = \"42pt\"\np.yaxis.axis_label_text_font_size = \"42pt\"\np.xaxis.major_label_text_font_size = \"34pt\"\np.yaxis.major_label_text_font_size = \"34pt\"\n\n# Theme-adaptive chrome\np.background_fill_color = PAGE_BG\np.border_fill_color = PAGE_BG\n# Drop the full rectangular frame - the bottom/left axis lines already form\n# an L-shaped frame, which reads cleaner than a boxed-in plot area\np.outline_line_color = None\n\np.title.text_color = INK\np.xaxis.axis_label_text_color = INK\np.yaxis.axis_label_text_color = INK\np.xaxis.major_label_text_color = INK_SOFT\np.yaxis.major_label_text_color = INK_SOFT\np.xaxis.axis_line_color = INK_SOFT\np.yaxis.axis_line_color = INK_SOFT\np.xaxis.major_tick_line_color = INK_SOFT\np.yaxis.major_tick_line_color = INK_SOFT\n\np.xgrid.grid_line_color = INK\np.ygrid.grid_line_color = INK\np.xgrid.grid_line_alpha = 0.15\np.ygrid.grid_line_alpha = 0.15\n\n# Configure legend - click a label to mute that region's histogram, a\n# genuine bokeh-native interaction beyond the static HoverTool tooltips\np.legend.location = \"top_left\"\np.legend.label_text_font_size = \"34pt\"\np.legend.spacing = 10\np.legend.padding = 15\np.legend.background_fill_color = ELEVATED_BG\np.legend.border_line_color = INK_SOFT\np.legend.border_line_alpha = 0.4\np.legend.border_radius = 6\np.legend.label_text_color = INK_SOFT\np.legend.glyph_height = 34\np.legend.glyph_width = 34\np.legend.click_policy = \"mute\"\n\n# Save HTML\noutput_file(f\"plot-{THEME}.html\")\nsave(p)\n\n# Screenshot with headless Chrome via Selenium\nW, H = 3200, 1800\nopts = Options()\nfor arg in (\n    \"--headless=new\",\n    \"--no-sandbox\",\n    \"--disable-dev-shm-usage\",\n    \"--disable-gpu\",\n    f\"--window-size={W},{H}\",\n    \"--hide-scrollbars\",\n):\n    opts.add_argument(arg)\n\ndriver = webdriver.Chrome(options=opts)\ndriver.set_window_size(W, H)\ndriver.get(f\"file://{Path(f'plot-{THEME}.html').resolve()}\")\n# headless Chrome's --window-size sets the OUTER window, which still reserves\n# a phantom title-bar height even headless; pin the viewport exactly via CDP.\ndriver.execute_cdp_cmd(\n    \"Emulation.setDeviceMetricsOverride\", {\"width\": W, \"height\": H, \"deviceScaleFactor\": 1, \"mobile\": False}\n)\ntime.sleep(3)\ndriver.save_screenshot(f\"plot-{THEME}.png\")\ndriver.quit()\n"}