{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ddd7bbc3-b7c1-4b3b-8ac0-24c37e8c6cc5",
   "metadata": {},
   "source": [
    "# Multiline Axis Labels\n",
    "\n",
    "Multiline axis labels allow better visualization of long categorical values. Instead of overcrowding the axis, labels can now be formatted across multiple lines, enhancing readability. \n",
    "\n",
    "* To create a multiline axis label, simply add \"\\n\" inside the string where you want the line break."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e83da232-c578-4c48-848e-53fb1199a51c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "            <div id=\"fDlMFF\"></div>\n",
       "            <script type=\"text/javascript\" data-lets-plot-script=\"library\">\n",
       "                if(!window.letsPlotCallQueue) {\n",
       "                    window.letsPlotCallQueue = [];\n",
       "                }; \n",
       "                window.letsPlotCall = function(f) {\n",
       "                    window.letsPlotCallQueue.push(f);\n",
       "                };\n",
       "                (function() {\n",
       "                    var script = document.createElement(\"script\");\n",
       "                    script.type = \"text/javascript\";\n",
       "                    script.src = \"https://cdn.jsdelivr.net/gh/JetBrains/lets-plot@v4.6.0rc1/js-package/distr/lets-plot.min.js\";\n",
       "                    script.onload = function() {\n",
       "                        window.letsPlotCall = function(f) {f();};\n",
       "                        window.letsPlotCallQueue.forEach(function(f) {f();});\n",
       "                        window.letsPlotCallQueue = [];\n",
       "                        \n",
       "                    };\n",
       "                    script.onerror = function(event) {\n",
       "                        window.letsPlotCall = function(f) {};    // noop\n",
       "                        window.letsPlotCallQueue = [];\n",
       "                        var div = document.createElement(\"div\");\n",
       "                        div.style.color = 'darkred';\n",
       "                        div.textContent = 'Error loading Lets-Plot JS';\n",
       "                        document.getElementById(\"fDlMFF\").appendChild(div);\n",
       "                    };\n",
       "                    var e = document.getElementById(\"fDlMFF\");\n",
       "                    e.appendChild(script);\n",
       "                })()\n",
       "            </script>\n",
       "            "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from lets_plot import *\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "LetsPlot.setup_html()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63f9d1ac-de82-4cda-85f1-3f3d8998eef0",
   "metadata": {},
   "source": [
    "## Quarters & Years"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8ea6aa2f-e6b9-42d1-acb0-8984bd93d2d6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Quarter_Year</th>\n",
       "      <th>Type</th>\n",
       "      <th>Amount</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Q1-2022</td>\n",
       "      <td>Income</td>\n",
       "      <td>11564</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Q1-2022</td>\n",
       "      <td>Expenses</td>\n",
       "      <td>9924</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Q2-2022</td>\n",
       "      <td>Income</td>\n",
       "      <td>11365</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Q2-2022</td>\n",
       "      <td>Expenses</td>\n",
       "      <td>10432</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  Quarter_Year      Type  Amount\n",
       "0      Q1-2022    Income   11564\n",
       "1      Q1-2022  Expenses    9924\n",
       "2      Q2-2022    Income   11365\n",
       "3      Q2-2022  Expenses   10432"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Create a DataFrame with artificial income and expenses\n",
    "np.random.seed(42)\n",
    "years = [2022, 2023, 2024]\n",
    "quarters = [\"Q1\", \"Q2\", \"Q3\", \"Q4\"]\n",
    "\n",
    "data = []\n",
    "for year in years:\n",
    "    base_income = np.random.randint(5000, 15000)  # Base income\n",
    "    base_expenses = base_income * np.random.uniform(0.6, 0.9)  # Expenses as 60-90% of income\n",
    "    \n",
    "    for quarter in quarters:\n",
    "        income = base_income + np.random.randint(-2000, 2000)  # Add variation\n",
    "        expenses = base_expenses + np.random.randint(-1500, 1500)\n",
    "        \n",
    "        quarter_year = f\"{quarter}-{year}\"\n",
    "        data.append({\"Quarter_Year\": quarter_year, \"Type\": \"Income\", \"Amount\": round(income)})\n",
    "        data.append({\"Quarter_Year\": quarter_year, \"Type\": \"Expenses\", \"Amount\": round(expenses)})\n",
    "\n",
    "df = pd.DataFrame(data)\n",
    "df.head(4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "18870e14-f8f7-4bac-a914-ca9c188b93a2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Multiline labels for X-axis\n",
    "x_labels_mapping =  [f\"{q}\\n{year}\" if q == \"Q1\" else q for year in years for q in quarters]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "9a735efd-24e3-450b-890d-f0eb076e17a5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"LTa8WW\"></div>\n",
       "   <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n",
       "   \n",
       "   (function() {\n",
       "   // ----------\n",
       "   \n",
       "   const forceImmediateRender = false;\n",
       "   const responsive = false;\n",
       "   \n",
       "   let sizing = {\n",
       "       width_mode: \"MIN\",\n",
       "       height_mode: \"SCALED\",\n",
       "       width: null, \n",
       "       height: null \n",
       "   };\n",
       "   \n",
       "   const preferredWidth = document.body.dataset.letsPlotPreferredWidth;\n",
       "   if (preferredWidth !== undefined) {\n",
       "       sizing = {\n",
       "           width_mode: 'FIXED',\n",
       "           height_mode: 'SCALED',\n",
       "           width: parseFloat(preferredWidth)\n",
       "       };\n",
       "   }\n",
       "   \n",
       "   const containerDiv = document.getElementById(\"LTa8WW\");\n",
       "   let fig = null;\n",
       "   \n",
       "   function renderPlot() {\n",
       "       if (fig === null) {\n",
       "           const plotSpec = {\n",
       "\"data\":{\n",
       "\"Quarter_Year\":[\"Q1-2022\",\"Q1-2022\",\"Q2-2022\",\"Q2-2022\",\"Q3-2022\",\"Q3-2022\",\"Q4-2022\",\"Q4-2022\",\"Q1-2023\",\"Q1-2023\",\"Q2-2023\",\"Q2-2023\",\"Q3-2023\",\"Q3-2023\",\"Q4-2023\",\"Q4-2023\",\"Q1-2024\",\"Q1-2024\",\"Q2-2024\",\"Q2-2024\",\"Q3-2024\",\"Q3-2024\",\"Q4-2024\",\"Q4-2024\"],\n",
       "\"Type\":[\"Income\",\"Expenses\",\"Income\",\"Expenses\",\"Income\",\"Expenses\",\"Income\",\"Expenses\",\"Income\",\"Expenses\",\"Income\",\"Expenses\",\"Income\",\"Expenses\",\"Income\",\"Expenses\",\"Income\",\"Expenses\",\"Income\",\"Expenses\",\"Income\",\"Expenses\",\"Income\",\"Expenses\"],\n",
       "\"Amount\":[11564.0,9924.0,11365.0,10432.0,12439.0,9260.0,11508.0,9124.0,11749.0,10515.0,12313.0,7726.0,10263.0,8365.0,10969.0,9111.0,10904.0,7996.0,11133.0,6131.0,13334.0,5693.0,12249.0,6419.0]\n",
       "},\n",
       "\"mapping\":{\n",
       "\"x\":\"Quarter_Year\",\n",
       "\"y\":\"Amount\",\n",
       "\"color\":\"Type\"\n",
       "},\n",
       "\"data_meta\":{\n",
       "\"series_annotations\":[{\n",
       "\"type\":\"str\",\n",
       "\"column\":\"Quarter_Year\"\n",
       "},{\n",
       "\"type\":\"str\",\n",
       "\"column\":\"Type\"\n",
       "},{\n",
       "\"type\":\"int\",\n",
       "\"column\":\"Amount\"\n",
       "}]\n",
       "},\n",
       "\"ggtitle\":{\n",
       "\"text\":\"Quarterly Income vs Expenses\"\n",
       "},\n",
       "\"guides\":{\n",
       "\"x\":{\n",
       "\"title\":\"Quarters\"\n",
       "},\n",
       "\"y\":{\n",
       "\"title\":\"Amount ($)\"\n",
       "}\n",
       "},\n",
       "\"theme\":{\n",
       "\"axis_text_x\":{\n",
       "\"angle\":30.0,\n",
       "\"blank\":false\n",
       "}\n",
       "},\n",
       "\"kind\":\"plot\",\n",
       "\"scales\":[{\n",
       "\"aesthetic\":\"x\",\n",
       "\"labels\":[\"Q1\\n2022\",\"Q2\",\"Q3\",\"Q4\",\"Q1\\n2023\",\"Q2\",\"Q3\",\"Q4\",\"Q1\\n2024\",\"Q2\",\"Q3\",\"Q4\"],\n",
       "\"discrete\":true,\n",
       "\"reverse\":false\n",
       "}],\n",
       "\"layers\":[{\n",
       "\"geom\":\"line\",\n",
       "\"mapping\":{\n",
       "},\n",
       "\"data_meta\":{\n",
       "},\n",
       "\"size\":1.5,\n",
       "\"data\":{\n",
       "}\n",
       "},{\n",
       "\"geom\":\"point\",\n",
       "\"mapping\":{\n",
       "},\n",
       "\"data_meta\":{\n",
       "},\n",
       "\"size\":4.0,\n",
       "\"data\":{\n",
       "}\n",
       "}],\n",
       "\"metainfo_list\":[],\n",
       "\"spec_id\":\"1\"\n",
       "};\n",
       "           window.letsPlotCall(function() { fig = LetsPlot.buildPlotFromProcessedSpecs(plotSpec, containerDiv, sizing); });\n",
       "       } else {\n",
       "           fig.updateView({});\n",
       "       }\n",
       "   }\n",
       "   \n",
       "   const renderImmediately = \n",
       "       forceImmediateRender || (\n",
       "           sizing.width_mode === 'FIXED' && \n",
       "           (sizing.height_mode === 'FIXED' || sizing.height_mode === 'SCALED')\n",
       "       );\n",
       "   \n",
       "   if (renderImmediately) {\n",
       "       renderPlot();\n",
       "   }\n",
       "   \n",
       "   if (!renderImmediately || responsive) {\n",
       "       // Set up observer for initial sizing or continuous monitoring\n",
       "       var observer = new ResizeObserver(function(entries) {\n",
       "           for (let entry of entries) {\n",
       "               if (entry.contentBoxSize && \n",
       "                   entry.contentBoxSize[0].inlineSize > 0) {\n",
       "                   if (!responsive && observer) {\n",
       "                       observer.disconnect();\n",
       "                       observer = null;\n",
       "                   }\n",
       "                   renderPlot();\n",
       "                   if (!responsive) {\n",
       "                       break;\n",
       "                   }\n",
       "               }\n",
       "           }\n",
       "       });\n",
       "       \n",
       "       observer.observe(containerDiv);\n",
       "   }\n",
       "   \n",
       "   // ----------\n",
       "   })();\n",
       "   \n",
       "   </script>"
      ],
      "text/plain": [
       "<lets_plot.plot.core.PlotSpec at 0x1668b8d00>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ggplot(df, aes(x=\"Quarter_Year\", y=\"Amount\", color=\"Type\")) + \\\n",
    "    geom_line(size=1.5) + \\\n",
    "    geom_point(size=4) + \\\n",
    "    scale_x_discrete(labels=x_labels_mapping) + \\\n",
    "    labs(title=\"Quarterly Income vs Expenses\",\n",
    "         x=\"Quarters\",\n",
    "         y=\"Amount ($)\") + \\\n",
    "    theme(axis_text_x=element_text(angle=30))"
   ]
  }
 ],
 "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.21"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}