{ "cells": [ { "cell_type": "markdown", "id": "021b0473-978d-4f33-9fbc-15ddb7d02046", "metadata": {}, "source": [ "## Legend Wrap\n", "\n", "When the legend contains many items, it automatically wraps to prevent overlap - \n", "up to 15 rows for vertical legends and 5 columns for horizontal ones." ] }, { "cell_type": "code", "execution_count": 1, "id": "688c06d9-401f-4bfc-a5c9-8e8b2fda7caa", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import random\n", "import colorsys\n", "import pandas as pd\n", "from lets_plot import *\n", "\n", "LetsPlot.setup_html()" ] }, { "cell_type": "code", "execution_count": 2, "id": "67c03745-047e-4a2a-b3e6-fbcaf5156150", "metadata": {}, "outputs": [], "source": [ "# Prepare a dataset\n", "\n", "def distinct_palette(n, s=0.72, l=0.53):\n", " # Evenly spaced hues in HSL -> hex\n", " vals = []\n", " for i in range(n):\n", " h = i / n\n", " r, g, b = colorsys.hls_to_rgb(h, l, s)\n", " vals.append('#{:02X}{:02X}{:02X}'.format(int(r*255), int(g*255), int(b*255)))\n", " return vals\n", "\n", "random.seed(0)\n", "n_cats = 36\n", "pts_per_cat = 13\n", "cats = [f\"C{i:02d}\" for i in range(1, n_cats + 1)]\n", "\n", "rows = []\n", "for i, c in enumerate(cats):\n", " for _ in range(pts_per_cat):\n", " x = i % 6 + random.uniform(-0.4, 0.4)\n", " y = i // 6 + random.uniform(-0.4, 0.4)\n", " rows.append({\"x\": x, \"y\": y, \"cat\": c})\n", "\n", "df = pd.DataFrame(rows)\n", "\n", "palette = distinct_palette(n_cats)" ] }, { "cell_type": "code", "execution_count": 3, "id": "8acb5638-8484-4058-a31f-248b0ba005ca", "metadata": {}, "outputs": [], "source": [ "base = (\n", " ggplot(df, aes(\"x\", \"y\", color=\"cat\")) +\n", " geom_point(size=3, alpha=0.9) +\n", " scale_color_discrete(name=f\"Categories ({n_cats})\") +\n", " scale_color_manual(values=palette, name=f\"Categories ({n_cats})\") +\n", " ggsize(800, 460)\n", ")\n" ] }, { "cell_type": "code", "execution_count": 4, "id": "064b9fb2-7383-4bc8-a1fd-26f7ceec5d88", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The default legend layout (vertical)\n", "base" ] }, { "cell_type": "code", "execution_count": 5, "id": "512dc5bc-d4e9-492a-b489-757160fa3e41", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The horizontal case\n", "base + theme(legend_position=\"bottom\")" ] }, { "cell_type": "code", "execution_count": 6, "id": "54f0fba8-8297-4bfb-ac8a-6a73e75e0972", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# You can still adjust the number of legend rows or columns manually.\n", "\n", "base + theme(legend_position=\"bottom\") + guides(color=guide_legend(ncol=10, byrow=True))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.23" } }, "nbformat": 4, "nbformat_minor": 5 }