{"spec_id":"star-chart-constellation","library":"bokeh","language":"python","code":"\"\"\" anyplot.ai\nstar-chart-constellation: Star Chart with Constellations\nLibrary: bokeh 3.9.1 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-06-17\n\"\"\"\n\nimport os\nimport time\nfrom pathlib import Path\n\nimport numpy as np\nfrom bokeh.io import output_file, save\nfrom bokeh.models import ColumnDataSource, Label, LabelSet, Range1d\nfrom bokeh.plotting import figure\nfrom selenium import webdriver\nfrom selenium.webdriver.chrome.options import Options\n\n\n# Theme tokens (see prompts/default-style-guide.md \"Background\" + \"Theme-adaptive Chrome\").\n# A star chart is intrinsically a night-sky view, so the two themes are read as:\n#   dark  -> literal night sky: pale stars on near-black #1A1A17\n#   light -> antique engraved star atlas: ink stars on warm cream #FAF8F1\n# Star MAGNITUDE is encoded by point SIZE (the real data dimension); the star tone\n# only flips with the theme so the chart stays legible on both surfaces.\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\n# Sky-specific theme tones (structural chrome, not categorical data)\nSTAR_BRIGHT = \"#1A1A17\" if THEME == \"light\" else \"#FFFDE7\"\nSTAR_MID = \"#3D4D6B\" if THEME == \"light\" else \"#DDE3F0\"\nSTAR_DIM = \"#8089A0\" if THEME == \"light\" else \"#9FB0C4\"\nLINE_COLOR = \"#4467A3\" if THEME == \"light\" else \"#5E7BB5\"  # Imprint blue (lightened on dark)\nGRID_COLOR = \"#C2C8D6\" if THEME == \"light\" else \"#3D4A66\"\nGRID_LABEL = \"#7A8398\" if THEME == \"light\" else \"#6E7C9E\"\nCNAME_COLOR = \"#5A6478\" if THEME == \"light\" else \"#9BA6BD\"  # constellation names\nSNAME_COLOR = \"#2A2A26\" if THEME == \"light\" else \"#D6DCE6\"  # bright star names\n\n# Data\nnp.random.seed(42)\n\n# Star catalog: (name, RA in hours, Dec in degrees, magnitude, constellation)\nstars_data = [\n    # Orion\n    (\"Betelgeuse\", 5.92, 7.41, 0.42, \"Ori\"),\n    (\"Rigel\", 5.24, -8.20, 0.13, \"Ori\"),\n    (\"Bellatrix\", 5.42, 6.35, 1.64, \"Ori\"),\n    (\"Mintaka\", 5.53, -0.30, 2.23, \"Ori\"),\n    (\"Alnilam\", 5.60, -1.20, 1.69, \"Ori\"),\n    (\"Alnitak\", 5.68, -1.94, 1.77, \"Ori\"),\n    (\"Saiph\", 5.80, -9.67, 2.09, \"Ori\"),\n    # Ursa Major\n    (\"Dubhe\", 11.06, 61.75, 1.79, \"UMa\"),\n    (\"Merak\", 11.03, 56.38, 2.37, \"UMa\"),\n    (\"Phecda\", 11.90, 53.69, 2.44, \"UMa\"),\n    (\"Megrez\", 12.26, 57.03, 3.31, \"UMa\"),\n    (\"Alioth\", 12.90, 55.96, 1.77, \"UMa\"),\n    (\"Mizar\", 13.40, 54.93, 2.27, \"UMa\"),\n    (\"Alkaid\", 13.79, 49.31, 1.86, \"UMa\"),\n    # Cassiopeia\n    (\"Schedar\", 0.68, 56.54, 2.23, \"Cas\"),\n    (\"Caph\", 0.15, 59.15, 2.27, \"Cas\"),\n    (\"Gamma Cas\", 0.95, 60.72, 2.47, \"Cas\"),\n    (\"Ruchbah\", 1.43, 60.24, 2.68, \"Cas\"),\n    (\"Segin\", 1.91, 63.67, 3.37, \"Cas\"),\n    # Leo\n    (\"Regulus\", 10.14, 11.97, 1.35, \"Leo\"),\n    (\"Denebola\", 11.82, 14.57, 2.13, \"Leo\"),\n    (\"Algieba\", 10.33, 19.84, 2.28, \"Leo\"),\n    (\"Zosma\", 11.24, 20.52, 2.56, \"Leo\"),\n    (\"Chertan\", 11.24, 15.43, 3.33, \"Leo\"),\n    # Cygnus\n    (\"Deneb\", 20.69, 45.28, 1.25, \"Cyg\"),\n    (\"Sadr\", 20.37, 40.26, 2.20, \"Cyg\"),\n    (\"Gienah Cyg\", 20.77, 33.97, 2.46, \"Cyg\"),\n    (\"Delta Cyg\", 19.75, 45.13, 2.87, \"Cyg\"),\n    (\"Albireo\", 19.51, 27.96, 3.08, \"Cyg\"),\n    # Scorpius\n    (\"Antares\", 16.49, -26.43, 0.96, \"Sco\"),\n    (\"Dschubba\", 16.01, -22.62, 2.32, \"Sco\"),\n    (\"Graffias\", 16.09, -19.81, 2.62, \"Sco\"),\n    (\"Pi Sco\", 15.98, -26.11, 2.89, \"Sco\"),\n    # Gemini\n    (\"Pollux\", 7.76, 28.03, 1.14, \"Gem\"),\n    (\"Castor\", 7.58, 31.89, 1.58, \"Gem\"),\n    (\"Alhena\", 6.63, 16.40, 1.93, \"Gem\"),\n    (\"Tejat\", 6.38, 22.51, 2.88, \"Gem\"),\n    (\"Mebsuta\", 6.73, 25.13, 2.98, \"Gem\"),\n    # Lyra\n    (\"Vega\", 18.62, 38.78, 0.03, \"Lyr\"),\n    (\"Sheliak\", 18.83, 33.36, 3.45, \"Lyr\"),\n    (\"Sulafat\", 18.98, 32.69, 3.24, \"Lyr\"),\n    # Aquila\n    (\"Altair\", 19.85, 8.87, 0.77, \"Aql\"),\n    (\"Tarazed\", 19.77, 10.61, 2.72, \"Aql\"),\n    (\"Alshain\", 19.92, 6.41, 3.71, \"Aql\"),\n    # Taurus\n    (\"Aldebaran\", 4.60, 16.51, 0.85, \"Tau\"),\n    (\"Elnath\", 5.44, 28.61, 1.65, \"Tau\"),\n    (\"Alcyone\", 3.79, 24.11, 2.87, \"Tau\"),\n    (\"Tianguan\", 5.63, 21.14, 3.00, \"Tau\"),\n    # Canis Minor / Sirius region kept north of the crop\n    (\"Sirius\", 6.75, -16.72, -1.46, \"CMa\"),\n    (\"Mirzam\", 6.38, -17.96, 1.98, \"CMa\"),\n    # Perseus\n    (\"Mirfak\", 3.41, 49.86, 1.80, \"Per\"),\n    (\"Algol\", 3.14, 40.96, 2.12, \"Per\"),\n    (\"Zeta Per\", 3.90, 31.88, 2.85, \"Per\"),\n    (\"Epsilon Per\", 3.96, 40.01, 2.89, \"Per\"),\n    # Auriga\n    (\"Capella\", 5.28, 46.00, 0.08, \"Aur\"),\n    (\"Menkalinan\", 5.99, 44.95, 1.90, \"Aur\"),\n    (\"Theta Aur\", 5.99, 37.21, 2.62, \"Aur\"),\n    # Bootes\n    (\"Arcturus\", 14.26, 19.18, -0.05, \"Boo\"),\n    (\"Izar\", 14.75, 27.07, 2.37, \"Boo\"),\n    (\"Muphrid\", 13.91, 18.40, 2.68, \"Boo\"),\n    # Corona Borealis\n    (\"Alphecca\", 15.58, 26.71, 2.23, \"CrB\"),\n    (\"Nusakan\", 15.46, 29.11, 3.68, \"CrB\"),\n    # Andromeda\n    (\"Alpheratz\", 0.14, 29.09, 2.06, \"And\"),\n    (\"Mirach\", 1.16, 35.62, 2.05, \"And\"),\n    (\"Almach\", 2.07, 42.33, 2.17, \"And\"),\n    # Pegasus\n    (\"Markab\", 23.08, 15.21, 2.49, \"Peg\"),\n    (\"Scheat\", 23.06, 28.08, 2.42, \"Peg\"),\n    (\"Algenib\", 0.22, 15.18, 2.84, \"Peg\"),\n    # Draco\n    (\"Eltanin\", 17.94, 51.49, 2.23, \"Dra\"),\n    (\"Rastaban\", 17.51, 52.30, 2.79, \"Dra\"),\n    (\"Thuban\", 14.07, 64.38, 3.65, \"Dra\"),\n    # Corona / Hercules anchor\n    (\"Rasalgethi\", 17.24, 14.39, 3.49, \"Her\"),\n    (\"Kornephoros\", 16.50, 21.49, 2.78, \"Her\"),\n]\n\n# Background stars for realism, drawn within the visible northern view\nn_bg = 220\nbg_ra = np.random.uniform(0, 24, n_bg)\nbg_dec = np.random.uniform(-25, 82, n_bg)\nbg_mag = np.random.uniform(3.6, 5.4, n_bg)\nfor i in range(n_bg):\n    stars_data.append((f\"BG{i}\", bg_ra[i], bg_dec[i], bg_mag[i], \"\"))\n\n# Parse star data\nstar_names = [s[0] for s in stars_data]\nra_hours = np.array([s[1] for s in stars_data])\ndec_deg = np.array([s[2] for s in stars_data])\nmagnitudes = np.array([s[3] for s in stars_data])\nconstellations = [s[4] for s in stars_data]\n\n# Stereographic projection (north celestial pole centered)\nra_rad = ra_hours * (2 * np.pi / 24)\ndec_rad = np.deg2rad(dec_deg)\nr = np.cos(dec_rad) / (1 + np.sin(dec_rad))\nproj_x = -r * np.cos(ra_rad)  # flip x so RA increases right-to-left (sky convention)\nproj_y = r * np.sin(ra_rad)\n\n# Invert magnitude to point size: brighter (lower mag) = bigger\nmag_min, mag_max = magnitudes.min(), magnitudes.max()\nsize_min, size_max = 4, 40\nsizes = size_min + (size_max - size_min) * (mag_max - magnitudes) / (mag_max - mag_min)\n\n# Star tone by magnitude (brightest -> brightest tone for the theme)\nstar_colors = []\nfor m in magnitudes:\n    frac = (m - mag_min) / (mag_max - mag_min)\n    if frac < 0.3:\n        star_colors.append(STAR_BRIGHT)\n    elif frac < 0.6:\n        star_colors.append(STAR_MID)\n    else:\n        star_colors.append(STAR_DIM)\n\n# Constellation stick-figure edges (pairs of star names)\nedges = [\n    (\"Betelgeuse\", \"Bellatrix\"),\n    (\"Bellatrix\", \"Mintaka\"),\n    (\"Mintaka\", \"Alnilam\"),\n    (\"Alnilam\", \"Alnitak\"),\n    (\"Betelgeuse\", \"Alnilam\"),\n    (\"Alnitak\", \"Saiph\"),\n    (\"Mintaka\", \"Rigel\"),\n    (\"Rigel\", \"Saiph\"),\n    (\"Dubhe\", \"Merak\"),\n    (\"Merak\", \"Phecda\"),\n    (\"Phecda\", \"Megrez\"),\n    (\"Megrez\", \"Dubhe\"),\n    (\"Megrez\", \"Alioth\"),\n    (\"Alioth\", \"Mizar\"),\n    (\"Mizar\", \"Alkaid\"),\n    (\"Caph\", \"Schedar\"),\n    (\"Schedar\", \"Gamma Cas\"),\n    (\"Gamma Cas\", \"Ruchbah\"),\n    (\"Ruchbah\", \"Segin\"),\n    (\"Regulus\", \"Chertan\"),\n    (\"Chertan\", \"Zosma\"),\n    (\"Zosma\", \"Denebola\"),\n    (\"Regulus\", \"Algieba\"),\n    (\"Algieba\", \"Zosma\"),\n    (\"Deneb\", \"Sadr\"),\n    (\"Sadr\", \"Albireo\"),\n    (\"Delta Cyg\", \"Sadr\"),\n    (\"Sadr\", \"Gienah Cyg\"),\n    (\"Graffias\", \"Dschubba\"),\n    (\"Dschubba\", \"Antares\"),\n    (\"Antares\", \"Pi Sco\"),\n    (\"Castor\", \"Pollux\"),\n    (\"Castor\", \"Mebsuta\"),\n    (\"Mebsuta\", \"Tejat\"),\n    (\"Pollux\", \"Alhena\"),\n    (\"Vega\", \"Sheliak\"),\n    (\"Sheliak\", \"Sulafat\"),\n    (\"Sulafat\", \"Vega\"),\n    (\"Altair\", \"Tarazed\"),\n    (\"Altair\", \"Alshain\"),\n    (\"Aldebaran\", \"Tianguan\"),\n    (\"Tianguan\", \"Elnath\"),\n    (\"Aldebaran\", \"Alcyone\"),\n    (\"Sirius\", \"Mirzam\"),\n    (\"Mirfak\", \"Algol\"),\n    (\"Mirfak\", \"Epsilon Per\"),\n    (\"Epsilon Per\", \"Zeta Per\"),\n    (\"Capella\", \"Menkalinan\"),\n    (\"Menkalinan\", \"Theta Aur\"),\n    (\"Arcturus\", \"Izar\"),\n    (\"Arcturus\", \"Muphrid\"),\n    (\"Alpheratz\", \"Mirach\"),\n    (\"Mirach\", \"Almach\"),\n    (\"Markab\", \"Algenib\"),\n    (\"Algenib\", \"Alpheratz\"),\n    (\"Alpheratz\", \"Scheat\"),\n    (\"Scheat\", \"Markab\"),\n    (\"Eltanin\", \"Rastaban\"),\n    (\"Rasalgethi\", \"Kornephoros\"),\n]\n\nname_to_idx = {name: i for i, name in enumerate(star_names)}\n\n# Plot — square canvas (sky projection has no preferred horizontal axis)\ntitle = \"star-chart-constellation · python · bokeh · anyplot.ai\"\np = figure(\n    width=2400,\n    height=2400,\n    title=title,\n    tools=\"pan,wheel_zoom,box_zoom,reset,hover\",\n    toolbar_location=None,  # bokeh's default toolbar shrinks the saved PNG below height=\n    match_aspect=True,\n    tooltips=[(\"Star\", \"@name\"), (\"Magnitude\", \"@mag\")],\n    min_border_left=40,\n    min_border_right=40,\n    min_border_top=100,\n    min_border_bottom=40,\n)\np.background_fill_color = PAGE_BG\np.border_fill_color = PAGE_BG\n\nview_range = 1.6\n\n# RA/Dec coordinate grid\n# Declination circles (celestial equator + northern parallels)\nfor dec_grid in range(0, 90, 30):\n    dec_r = np.deg2rad(dec_grid)\n    r_circle = np.cos(dec_r) / (1 + np.sin(dec_r))\n    theta_vals = np.linspace(0, 2 * np.pi, 200)\n    gx = -r_circle * np.cos(theta_vals)\n    gy = r_circle * np.sin(theta_vals)\n    p.line(gx, gy, line_color=GRID_COLOR, line_alpha=0.7, line_width=1.5, line_dash=\"dotted\")\n    # Skip the innermost (+60°) label — it collapses into the crowded pole region\n    if dec_grid <= 30:\n        dec_label = Label(\n            x=-r_circle,\n            y=0.0,\n            text=f\"+{dec_grid}°\",\n            text_font_size=\"18pt\",\n            text_color=GRID_LABEL,\n            x_offset=6,\n            y_offset=-6,\n        )\n        p.add_layout(dec_label)\n\n# RA meridians\nfor ra_grid in range(0, 24, 3):\n    ra_r = ra_grid * (2 * np.pi / 24)\n    dec_vals = np.linspace(-24, 89, 100)\n    r_vals = np.cos(np.deg2rad(dec_vals)) / (1 + np.sin(np.deg2rad(dec_vals)))\n    gx = -r_vals * np.cos(ra_r)\n    gy = r_vals * np.sin(ra_r)\n    p.line(gx, gy, line_color=GRID_COLOR, line_alpha=0.7, line_width=1.5, line_dash=\"dotted\")\n    # Label each meridian just inside the chart edge\n    edge_r = np.cos(np.deg2rad(-18)) / (1 + np.sin(np.deg2rad(-18)))\n    lx = -edge_r * np.cos(ra_r)\n    ly = edge_r * np.sin(ra_r)\n    if abs(lx) < view_range - 0.05 and abs(ly) < view_range - 0.05:\n        ra_label = Label(\n            x=lx, y=ly, text=f\"{ra_grid}h\", text_font_size=\"16pt\", text_color=GRID_LABEL, x_offset=5, y_offset=5\n        )\n        p.add_layout(ra_label)\n\n# Constellation stick-figure lines\nfor s1_name, s2_name in edges:\n    if s1_name in name_to_idx and s2_name in name_to_idx:\n        i1, i2 = name_to_idx[s1_name], name_to_idx[s2_name]\n        p.line(\n            [proj_x[i1], proj_x[i2]], [proj_y[i1], proj_y[i2]], line_color=LINE_COLOR, line_alpha=0.5, line_width=2.5\n        )\n\n# Stars\nsource = ColumnDataSource(\n    data={\n        \"x\": proj_x,\n        \"y\": proj_y,\n        \"size\": sizes,\n        \"color\": star_colors,\n        \"name\": star_names,\n        \"mag\": [f\"{m:.1f}\" for m in magnitudes],\n    }\n)\np.scatter(x=\"x\", y=\"y\", size=\"size\", color=\"color\", alpha=0.92, line_color=None, source=source)\n\n# Constellation names near each group centroid\nconstellation_full_names = {\n    \"Ori\": \"Orion\",\n    \"UMa\": \"Ursa Major\",\n    \"Cas\": \"Cassiopeia\",\n    \"Leo\": \"Leo\",\n    \"Cyg\": \"Cygnus\",\n    \"Sco\": \"Scorpius\",\n    \"Gem\": \"Gemini\",\n    \"Lyr\": \"Lyra\",\n    \"Aql\": \"Aquila\",\n    \"Tau\": \"Taurus\",\n    \"CMa\": \"Canis Major\",\n    \"Per\": \"Perseus\",\n    \"Aur\": \"Auriga\",\n    \"Boo\": \"Boötes\",\n    \"CrB\": \"Corona Bor.\",\n    \"And\": \"Andromeda\",\n    \"Peg\": \"Pegasus\",\n    \"Dra\": \"Draco\",\n    \"Her\": \"Hercules\",\n}\n# Per-constellation label offsets (px) to clear bright-star labels\nconstellation_offsets = {\n    \"Aur\": (-90, -40),  # clear Capella label\n    \"Lyr\": (60, -10),  # clear Vega label\n    \"Aql\": (-95, -8),  # clear Altair label\n    \"Boo\": (60, -10),  # clear Arcturus label\n    \"Ori\": (-100, -10),\n    \"Per\": (-60, 10),\n    \"CrB\": (10, 30),\n    \"Her\": (20, -30),\n}\n\nconstellation_set = sorted({c for c in constellations if c})\nlabel_x, label_y, label_text = [], [], []\nlabel_x_offset, label_y_offset = [], []\nfor c in constellation_set:\n    idxs = [i for i, cn in enumerate(constellations) if cn == c]\n    cx, cy = np.mean(proj_x[idxs]), np.mean(proj_y[idxs])\n    if abs(cx) > view_range or abs(cy) > view_range:\n        continue\n    label_x.append(cx)\n    label_y.append(cy)\n    label_text.append(constellation_full_names.get(c, c))\n    ox, oy = constellation_offsets.get(c, (0, -34))\n    label_x_offset.append(ox)\n    label_y_offset.append(oy)\n\nconstellation_source = ColumnDataSource(\n    data={\"x\": label_x, \"y\": label_y, \"text\": label_text, \"x_offset\": label_x_offset, \"y_offset\": label_y_offset}\n)\nconstellation_labels = LabelSet(\n    x=\"x\",\n    y=\"y\",\n    text=\"text\",\n    source=constellation_source,\n    x_offset=\"x_offset\",\n    y_offset=\"y_offset\",\n    text_font_size=\"20pt\",\n    text_color=CNAME_COLOR,\n    text_font_style=\"italic\",\n    text_align=\"center\",\n)\np.add_layout(constellation_labels)\n\n# Bright named stars (mag < 1.0) — placed above their star, with a few overrides\nbright_star_offsets = {\n    \"Capella\": (0, 36),\n    \"Vega\": (-18, 34),\n    \"Altair\": (16, 34),\n    \"Deneb\": (0, 36),\n    \"Arcturus\": (-18, 34),\n    \"Antares\": (0, -42),\n    \"Sirius\": (0, 38),\n}\nbx, by, btext = [], [], []\nbxo, byo = [], []\nfor i, (name, mag) in enumerate(zip(star_names, magnitudes, strict=False)):\n    if mag < 1.0 and not name.startswith(\"BG\"):\n        if abs(proj_x[i]) > view_range or abs(proj_y[i]) > view_range:\n            continue\n        bx.append(proj_x[i])\n        by.append(proj_y[i])\n        btext.append(name)\n        ox, oy = bright_star_offsets.get(name, (0, 34))\n        bxo.append(ox)\n        byo.append(oy)\n\nbright_source = ColumnDataSource(data={\"x\": bx, \"y\": by, \"text\": btext, \"x_offset\": bxo, \"y_offset\": byo})\nbright_labels = LabelSet(\n    x=\"x\",\n    y=\"y\",\n    text=\"text\",\n    source=bright_source,\n    x_offset=\"x_offset\",\n    y_offset=\"y_offset\",\n    text_font_size=\"17pt\",\n    text_color=SNAME_COLOR,\n    text_align=\"center\",\n)\np.add_layout(bright_labels)\n\n# Magnitude scale legend (bottom-left)\nlegend_mags = [0, 1, 2, 3, 4]\nlegend_x_base = -1.42\nlegend_y_base = -1.30\np.add_layout(\n    Label(\n        x=legend_x_base - 0.02,\n        y=legend_y_base + 0.12,\n        text=\"Magnitude\",\n        text_font_size=\"18pt\",\n        text_color=INK_SOFT,\n        text_font_style=\"bold\",\n    )\n)\nfor j, lm in enumerate(legend_mags):\n    lx = legend_x_base + j * 0.13\n    ls = size_min + (size_max - size_min) * (mag_max - lm) / (mag_max - mag_min)\n    lc = STAR_BRIGHT if lm < 1.5 else STAR_MID if lm < 3 else STAR_DIM\n    p.scatter([lx], [legend_y_base], size=ls, color=lc, alpha=0.92, line_color=None)\n    p.add_layout(\n        Label(\n            x=lx, y=legend_y_base - 0.10, text=str(lm), text_font_size=\"15pt\", text_color=INK_SOFT, text_align=\"center\"\n        )\n    )\n\n# Style\np.title.text_font_size = \"50pt\"\np.title.text_color = INK\np.title.align = \"center\"\np.xaxis.visible = False\np.yaxis.visible = False\np.xgrid.grid_line_color = None\np.ygrid.grid_line_color = None\np.outline_line_color = INK_SOFT\np.outline_line_alpha = 0.4\np.x_range = Range1d(-view_range, view_range)\np.y_range = Range1d(-view_range, view_range)\n\n# Save — interactive HTML + headless-Chrome screenshot (export_png is unavailable here)\noutput_file(f\"plot-{THEME}.html\", title=\"Star Chart with Constellations\")\nsave(p)\n\nW, H = 2400, 2400\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.set_window_size(W, H)\ndriver.get(f\"file://{Path(f'plot-{THEME}.html').resolve()}\")\ntime.sleep(3)\n# Compensate for browser chrome so the inner viewport is exactly W x H\ninner_w, inner_h = driver.execute_script(\"return [window.innerWidth, window.innerHeight];\")\ndriver.set_window_size(W + (W - inner_w), H + (H - inner_h))\ntime.sleep(1)\ndriver.save_screenshot(f\"plot-{THEME}.png\")\ndriver.quit()\n"}