{"spec_id":"contour-basic","library":"bokeh","language":"python","code":"\"\"\" anyplot.ai\ncontour-basic: Basic Contour Plot\nLibrary: bokeh 3.9.1 | Python 3.13.14\nQuality: 93/100 | Updated: 2026-06-25\n\"\"\"\n\nimport os\nimport sys\nimport time\nfrom pathlib import Path\n\n\n# bokeh.py shadows the installed bokeh package — remove current dir from path\nsys.path = [p for p in sys.path if p not in (\"\", os.getcwd())]\n\nimport numpy as np\nfrom bokeh.io import output_file, save\nfrom bokeh.models import HoverTool, Label, LinearColorMapper\nfrom bokeh.plotting import figure\nfrom selenium import webdriver\nfrom selenium.webdriver.chrome.options import Options\n\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\n# Imprint sequential palette: brand green (#009E73) → blue (#4467A3) — 256 stops\n_r0, _g0, _b0 = 0x00, 0x9E, 0x73\n_r1, _g1, _b1 = 0x44, 0x67, 0xA3\nANYPLOT_SEQ256 = [\n    \"#{:02X}{:02X}{:02X}\".format(\n        round(_r0 + (_r1 - _r0) * t / 255), round(_g0 + (_g1 - _g0) * t / 255), round(_b0 + (_b1 - _b0) * t / 255)\n    )\n    for t in range(256)\n]\n\n# Data — simulated topographic elevation map of a 10km x 10km mountain region\nx = np.linspace(0, 10, 90)\ny = np.linspace(0, 10, 90)\nX, Y = np.meshgrid(x, y)\n\nelevation = (\n    850 * np.exp(-((X - 7) ** 2 + (Y - 7) ** 2) / 4.0)\n    + 550 * np.exp(-((X - 2.5) ** 2 + (Y - 3) ** 2) / 3.0)\n    - 180 * np.exp(-((X - 5) ** 2 + (Y - 5) ** 2) / 8.0)\n    + 12 * X\n    + 350\n)\n\nlevels = np.linspace(elevation.min(), elevation.max(), 14)\n\n# Locate the two peaks for annotations\n_ne_iy, _ne_ix = np.unravel_index(elevation.argmax(), elevation.shape)\nx_ne, y_ne = float(x[_ne_ix]), float(y[_ne_iy])\nne_peak_elev = int(round(float(elevation[_ne_iy, _ne_ix])))\n\n_sw_elev = np.where((X < 5) & (Y < 6), elevation, 0)\n_sw_iy, _sw_ix = np.unravel_index(_sw_elev.argmax(), _sw_elev.shape)\nx_sw, y_sw = float(x[_sw_ix]), float(y[_sw_iy])\nsw_peak_elev = int(round(float(elevation[_sw_iy, _sw_ix])))\n\n# Title — 62 chars, below 67-char baseline\ntitle = \"Mountain Terrain · contour-basic · python · bokeh · anyplot.ai\"\n\n# Plot — canonical 3200×1800 landscape canvas\nW, H = 3200, 1800\np = figure(\n    width=W,\n    height=H,\n    title=title,\n    x_axis_label=\"Distance East (km)\",\n    y_axis_label=\"Distance North (km)\",\n    toolbar_location=None,\n    x_range=(0, 10),\n    y_range=(0, 10),\n    match_aspect=True,\n    min_border_bottom=160,\n    min_border_left=180,\n    min_border_top=110,\n    min_border_right=50,\n)\n\ncontour = p.contour(\n    x=X, y=Y, z=elevation, levels=levels, fill_color=ANYPLOT_SEQ256, line_color=PAGE_BG, line_width=2, line_alpha=0.45\n)\n\ncolorbar = contour.construct_color_bar(\n    title=\"Elevation (m)\",\n    title_text_font_size=\"26pt\",\n    title_text_color=INK,\n    title_text_font_style=\"normal\",\n    title_standoff=20,\n    major_label_text_font_size=\"22pt\",\n    major_label_text_color=INK_SOFT,\n    background_fill_color=PAGE_BG,\n    border_line_color=None,\n    width=60,\n    padding=20,\n)\np.add_layout(colorbar, \"right\")\n\n# Invisible image renderer — enables HoverTool elevation readout in the HTML artifact\n_mapper = LinearColorMapper(palette=ANYPLOT_SEQ256, low=elevation.min(), high=elevation.max())\n_img_r = p.image(image=[elevation], x=0, y=0, dw=10, dh=10, color_mapper=_mapper, alpha=0)\np.add_tools(\n    HoverTool(\n        renderers=[_img_r], tooltips=[(\"Position\", \"($x{0.1f} km E, $y{0.1f} km N)\"), (\"Elevation\", \"@image{0} m\")]\n    )\n)\n\n# Contour level labels — every 3rd level labels key isolines (spec: \"label when practical\")\nfor _i in (1, 4, 7, 10):\n    _level_val = levels[_i]\n    _diff = np.abs(elevation - _level_val)\n    # Exclude borders and the right-side colorbar zone (x > ~8)\n    _diff[:4, :] = np.inf\n    _diff[-4:, :] = np.inf\n    _diff[:, :4] = np.inf\n    _diff[:, -18:] = np.inf\n    _iy, _ix = np.unravel_index(_diff.argmin(), _diff.shape)\n    if np.isfinite(_diff[_iy, _ix]):\n        p.add_layout(\n            Label(\n                x=float(x[_ix]),\n                y=float(y[_iy]),\n                text=f\"{int(round(_level_val))}\",\n                text_font_size=\"22pt\",\n                text_color=INK,\n                text_align=\"center\",\n                text_baseline=\"middle\",\n                background_fill_color=PAGE_BG,\n                background_fill_alpha=0.8,\n                border_line_color=INK_SOFT,\n                border_line_alpha=0.4,\n            )\n        )\n\n# Summit annotations — storytelling focal points for the two elevation peaks\nfor _x_pk, _y_pk, _elev_pk in ((x_ne, y_ne, ne_peak_elev), (x_sw, y_sw, sw_peak_elev)):\n    p.add_layout(\n        Label(\n            x=_x_pk,\n            y=_y_pk,\n            text=f\"▲ {_elev_pk} m\",\n            text_font_size=\"26pt\",\n            text_color=INK,\n            text_align=\"center\",\n            text_baseline=\"bottom\",\n            x_offset=0,\n            y_offset=40,\n            background_fill_color=PAGE_BG,\n            background_fill_alpha=0.8,\n            border_line_color=None,\n        )\n    )\n\n# Typography — sized for 3200×1800 canvas\np.title.text_font_size = \"50pt\"\np.title.text_font_style = \"bold\"\np.title.text_color = INK\np.title.align = \"center\"\n\np.xaxis.axis_label_text_font_size = \"42pt\"\np.yaxis.axis_label_text_font_size = \"42pt\"\np.xaxis.axis_label_text_font_style = \"normal\"\np.yaxis.axis_label_text_font_style = \"normal\"\np.xaxis.major_label_text_font_size = \"34pt\"\np.yaxis.major_label_text_font_size = \"34pt\"\np.xaxis.axis_label_standoff = 28\np.yaxis.axis_label_standoff = 28\n\n# Theme-adaptive chrome\np.background_fill_color = PAGE_BG\np.border_fill_color = PAGE_BG\np.outline_line_color = None  # frameless — cleaner minimalist look\n\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\np.xaxis.minor_tick_line_color = None\np.yaxis.minor_tick_line_color = None\n\n# Filled contour covers the plot area — disable grid to avoid noise\np.xgrid.grid_line_color = None\np.ygrid.grid_line_color = None\n\np.xaxis.ticker.desired_num_ticks = 10\np.yaxis.ticker.desired_num_ticks = 8\n\n# Save HTML (interactive catalog artifact)\noutput_file(f\"plot-{THEME}.html\", title=\"contour-basic · bokeh · anyplot.ai\")\nsave(p)\n\n# Screenshot with headless Chrome — CDP device override ensures exact W×H pixel output\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)\ndriver = webdriver.Chrome(options=opts)\ndriver.execute_cdp_cmd(\n    \"Emulation.setDeviceMetricsOverride\", {\"width\": W, \"height\": H, \"deviceScaleFactor\": 1, \"mobile\": False}\n)\ndriver.get(f\"file://{Path(f'plot-{THEME}.html').resolve()}\")\ntime.sleep(3)\ndriver.save_screenshot(f\"plot-{THEME}.png\")\ndriver.quit()\n"}