{"spec_id":"scatter-annotated","library":"bokeh","language":"python","code":"\"\"\" anyplot.ai\nscatter-annotated: Annotated Scatter Plot with Text Labels\nLibrary: bokeh 3.9.0 | Python 3.13.13\nQuality: 88/100 | Updated: 2026-05-13\n\"\"\"\n\nimport sys\n\n\nsys.path = [p for p in sys.path if not p.endswith(\"implementations/python\")]\n\nimport os\nimport time\nfrom pathlib import Path\n\nimport bokeh.io\nimport bokeh.models\nimport bokeh.plotting\nimport numpy as np\nfrom selenium import webdriver\nfrom selenium.webdriver.chrome.options import Options\n\n\n# Create aliases to avoid name shadowing with bokeh.py module name\noutput_file = bokeh.io.output_file\nsave = bokeh.io.save\nColumnDataSource = bokeh.models.ColumnDataSource\nLabelSet = bokeh.models.LabelSet\nfigure = bokeh.plotting.figure\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\"\nBRAND = \"#009E73\"\n\n# Data - Company market performance example\nnp.random.seed(42)\ncompanies = [\n    \"TechCorp\",\n    \"DataSys\",\n    \"CloudNet\",\n    \"AIVenture\",\n    \"NetFlow\",\n    \"CodeBase\",\n    \"ByteWorks\",\n    \"DigiCore\",\n    \"InfoTech\",\n    \"WebScale\",\n    \"AppLogic\",\n    \"SoftPeak\",\n    \"CyberLink\",\n    \"DevOps\",\n    \"QuantumBit\",\n]\n\n# Revenue (billions) and Market Cap (billions)\nrevenue = np.array([12.5, 8.3, 22.1, 5.7, 15.8, 9.2, 18.4, 6.9, 11.3, 25.6, 7.4, 14.2, 19.8, 4.5, 10.1])\nmarket_cap = np.array([45.2, 28.1, 85.3, 32.5, 52.8, 35.6, 68.9, 25.4, 41.7, 98.2, 22.3, 55.4, 72.1, 18.9, 38.5])\n\n# Create ColumnDataSource with label offsets\nsource = ColumnDataSource(\n    data={\n        \"x\": revenue,\n        \"y\": market_cap,\n        \"labels\": companies,\n        \"x_offset\": np.full(len(companies), 0.8),\n        \"y_offset\": np.full(len(companies), 2.0),\n    }\n)\n\n# Create figure\np = figure(\n    width=4800,\n    height=2700,\n    title=\"scatter-annotated · bokeh · anyplot.ai\",\n    x_axis_label=\"Revenue (Billions $)\",\n    y_axis_label=\"Market Cap (Billions $)\",\n    tools=\"pan,wheel_zoom,box_zoom,reset\",\n)\n\n# Plot scatter points\np.scatter(x=\"x\", y=\"y\", source=source, size=40, color=BRAND, alpha=0.7, line_color=PAGE_BG, line_width=2)\n\n# Add connecting line segments from points to labels\nsegments_source = ColumnDataSource(data={\"x0\": revenue, \"y0\": market_cap, \"x1\": revenue + 0.8, \"y1\": market_cap + 2.0})\np.segment(x0=\"x0\", y0=\"y0\", x1=\"x1\", y1=\"y1\", source=segments_source, line_color=INK_SOFT, line_width=1, line_alpha=0.4)\n\n# Add text labels\nlabels = LabelSet(\n    x=\"x\",\n    y=\"y\",\n    text=\"labels\",\n    source=source,\n    x_offset=30,\n    y_offset=45,\n    text_font_size=\"24pt\",\n    text_color=INK,\n    text_font_style=\"normal\",\n)\np.add_layout(labels)\n\n# Style title\np.title.text_font_size = \"28pt\"\np.title.text_color = INK\n\n# Style axes labels\np.xaxis.axis_label_text_font_size = \"22pt\"\np.yaxis.axis_label_text_font_size = \"22pt\"\np.xaxis.axis_label_text_color = INK\np.yaxis.axis_label_text_color = INK\n\n# Style tick labels\np.xaxis.major_label_text_font_size = \"18pt\"\np.yaxis.major_label_text_font_size = \"18pt\"\np.xaxis.major_label_text_color = INK_SOFT\np.yaxis.major_label_text_color = INK_SOFT\n\n# Style grid\np.xgrid.grid_line_color = INK\np.ygrid.grid_line_color = INK\np.xgrid.grid_line_alpha = 0.10\np.ygrid.grid_line_alpha = 0.10\n\n# Background\np.background_fill_color = PAGE_BG\np.border_fill_color = PAGE_BG\np.outline_line_color = INK_SOFT\n\n# Axis styling\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\n# Save HTML\noutput_file(f\"plot-{THEME}.html\")\nsave(p)\n\n# Screenshot with headless Chrome\nW, H = 4800, 2700\nopts = Options()\nopts.binary_location = \"/usr/bin/chromium\"\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)\ndriver.save_screenshot(f\"plot-{THEME}.png\")\ndriver.quit()\n"}