{"spec_id":"chessboard-pieces","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nchessboard-pieces: Chess Board with Pieces for Position Diagrams\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 92/100 | Updated: 2026-05-17\n\"\"\"\n\nimport os\nimport shutil\n\nimport pandas as pd\nfrom lets_plot import (\n    LetsPlot,\n    aes,\n    coord_fixed,\n    element_blank,\n    element_rect,\n    element_text,\n    geom_text,\n    geom_tile,\n    ggplot,\n    ggsave,\n    ggsize,\n    labs,\n    scale_fill_manual,\n    scale_x_continuous,\n    scale_y_continuous,\n    theme,\n    theme_void,\n)\n\n\nLetsPlot.setup_html()\n\n# Theme tokens\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# Unicode chess symbols\nPIECE_SYMBOLS = {\n    \"K\": \"♔\",\n    \"Q\": \"♕\",\n    \"R\": \"♖\",\n    \"B\": \"♗\",\n    \"N\": \"♘\",\n    \"P\": \"♙\",\n    \"k\": \"♚\",\n    \"q\": \"♛\",\n    \"r\": \"♜\",\n    \"b\": \"♝\",\n    \"n\": \"♞\",\n    \"p\": \"♟\",\n}\n\n# Scholar's Mate position - a famous 4-move checkmate\npieces = {\n    \"a1\": \"R\",\n    \"b1\": \"N\",\n    \"c1\": \"B\",\n    \"d1\": \"Q\",\n    \"e1\": \"K\",\n    \"f1\": \"B\",\n    \"g1\": \"N\",\n    \"h1\": \"R\",\n    \"a2\": \"P\",\n    \"b2\": \"P\",\n    \"c2\": \"P\",\n    \"d2\": \"P\",\n    \"f2\": \"P\",\n    \"g2\": \"P\",\n    \"h2\": \"P\",\n    \"e4\": \"P\",\n    \"c4\": \"B\",\n    \"f7\": \"Q\",\n    \"a7\": \"p\",\n    \"b7\": \"p\",\n    \"c7\": \"p\",\n    \"d7\": \"p\",\n    \"g7\": \"p\",\n    \"h7\": \"p\",\n    \"a8\": \"r\",\n    \"b8\": \"n\",\n    \"c8\": \"b\",\n    \"d8\": \"q\",\n    \"e8\": \"k\",\n    \"f8\": \"b\",\n    \"g8\": \"n\",\n    \"h8\": \"r\",\n    \"e5\": \"p\",\n    \"f6\": \"n\",\n}\n\n# Create board squares data\nfiles = \"abcdefgh\"\nsquares_data = []\nfor i in range(8):\n    for j in range(8):\n        is_light = (i + j) % 2 == 1\n        squares_data.append({\"file\": i + 0.5, \"rank\": j + 0.5, \"color\": \"light\" if is_light else \"dark\"})\ndf_squares = pd.DataFrame(squares_data)\n\n# Create pieces data\npieces_data = []\nfor square, piece in pieces.items():\n    file_idx = files.index(square[0]) + 0.5\n    rank_val = int(square[1]) - 0.5\n    symbol = PIECE_SYMBOLS.get(piece, \"\")\n    pieces_data.append({\"file\": file_idx, \"rank\": rank_val, \"symbol\": symbol})\ndf_pieces = pd.DataFrame(pieces_data)\n\n# Board colors (chess standard, theme-independent for clarity)\nlight_color = \"#F0D9B5\"\ndark_color = \"#B58863\"\n\n# Build the plot\nplot = (\n    ggplot()\n    + geom_tile(aes(x=\"file\", y=\"rank\", fill=\"color\"), data=df_squares, width=1, height=1, color=\"#8B7355\", size=0.5)\n    + scale_fill_manual(values={\"light\": light_color, \"dark\": dark_color}, guide=\"none\")\n    + geom_text(aes(x=\"file\", y=\"rank\", label=\"symbol\"), data=df_pieces, size=28)\n    + scale_x_continuous(\n        breaks=[0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5], labels=[\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"]\n    )\n    + scale_y_continuous(\n        breaks=[0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5], labels=[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"]\n    )\n    + coord_fixed(ratio=1)\n    + labs(title=\"chessboard-pieces · letsplot · anyplot.ai\")\n    + theme_void()\n    + theme(\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        plot_title=element_text(size=24, hjust=0.5, face=\"bold\", color=INK),\n        axis_text=element_text(size=18, face=\"bold\", color=INK_SOFT),\n        axis_line=element_blank(),\n        plot_margin=40,\n    )\n    + ggsize(1200, 1200)\n)\n\n# Save outputs - ggsave uses lets-plot-images subfolder by default\nggsave(plot, f\"plot-{THEME}.png\", scale=3)\nggsave(plot, f\"plot-{THEME}.html\")\n\n# Move files from lets-plot-images to current directory\nif os.path.exists(f\"lets-plot-images/plot-{THEME}.png\"):\n    shutil.move(f\"lets-plot-images/plot-{THEME}.png\", f\"plot-{THEME}.png\")\nif os.path.exists(f\"lets-plot-images/plot-{THEME}.html\"):\n    shutil.move(f\"lets-plot-images/plot-{THEME}.html\", f\"plot-{THEME}.html\")\nif os.path.exists(\"lets-plot-images\"):\n    shutil.rmtree(\"lets-plot-images\")\n"}