{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Formatting labels on plots.\n",
    "\n",
    "In Lets-Plot you can apply a formatting to:\n",
    "\n",
    "- axis break values.\n",
    "- labels displayed by `geomText()`.\n",
    "- tooltip text.\n",
    "- facet labels.\n",
    "\n",
    "Using format string you can format values of numeric and date-time types.\n",
    "\n",
    "In addition, you can use a *string template*.\n",
    "\n",
    "In *string template* the value's format string is surrounded by curly braces: `\"... {.2f} ...\"`.\n",
    "\n",
    "An empty placeholder `{}` is also allowed. In this case a default string representation will be shown. This is also applicable to categorical values.\n",
    "\n",
    "To learn more about formatting templates see: [Formatting](https://lets-plot.org/kotlin/formats.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"sfQbN8\"></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.0.0/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",
       "           };\n",
       "           script.onerror = function(event) {\n",
       "               window.letsPlotCall = function(f) {};\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(\"sfQbN8\").appendChild(div);\n",
       "           };\n",
       "           var e = document.getElementById(\"sfQbN8\");\n",
       "           e.appendChild(script);\n",
       "       })();\n",
       "   </script>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "            <div id=\"kotlin_out_0\"/>\n",
       "            <script type=\"text/javascript\">\n",
       "                            if(!window.kotlinQueues) {\n",
       "                window.kotlinQueues = {};\n",
       "            }\n",
       "            if(!window.kotlinQueues[\"DataFrame\"]) {\n",
       "                var resQueue = [];\n",
       "                window.kotlinQueues[\"DataFrame\"] = resQueue;\n",
       "                window[\"call_DataFrame\"] = function(f) {\n",
       "                    resQueue.push(f);\n",
       "                }\n",
       "            }\n",
       "            (function (){\n",
       "                var modifiers = [(function(script) {\n",
       "    script.src = \"https://cdn.jsdelivr.net/gh/Kotlin/dataframe@3db46ccccaa1291c0627307d64133317f545e6ae/core/src/main/resources/init.js\"\n",
       "    script.type = \"text/javascript\";\n",
       "})];\n",
       "                var e = document.getElementById(\"kotlin_out_0\");\n",
       "                modifiers.forEach(function (gen) {\n",
       "                    var script = document.createElement(\"script\");\n",
       "                    gen(script)\n",
       "                    script.addEventListener(\"load\", function() {\n",
       "                        window[\"call_DataFrame\"] = function(f) {f();};\n",
       "                        window.kotlinQueues[\"DataFrame\"].forEach(function(f) {f();});\n",
       "                        window.kotlinQueues[\"DataFrame\"] = [];\n",
       "                    }, false);\n",
       "                    script.addEventListener(\"error\", function() {\n",
       "                        window[\"call_DataFrame\"] = function(f) {};\n",
       "                        window.kotlinQueues[\"DataFrame\"] = [];\n",
       "                        var div = document.createElement(\"div\");\n",
       "                        div.style.color = 'darkred';\n",
       "                        div.textContent = 'Error loading resource DataFrame';\n",
       "                        document.getElementById(\"kotlin_out_0\").appendChild(div);\n",
       "                    }, false);\n",
       "                    \n",
       "                    e.appendChild(script);\n",
       "                });\n",
       "            })();\n",
       "            </script>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "                <style>\n",
       "                :root {\n",
       "    --background: #fff;\n",
       "    --background-odd: #f5f5f5;\n",
       "    --background-hover: #d9edfd;\n",
       "    --header-text-color: #474747;\n",
       "    --text-color: #848484;\n",
       "    --text-color-dark: #000;\n",
       "    --text-color-medium: #737373;\n",
       "    --text-color-pale: #b3b3b3;\n",
       "    --inner-border-color: #aaa;\n",
       "    --bold-border-color: #000;\n",
       "    --link-color: #296eaa;\n",
       "    --link-color-pale: #296eaa;\n",
       "    --link-hover: #1a466c;\n",
       "}\n",
       "\n",
       ":root[theme=\"dark\"], :root [data-jp-theme-light=\"false\"], .dataframe_dark{\n",
       "    --background: #303030;\n",
       "    --background-odd: #3c3c3c;\n",
       "    --background-hover: #464646;\n",
       "    --header-text-color: #dddddd;\n",
       "    --text-color: #b3b3b3;\n",
       "    --text-color-dark: #dddddd;\n",
       "    --text-color-medium: #b2b2b2;\n",
       "    --text-color-pale: #737373;\n",
       "    --inner-border-color: #707070;\n",
       "    --bold-border-color: #777777;\n",
       "    --link-color: #008dc0;\n",
       "    --link-color-pale: #97e1fb;\n",
       "    --link-hover: #00688e;\n",
       "}\n",
       "\n",
       "p.dataframe_description {\n",
       "    color: var(--text-color-dark);\n",
       "}\n",
       "\n",
       "table.dataframe {\n",
       "    font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n",
       "    font-size: 12px;\n",
       "    background-color: var(--background);\n",
       "    color: var(--text-color-dark);\n",
       "    border: none;\n",
       "    border-collapse: collapse;\n",
       "}\n",
       "\n",
       "table.dataframe th, td {\n",
       "    padding: 6px;\n",
       "    border: 1px solid transparent;\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       "table.dataframe th {\n",
       "    background-color: var(--background);\n",
       "    color: var(--header-text-color);\n",
       "}\n",
       "\n",
       "table.dataframe td {\n",
       "    vertical-align: top;\n",
       "}\n",
       "\n",
       "table.dataframe th.bottomBorder {\n",
       "    border-bottom-color: var(--bold-border-color);\n",
       "}\n",
       "\n",
       "table.dataframe tbody > tr:nth-child(odd) {\n",
       "    background: var(--background-odd);\n",
       "}\n",
       "\n",
       "table.dataframe tbody > tr:nth-child(even) {\n",
       "    background: var(--background);\n",
       "}\n",
       "\n",
       "table.dataframe tbody > tr:hover {\n",
       "    background: var(--background-hover);\n",
       "}\n",
       "\n",
       "table.dataframe a {\n",
       "    cursor: pointer;\n",
       "    color: var(--link-color);\n",
       "    text-decoration: none;\n",
       "}\n",
       "\n",
       "table.dataframe tr:hover > td a {\n",
       "    color: var(--link-color-pale);\n",
       "}\n",
       "\n",
       "table.dataframe a:hover {\n",
       "    color: var(--link-hover);\n",
       "    text-decoration: underline;\n",
       "}\n",
       "\n",
       "table.dataframe img {\n",
       "    max-width: fit-content;\n",
       "}\n",
       "\n",
       "table.dataframe th.complex {\n",
       "    background-color: var(--background);\n",
       "    border: 1px solid var(--background);\n",
       "}\n",
       "\n",
       "table.dataframe .leftBorder {\n",
       "    border-left-color: var(--inner-border-color);\n",
       "}\n",
       "\n",
       "table.dataframe .rightBorder {\n",
       "    border-right-color: var(--inner-border-color);\n",
       "}\n",
       "\n",
       "table.dataframe .rightAlign {\n",
       "    text-align: right;\n",
       "}\n",
       "\n",
       "table.dataframe .expanderSvg {\n",
       "    width: 8px;\n",
       "    height: 8px;\n",
       "    margin-right: 3px;\n",
       "}\n",
       "\n",
       "table.dataframe .expander {\n",
       "    display: flex;\n",
       "    align-items: center;\n",
       "}\n",
       "\n",
       "/* formatting */\n",
       "\n",
       "table.dataframe .null {\n",
       "    color: var(--text-color-pale);\n",
       "}\n",
       "\n",
       "table.dataframe .structural {\n",
       "    color: var(--text-color-medium);\n",
       "    font-weight: bold;\n",
       "}\n",
       "\n",
       "table.dataframe .dataFrameCaption {\n",
       "    font-weight: bold;\n",
       "}\n",
       "\n",
       "table.dataframe .numbers {\n",
       "    color: var(--text-color-dark);\n",
       "}\n",
       "\n",
       "table.dataframe td:hover .formatted .structural, .null {\n",
       "    color: var(--text-color-dark);\n",
       "}\n",
       "\n",
       "table.dataframe tr:hover .formatted .structural, .null {\n",
       "    color: var(--text-color-dark);\n",
       "}\n",
       "\n",
       "\n",
       "                </style>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%useLatestDescriptors\n",
    "%use lets-plot\n",
    "%use dataframe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Lets-Plot Kotlin API v.4.4.2. Frontend: Notebook with dynamically loaded JS. Lets-Plot JS v.4.0.0."
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "LetsPlot.getInfo()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The US Unemployment Rates 2000-2016"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "var economics = DataFrame.readCSV(\"https://vincentarelbundock.github.io/Rdatasets/csv/ggplot2/economics.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/kotlindataframe+json": "{\"nrow\":5,\"ncol\":7,\"columns\":[\"untitled\",\"date\",\"pce\",\"pop\",\"psavert\",\"uempmed\",\"unemploy\"],\"kotlin_dataframe\":[{\"untitled\":1,\"date\":\"1967-07-01\",\"pce\":506.7,\"pop\":198712.0,\"psavert\":12.6,\"uempmed\":4.5,\"unemploy\":2944},{\"untitled\":2,\"date\":\"1967-08-01\",\"pce\":509.8,\"pop\":198911.0,\"psavert\":12.6,\"uempmed\":4.7,\"unemploy\":2945},{\"untitled\":3,\"date\":\"1967-09-01\",\"pce\":515.6,\"pop\":199113.0,\"psavert\":11.9,\"uempmed\":4.6,\"unemploy\":2958},{\"untitled\":4,\"date\":\"1967-10-01\",\"pce\":512.2,\"pop\":199311.0,\"psavert\":12.9,\"uempmed\":4.9,\"unemploy\":3143},{\"untitled\":5,\"date\":\"1967-11-01\",\"pce\":517.4,\"pop\":199498.0,\"psavert\":12.8,\"uempmed\":4.7,\"unemploy\":3066}]}",
      "text/html": [
       "        <html>\n",
       "        <head>\n",
       "            <style type=\"text/css\">\n",
       "                :root {\n",
       "    --background: #fff;\n",
       "    --background-odd: #f5f5f5;\n",
       "    --background-hover: #d9edfd;\n",
       "    --header-text-color: #474747;\n",
       "    --text-color: #848484;\n",
       "    --text-color-dark: #000;\n",
       "    --text-color-medium: #737373;\n",
       "    --text-color-pale: #b3b3b3;\n",
       "    --inner-border-color: #aaa;\n",
       "    --bold-border-color: #000;\n",
       "    --link-color: #296eaa;\n",
       "    --link-color-pale: #296eaa;\n",
       "    --link-hover: #1a466c;\n",
       "}\n",
       "\n",
       ":root[theme=\"dark\"], :root [data-jp-theme-light=\"false\"], .dataframe_dark{\n",
       "    --background: #303030;\n",
       "    --background-odd: #3c3c3c;\n",
       "    --background-hover: #464646;\n",
       "    --header-text-color: #dddddd;\n",
       "    --text-color: #b3b3b3;\n",
       "    --text-color-dark: #dddddd;\n",
       "    --text-color-medium: #b2b2b2;\n",
       "    --text-color-pale: #737373;\n",
       "    --inner-border-color: #707070;\n",
       "    --bold-border-color: #777777;\n",
       "    --link-color: #008dc0;\n",
       "    --link-color-pale: #97e1fb;\n",
       "    --link-hover: #00688e;\n",
       "}\n",
       "\n",
       "p.dataframe_description {\n",
       "    color: var(--text-color-dark);\n",
       "}\n",
       "\n",
       "table.dataframe {\n",
       "    font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n",
       "    font-size: 12px;\n",
       "    background-color: var(--background);\n",
       "    color: var(--text-color-dark);\n",
       "    border: none;\n",
       "    border-collapse: collapse;\n",
       "}\n",
       "\n",
       "table.dataframe th, td {\n",
       "    padding: 6px;\n",
       "    border: 1px solid transparent;\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       "table.dataframe th {\n",
       "    background-color: var(--background);\n",
       "    color: var(--header-text-color);\n",
       "}\n",
       "\n",
       "table.dataframe td {\n",
       "    vertical-align: top;\n",
       "}\n",
       "\n",
       "table.dataframe th.bottomBorder {\n",
       "    border-bottom-color: var(--bold-border-color);\n",
       "}\n",
       "\n",
       "table.dataframe tbody > tr:nth-child(odd) {\n",
       "    background: var(--background-odd);\n",
       "}\n",
       "\n",
       "table.dataframe tbody > tr:nth-child(even) {\n",
       "    background: var(--background);\n",
       "}\n",
       "\n",
       "table.dataframe tbody > tr:hover {\n",
       "    background: var(--background-hover);\n",
       "}\n",
       "\n",
       "table.dataframe a {\n",
       "    cursor: pointer;\n",
       "    color: var(--link-color);\n",
       "    text-decoration: none;\n",
       "}\n",
       "\n",
       "table.dataframe tr:hover > td a {\n",
       "    color: var(--link-color-pale);\n",
       "}\n",
       "\n",
       "table.dataframe a:hover {\n",
       "    color: var(--link-hover);\n",
       "    text-decoration: underline;\n",
       "}\n",
       "\n",
       "table.dataframe img {\n",
       "    max-width: fit-content;\n",
       "}\n",
       "\n",
       "table.dataframe th.complex {\n",
       "    background-color: var(--background);\n",
       "    border: 1px solid var(--background);\n",
       "}\n",
       "\n",
       "table.dataframe .leftBorder {\n",
       "    border-left-color: var(--inner-border-color);\n",
       "}\n",
       "\n",
       "table.dataframe .rightBorder {\n",
       "    border-right-color: var(--inner-border-color);\n",
       "}\n",
       "\n",
       "table.dataframe .rightAlign {\n",
       "    text-align: right;\n",
       "}\n",
       "\n",
       "table.dataframe .expanderSvg {\n",
       "    width: 8px;\n",
       "    height: 8px;\n",
       "    margin-right: 3px;\n",
       "}\n",
       "\n",
       "table.dataframe .expander {\n",
       "    display: flex;\n",
       "    align-items: center;\n",
       "}\n",
       "\n",
       "/* formatting */\n",
       "\n",
       "table.dataframe .null {\n",
       "    color: var(--text-color-pale);\n",
       "}\n",
       "\n",
       "table.dataframe .structural {\n",
       "    color: var(--text-color-medium);\n",
       "    font-weight: bold;\n",
       "}\n",
       "\n",
       "table.dataframe .dataFrameCaption {\n",
       "    font-weight: bold;\n",
       "}\n",
       "\n",
       "table.dataframe .numbers {\n",
       "    color: var(--text-color-dark);\n",
       "}\n",
       "\n",
       "table.dataframe td:hover .formatted .structural, .null {\n",
       "    color: var(--text-color-dark);\n",
       "}\n",
       "\n",
       "table.dataframe tr:hover .formatted .structural, .null {\n",
       "    color: var(--text-color-dark);\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "            </style>\n",
       "        </head>\n",
       "        <body>\n",
       "            \n",
       "<table class=\"dataframe\" id=\"df_-419430400\"></table>\n",
       "\n",
       "<p class=\"dataframe_description\">DataFrame: rowsCount = 5, columnsCount = 7</p>\n",
       "        </body>\n",
       "        <script>\n",
       "            \n",
       "/*<!--*/\n",
       "call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: \"<span title=\\\"untitled: Int\\\">untitled</span>\", children: [], rightAlign: true, values: [\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">1</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">2</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">3</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">4</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">5</span></span>\"] }, \n",
       "{ name: \"<span title=\\\"date: kotlinx.datetime.LocalDate\\\">date</span>\", children: [], rightAlign: false, values: [\"1967-07-01\",\"1967-08-01\",\"1967-09-01\",\"1967-10-01\",\"1967-11-01\"] }, \n",
       "{ name: \"<span title=\\\"pce: Double\\\">pce</span>\", children: [], rightAlign: true, values: [\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">506.7</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">509.8</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">515.6</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">512.2</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">517.4</span></span>\"] }, \n",
       "{ name: \"<span title=\\\"pop: Double\\\">pop</span>\", children: [], rightAlign: true, values: [\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">198712.0</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">198911.0</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">199113.0</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">199311.0</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">199498.0</span></span>\"] }, \n",
       "{ name: \"<span title=\\\"psavert: Double\\\">psavert</span>\", children: [], rightAlign: true, values: [\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">12.6</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">12.6</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">11.9</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">12.9</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">12.8</span></span>\"] }, \n",
       "{ name: \"<span title=\\\"uempmed: Double\\\">uempmed</span>\", children: [], rightAlign: true, values: [\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">4.5</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">4.7</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">4.6</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">4.9</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">4.7</span></span>\"] }, \n",
       "{ name: \"<span title=\\\"unemploy: Int\\\">unemploy</span>\", children: [], rightAlign: true, values: [\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">2944</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">2945</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">2958</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">3143</span></span>\",\"<span class=\\\"formatted\\\" title=\\\"\\\"><span class=\\\"numbers\\\">3066</span></span>\"] }, \n",
       "], id: -419430400, rootId: -419430400, totalRows: 5 } ) });\n",
       "/*-->*/\n",
       "\n",
       "call_DataFrame(function() { DataFrame.renderTable(-419430400) });\n",
       "\n",
       "\n",
       "        </script>\n",
       "        </html>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "economics.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import kotlinx.datetime.*\n",
    "\n",
    "fun LocalDate.toEpochMilliseconds(): Long {\n",
    "    return atStartOfDayIn((TimeZone.currentSystemDefault())).toEpochMilliseconds()\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "val startDate = LocalDate.parse(\"2000-01-01\")\n",
    "economics = economics.filter { date.compareTo(startDate) >= 0 }.convert {date}.with {it.toEpochMilliseconds()}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "val p = letsPlot(economics.toMap()){x=\"date\"; y=\"uempmed\"} + \n",
    "    geomLine() +\n",
    "    ylab(\"unemployment rate\") +\n",
    "    ggsize(900, 400)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Default plot (no formatting)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Apply formatting to X and Y axis labels.\n",
    "\n",
    "Use the `format` parameter in `scaleXxx()`.\n",
    "\n",
    "Note that the text in tooltips is now also formatted."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"u3N5bi\"></div>\n",
       "   <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n",
       "       (function() {\n",
       "           var plotSpec={\n",
       "\"mapping\":{\n",
       "\"x\":\"date\",\n",
       "\"y\":\"uempmed\"\n",
       "},\n",
       "\"data\":{\n",
       "\"date\":[9.467028E11,9.493812E11,9.518868E11,9.545652E11,9.571536E11,9.59832E11,9.62424E11,9.651024E11,9.677808E11,9.703728E11,9.730548E11,9.756468E11,9.783252E11,9.810036E11,9.834228E11,9.861012E11,9.886896E11,9.91368E11,9.9396E11,9.966384E11,9.993168E11,1.0019088E12,1.0045908E12,1.0071828E12,1.0098612E12,1.0125396E12,1.0149588E12,1.0176372E12,1.0202256E12,1.022904E12,1.025496E12,1.0281744E12,1.0308528E12,1.0334448E12,1.0361268E12,1.0387188E12,1.0413972E12,1.0440756E12,1.0464948E12,1.0491732E12,1.0517616E12,1.05444E12,1.057032E12,1.0597104E12,1.0623888E12,1.0649808E12,1.0676628E12,1.0702548E12,1.0729332E12,1.0756116E12,1.0781172E12,1.0807956E12,1.083384E12,1.0860624E12,1.0886544E12,1.0913328E12,1.0940112E12,1.0966032E12,1.0992852E12,1.1018772E12,1.1045556E12,1.107234E12,1.1096532E12,1.1123316E12,1.11492E12,1.1175984E12,1.1201904E12,1.1228688E12,1.1255472E12,1.1281392E12,1.1308212E12,1.1334132E12,1.1360916E12,1.13877E12,1.1411892E12,1.1438676E12,1.146456E12,1.1491344E12,1.1517264E12,1.1544048E12,1.1570832E12,1.1596752E12,1.1623572E12,1.1649492E12,1.1676276E12,1.170306E12,1.1727252E12,1.1754E12,1.177992E12,1.1806704E12,1.1832624E12,1.1859408E12,1.1886192E12,1.1912112E12,1.1938896E12,1.1964852E12,1.1991636E12,1.201842E12,1.2043476E12,1.2070224E12,1.2096144E12,1.2122928E12,1.2148848E12,1.2175632E12,1.2202416E12,1.2228336E12,1.225512E12,1.2281076E12,1.230786E12,1.2334644E12,1.2358836E12,1.2385584E12,1.2411504E12,1.2438288E12,1.2464208E12,1.2490992E12,1.2517776E12,1.2543696E12,1.257048E12,1.2596436E12,1.262322E12,1.2650004E12,1.2674196E12,1.2700944E12,1.2726864E12,1.2753648E12,1.2779568E12,1.2806352E12,1.2833136E12,1.2859056E12,1.288584E12,1.2911796E12,1.293858E12,1.2965364E12,1.2989556E12,1.3016304E12,1.3042224E12,1.3069008E12,1.3094928E12,1.3121712E12,1.3148496E12,1.3174416E12,1.32012E12,1.3227156E12,1.325394E12,1.3280724E12,1.330578E12,1.3332528E12,1.3358448E12,1.3385232E12,1.3411152E12,1.3437936E12,1.346472E12,1.349064E12,1.3517424E12,1.354338E12,1.3570164E12,1.3596948E12,1.362114E12,1.3647888E12,1.3673808E12,1.3700592E12,1.3726512E12,1.3753296E12,1.378008E12,1.3806E12,1.3832784E12,1.385874E12,1.3885524E12,1.3912308E12,1.39365E12,1.3963248E12,1.3989168E12,1.4015952E12,1.4041872E12,1.4068656E12,1.409544E12,1.412136E12,1.4148144E12,1.41741E12,1.4200884E12,1.4227668E12,1.425186E12,1.4278608E12],\n",
       "\"uempmed\":[5.8,6.1,6.0,6.1,5.8,5.7,6.0,6.3,5.2,6.1,6.1,6.0,5.8,6.1,6.6,5.9,6.3,6.0,6.8,6.9,7.2,7.3,7.7,8.2,8.4,8.3,8.4,8.9,9.5,11.0,8.9,9.0,9.5,9.6,9.3,9.6,9.6,9.5,9.7,10.2,9.9,11.5,10.3,10.1,10.2,10.4,10.3,10.4,10.6,10.2,10.2,9.5,9.9,11.0,8.9,9.2,9.6,9.5,9.7,9.5,9.4,9.2,9.3,9.0,9.1,9.0,8.8,9.2,8.4,8.6,8.5,8.7,8.6,9.1,8.7,8.4,8.5,7.3,8.0,8.4,8.0,7.9,8.3,7.5,8.3,8.5,9.1,8.6,8.2,7.7,8.7,8.8,8.7,8.4,8.6,8.4,9.0,8.7,8.7,9.4,7.9,9.0,9.7,9.7,10.2,10.4,9.8,10.5,10.7,11.7,12.3,13.1,14.2,17.2,16.0,16.3,17.8,18.9,19.8,20.1,20.0,19.9,20.4,22.1,22.3,25.2,22.3,21.0,20.3,21.2,21.0,21.9,21.5,21.1,21.5,20.9,21.6,22.4,22.0,22.4,22.0,20.6,20.8,20.5,20.8,19.7,19.2,19.1,19.9,20.4,17.5,18.4,18.8,19.9,18.6,17.7,15.8,17.2,17.6,17.1,17.1,17.0,16.2,16.5,16.5,16.3,17.1,17.3,15.4,15.9,15.8,15.7,14.6,13.8,13.1,12.9,13.4,13.6,13.0,12.9,13.2,12.9,12.0,11.5]\n",
       "},\n",
       "\"ggsize\":{\n",
       "\"width\":900.0,\n",
       "\"height\":400.0\n",
       "},\n",
       "\"kind\":\"plot\",\n",
       "\"scales\":[{\n",
       "\"aesthetic\":\"y\",\n",
       "\"name\":\"unemployment rate\"\n",
       "},{\n",
       "\"aesthetic\":\"x\",\n",
       "\"datetime\":true,\n",
       "\"format\":\"%b %Y\"\n",
       "},{\n",
       "\"aesthetic\":\"y\",\n",
       "\"format\":\"{} %\"\n",
       "}],\n",
       "\"layers\":[{\n",
       "\"mapping\":{\n",
       "},\n",
       "\"stat\":\"identity\",\n",
       "\"position\":\"identity\",\n",
       "\"geom\":\"line\",\n",
       "\"data\":{\n",
       "}\n",
       "}]\n",
       "};\n",
       "           var plotContainer = document.getElementById(\"u3N5bi\");\n",
       "           window.letsPlotCall(function() {{\n",
       "               LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
       "           }});\n",
       "       })();    \n",
       "   </script>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p + scaleXDateTime(format=\"%b %Y\") + scaleYContinuous(format=\"{} %\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Format axis labels for breaks specified manually\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"VXBK5W\"></div>\n",
       "   <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n",
       "       (function() {\n",
       "           var plotSpec={\n",
       "\"mapping\":{\n",
       "\"x\":\"date\",\n",
       "\"y\":\"uempmed\"\n",
       "},\n",
       "\"data\":{\n",
       "\"date\":[9.467028E11,9.493812E11,9.518868E11,9.545652E11,9.571536E11,9.59832E11,9.62424E11,9.651024E11,9.677808E11,9.703728E11,9.730548E11,9.756468E11,9.783252E11,9.810036E11,9.834228E11,9.861012E11,9.886896E11,9.91368E11,9.9396E11,9.966384E11,9.993168E11,1.0019088E12,1.0045908E12,1.0071828E12,1.0098612E12,1.0125396E12,1.0149588E12,1.0176372E12,1.0202256E12,1.022904E12,1.025496E12,1.0281744E12,1.0308528E12,1.0334448E12,1.0361268E12,1.0387188E12,1.0413972E12,1.0440756E12,1.0464948E12,1.0491732E12,1.0517616E12,1.05444E12,1.057032E12,1.0597104E12,1.0623888E12,1.0649808E12,1.0676628E12,1.0702548E12,1.0729332E12,1.0756116E12,1.0781172E12,1.0807956E12,1.083384E12,1.0860624E12,1.0886544E12,1.0913328E12,1.0940112E12,1.0966032E12,1.0992852E12,1.1018772E12,1.1045556E12,1.107234E12,1.1096532E12,1.1123316E12,1.11492E12,1.1175984E12,1.1201904E12,1.1228688E12,1.1255472E12,1.1281392E12,1.1308212E12,1.1334132E12,1.1360916E12,1.13877E12,1.1411892E12,1.1438676E12,1.146456E12,1.1491344E12,1.1517264E12,1.1544048E12,1.1570832E12,1.1596752E12,1.1623572E12,1.1649492E12,1.1676276E12,1.170306E12,1.1727252E12,1.1754E12,1.177992E12,1.1806704E12,1.1832624E12,1.1859408E12,1.1886192E12,1.1912112E12,1.1938896E12,1.1964852E12,1.1991636E12,1.201842E12,1.2043476E12,1.2070224E12,1.2096144E12,1.2122928E12,1.2148848E12,1.2175632E12,1.2202416E12,1.2228336E12,1.225512E12,1.2281076E12,1.230786E12,1.2334644E12,1.2358836E12,1.2385584E12,1.2411504E12,1.2438288E12,1.2464208E12,1.2490992E12,1.2517776E12,1.2543696E12,1.257048E12,1.2596436E12,1.262322E12,1.2650004E12,1.2674196E12,1.2700944E12,1.2726864E12,1.2753648E12,1.2779568E12,1.2806352E12,1.2833136E12,1.2859056E12,1.288584E12,1.2911796E12,1.293858E12,1.2965364E12,1.2989556E12,1.3016304E12,1.3042224E12,1.3069008E12,1.3094928E12,1.3121712E12,1.3148496E12,1.3174416E12,1.32012E12,1.3227156E12,1.325394E12,1.3280724E12,1.330578E12,1.3332528E12,1.3358448E12,1.3385232E12,1.3411152E12,1.3437936E12,1.346472E12,1.349064E12,1.3517424E12,1.354338E12,1.3570164E12,1.3596948E12,1.362114E12,1.3647888E12,1.3673808E12,1.3700592E12,1.3726512E12,1.3753296E12,1.378008E12,1.3806E12,1.3832784E12,1.385874E12,1.3885524E12,1.3912308E12,1.39365E12,1.3963248E12,1.3989168E12,1.4015952E12,1.4041872E12,1.4068656E12,1.409544E12,1.412136E12,1.4148144E12,1.41741E12,1.4200884E12,1.4227668E12,1.425186E12,1.4278608E12],\n",
       "\"uempmed\":[5.8,6.1,6.0,6.1,5.8,5.7,6.0,6.3,5.2,6.1,6.1,6.0,5.8,6.1,6.6,5.9,6.3,6.0,6.8,6.9,7.2,7.3,7.7,8.2,8.4,8.3,8.4,8.9,9.5,11.0,8.9,9.0,9.5,9.6,9.3,9.6,9.6,9.5,9.7,10.2,9.9,11.5,10.3,10.1,10.2,10.4,10.3,10.4,10.6,10.2,10.2,9.5,9.9,11.0,8.9,9.2,9.6,9.5,9.7,9.5,9.4,9.2,9.3,9.0,9.1,9.0,8.8,9.2,8.4,8.6,8.5,8.7,8.6,9.1,8.7,8.4,8.5,7.3,8.0,8.4,8.0,7.9,8.3,7.5,8.3,8.5,9.1,8.6,8.2,7.7,8.7,8.8,8.7,8.4,8.6,8.4,9.0,8.7,8.7,9.4,7.9,9.0,9.7,9.7,10.2,10.4,9.8,10.5,10.7,11.7,12.3,13.1,14.2,17.2,16.0,16.3,17.8,18.9,19.8,20.1,20.0,19.9,20.4,22.1,22.3,25.2,22.3,21.0,20.3,21.2,21.0,21.9,21.5,21.1,21.5,20.9,21.6,22.4,22.0,22.4,22.0,20.6,20.8,20.5,20.8,19.7,19.2,19.1,19.9,20.4,17.5,18.4,18.8,19.9,18.6,17.7,15.8,17.2,17.6,17.1,17.1,17.0,16.2,16.5,16.5,16.3,17.1,17.3,15.4,15.9,15.8,15.7,14.6,13.8,13.1,12.9,13.4,13.6,13.0,12.9,13.2,12.9,12.0,11.5]\n",
       "},\n",
       "\"ggsize\":{\n",
       "\"width\":900.0,\n",
       "\"height\":400.0\n",
       "},\n",
       "\"kind\":\"plot\",\n",
       "\"scales\":[{\n",
       "\"aesthetic\":\"y\",\n",
       "\"name\":\"unemployment rate\"\n",
       "},{\n",
       "\"aesthetic\":\"x\",\n",
       "\"datetime\":true,\n",
       "\"breaks\":[9.783252E11,1.4516244E12],\n",
       "\"format\":\"%b %Y\"\n",
       "},{\n",
       "\"aesthetic\":\"y\",\n",
       "\"format\":\"{} %\"\n",
       "}],\n",
       "\"layers\":[{\n",
       "\"mapping\":{\n",
       "},\n",
       "\"stat\":\"identity\",\n",
       "\"position\":\"identity\",\n",
       "\"geom\":\"line\",\n",
       "\"data\":{\n",
       "}\n",
       "}]\n",
       "};\n",
       "           var plotContainer = document.getElementById(\"VXBK5W\");\n",
       "           window.letsPlotCall(function() {{\n",
       "               LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
       "           }});\n",
       "       })();    \n",
       "   </script>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val breaks = listOf(\n",
    "    LocalDate.parse(\"2001-01-01\"), \n",
    "    LocalDate.parse(\"2016-01-01\")\n",
    ").map {it.toEpochMilliseconds()}\n",
    "\n",
    "p + scaleXDateTime(format=\"%b %Y\", breaks=breaks) + scaleYContinuous(format=\"{} %\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Configure tooltip's text and location."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"TIYNJg\"></div>\n",
       "   <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n",
       "       (function() {\n",
       "           var plotSpec={\n",
       "\"mapping\":{\n",
       "\"x\":\"date\",\n",
       "\"y\":\"uempmed\"\n",
       "},\n",
       "\"data\":{\n",
       "\"date\":[9.467028E11,9.493812E11,9.518868E11,9.545652E11,9.571536E11,9.59832E11,9.62424E11,9.651024E11,9.677808E11,9.703728E11,9.730548E11,9.756468E11,9.783252E11,9.810036E11,9.834228E11,9.861012E11,9.886896E11,9.91368E11,9.9396E11,9.966384E11,9.993168E11,1.0019088E12,1.0045908E12,1.0071828E12,1.0098612E12,1.0125396E12,1.0149588E12,1.0176372E12,1.0202256E12,1.022904E12,1.025496E12,1.0281744E12,1.0308528E12,1.0334448E12,1.0361268E12,1.0387188E12,1.0413972E12,1.0440756E12,1.0464948E12,1.0491732E12,1.0517616E12,1.05444E12,1.057032E12,1.0597104E12,1.0623888E12,1.0649808E12,1.0676628E12,1.0702548E12,1.0729332E12,1.0756116E12,1.0781172E12,1.0807956E12,1.083384E12,1.0860624E12,1.0886544E12,1.0913328E12,1.0940112E12,1.0966032E12,1.0992852E12,1.1018772E12,1.1045556E12,1.107234E12,1.1096532E12,1.1123316E12,1.11492E12,1.1175984E12,1.1201904E12,1.1228688E12,1.1255472E12,1.1281392E12,1.1308212E12,1.1334132E12,1.1360916E12,1.13877E12,1.1411892E12,1.1438676E12,1.146456E12,1.1491344E12,1.1517264E12,1.1544048E12,1.1570832E12,1.1596752E12,1.1623572E12,1.1649492E12,1.1676276E12,1.170306E12,1.1727252E12,1.1754E12,1.177992E12,1.1806704E12,1.1832624E12,1.1859408E12,1.1886192E12,1.1912112E12,1.1938896E12,1.1964852E12,1.1991636E12,1.201842E12,1.2043476E12,1.2070224E12,1.2096144E12,1.2122928E12,1.2148848E12,1.2175632E12,1.2202416E12,1.2228336E12,1.225512E12,1.2281076E12,1.230786E12,1.2334644E12,1.2358836E12,1.2385584E12,1.2411504E12,1.2438288E12,1.2464208E12,1.2490992E12,1.2517776E12,1.2543696E12,1.257048E12,1.2596436E12,1.262322E12,1.2650004E12,1.2674196E12,1.2700944E12,1.2726864E12,1.2753648E12,1.2779568E12,1.2806352E12,1.2833136E12,1.2859056E12,1.288584E12,1.2911796E12,1.293858E12,1.2965364E12,1.2989556E12,1.3016304E12,1.3042224E12,1.3069008E12,1.3094928E12,1.3121712E12,1.3148496E12,1.3174416E12,1.32012E12,1.3227156E12,1.325394E12,1.3280724E12,1.330578E12,1.3332528E12,1.3358448E12,1.3385232E12,1.3411152E12,1.3437936E12,1.346472E12,1.349064E12,1.3517424E12,1.354338E12,1.3570164E12,1.3596948E12,1.362114E12,1.3647888E12,1.3673808E12,1.3700592E12,1.3726512E12,1.3753296E12,1.378008E12,1.3806E12,1.3832784E12,1.385874E12,1.3885524E12,1.3912308E12,1.39365E12,1.3963248E12,1.3989168E12,1.4015952E12,1.4041872E12,1.4068656E12,1.409544E12,1.412136E12,1.4148144E12,1.41741E12,1.4200884E12,1.4227668E12,1.425186E12,1.4278608E12],\n",
       "\"uempmed\":[5.8,6.1,6.0,6.1,5.8,5.7,6.0,6.3,5.2,6.1,6.1,6.0,5.8,6.1,6.6,5.9,6.3,6.0,6.8,6.9,7.2,7.3,7.7,8.2,8.4,8.3,8.4,8.9,9.5,11.0,8.9,9.0,9.5,9.6,9.3,9.6,9.6,9.5,9.7,10.2,9.9,11.5,10.3,10.1,10.2,10.4,10.3,10.4,10.6,10.2,10.2,9.5,9.9,11.0,8.9,9.2,9.6,9.5,9.7,9.5,9.4,9.2,9.3,9.0,9.1,9.0,8.8,9.2,8.4,8.6,8.5,8.7,8.6,9.1,8.7,8.4,8.5,7.3,8.0,8.4,8.0,7.9,8.3,7.5,8.3,8.5,9.1,8.6,8.2,7.7,8.7,8.8,8.7,8.4,8.6,8.4,9.0,8.7,8.7,9.4,7.9,9.0,9.7,9.7,10.2,10.4,9.8,10.5,10.7,11.7,12.3,13.1,14.2,17.2,16.0,16.3,17.8,18.9,19.8,20.1,20.0,19.9,20.4,22.1,22.3,25.2,22.3,21.0,20.3,21.2,21.0,21.9,21.5,21.1,21.5,20.9,21.6,22.4,22.0,22.4,22.0,20.6,20.8,20.5,20.8,19.7,19.2,19.1,19.9,20.4,17.5,18.4,18.8,19.9,18.6,17.7,15.8,17.2,17.6,17.1,17.1,17.0,16.2,16.5,16.5,16.3,17.1,17.3,15.4,15.9,15.8,15.7,14.6,13.8,13.1,12.9,13.4,13.6,13.0,12.9,13.2,12.9,12.0,11.5]\n",
       "},\n",
       "\"ggsize\":{\n",
       "\"width\":900.0,\n",
       "\"height\":400.0\n",
       "},\n",
       "\"kind\":\"plot\",\n",
       "\"scales\":[{\n",
       "\"aesthetic\":\"x\",\n",
       "\"datetime\":true,\n",
       "\"format\":\"%b %Y\"\n",
       "},{\n",
       "\"aesthetic\":\"y\",\n",
       "\"format\":\"{} %\"\n",
       "},{\n",
       "\"aesthetic\":\"y\",\n",
       "\"name\":\"unemployment rate\"\n",
       "}],\n",
       "\"layers\":[{\n",
       "\"mapping\":{\n",
       "},\n",
       "\"stat\":\"identity\",\n",
       "\"position\":\"identity\",\n",
       "\"geom\":\"line\",\n",
       "\"tooltips\":{\n",
       "\"lines\":[\"Unemployment rate:|^y\"],\n",
       "\"tooltip_min_width\":170,\n",
       "\"tooltip_anchor\":\"top_center\"\n",
       "},\n",
       "\"data\":{\n",
       "}\n",
       "}]\n",
       "};\n",
       "           var plotContainer = document.getElementById(\"TIYNJg\");\n",
       "           window.letsPlotCall(function() {{\n",
       "               LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
       "           }});\n",
       "       })();    \n",
       "   </script>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "letsPlot(economics.toMap()){x=\"date\"; y=\"uempmed\"} + \n",
    " geomLine(tooltips=layerTooltips()\n",
    "        .line(\"Unemployment rate:|^y\")\n",
    "        .anchor(\"top_center\")\n",
    "        .minWidth(170)) + \n",
    " scaleXDateTime(format=\"%b %Y\") +\n",
    " scaleYContinuous(format=\"{} %\") +\n",
    " ylab(\"unemployment rate\") +\n",
    " ggsize(900, 400)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Format value shown in tooltip."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"QhIVR6\"></div>\n",
       "   <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n",
       "       (function() {\n",
       "           var plotSpec={\n",
       "\"mapping\":{\n",
       "\"x\":\"date\",\n",
       "\"y\":\"uempmed\"\n",
       "},\n",
       "\"data\":{\n",
       "\"date\":[9.467028E11,9.493812E11,9.518868E11,9.545652E11,9.571536E11,9.59832E11,9.62424E11,9.651024E11,9.677808E11,9.703728E11,9.730548E11,9.756468E11,9.783252E11,9.810036E11,9.834228E11,9.861012E11,9.886896E11,9.91368E11,9.9396E11,9.966384E11,9.993168E11,1.0019088E12,1.0045908E12,1.0071828E12,1.0098612E12,1.0125396E12,1.0149588E12,1.0176372E12,1.0202256E12,1.022904E12,1.025496E12,1.0281744E12,1.0308528E12,1.0334448E12,1.0361268E12,1.0387188E12,1.0413972E12,1.0440756E12,1.0464948E12,1.0491732E12,1.0517616E12,1.05444E12,1.057032E12,1.0597104E12,1.0623888E12,1.0649808E12,1.0676628E12,1.0702548E12,1.0729332E12,1.0756116E12,1.0781172E12,1.0807956E12,1.083384E12,1.0860624E12,1.0886544E12,1.0913328E12,1.0940112E12,1.0966032E12,1.0992852E12,1.1018772E12,1.1045556E12,1.107234E12,1.1096532E12,1.1123316E12,1.11492E12,1.1175984E12,1.1201904E12,1.1228688E12,1.1255472E12,1.1281392E12,1.1308212E12,1.1334132E12,1.1360916E12,1.13877E12,1.1411892E12,1.1438676E12,1.146456E12,1.1491344E12,1.1517264E12,1.1544048E12,1.1570832E12,1.1596752E12,1.1623572E12,1.1649492E12,1.1676276E12,1.170306E12,1.1727252E12,1.1754E12,1.177992E12,1.1806704E12,1.1832624E12,1.1859408E12,1.1886192E12,1.1912112E12,1.1938896E12,1.1964852E12,1.1991636E12,1.201842E12,1.2043476E12,1.2070224E12,1.2096144E12,1.2122928E12,1.2148848E12,1.2175632E12,1.2202416E12,1.2228336E12,1.225512E12,1.2281076E12,1.230786E12,1.2334644E12,1.2358836E12,1.2385584E12,1.2411504E12,1.2438288E12,1.2464208E12,1.2490992E12,1.2517776E12,1.2543696E12,1.257048E12,1.2596436E12,1.262322E12,1.2650004E12,1.2674196E12,1.2700944E12,1.2726864E12,1.2753648E12,1.2779568E12,1.2806352E12,1.2833136E12,1.2859056E12,1.288584E12,1.2911796E12,1.293858E12,1.2965364E12,1.2989556E12,1.3016304E12,1.3042224E12,1.3069008E12,1.3094928E12,1.3121712E12,1.3148496E12,1.3174416E12,1.32012E12,1.3227156E12,1.325394E12,1.3280724E12,1.330578E12,1.3332528E12,1.3358448E12,1.3385232E12,1.3411152E12,1.3437936E12,1.346472E12,1.349064E12,1.3517424E12,1.354338E12,1.3570164E12,1.3596948E12,1.362114E12,1.3647888E12,1.3673808E12,1.3700592E12,1.3726512E12,1.3753296E12,1.378008E12,1.3806E12,1.3832784E12,1.385874E12,1.3885524E12,1.3912308E12,1.39365E12,1.3963248E12,1.3989168E12,1.4015952E12,1.4041872E12,1.4068656E12,1.409544E12,1.412136E12,1.4148144E12,1.41741E12,1.4200884E12,1.4227668E12,1.425186E12,1.4278608E12],\n",
       "\"uempmed\":[5.8,6.1,6.0,6.1,5.8,5.7,6.0,6.3,5.2,6.1,6.1,6.0,5.8,6.1,6.6,5.9,6.3,6.0,6.8,6.9,7.2,7.3,7.7,8.2,8.4,8.3,8.4,8.9,9.5,11.0,8.9,9.0,9.5,9.6,9.3,9.6,9.6,9.5,9.7,10.2,9.9,11.5,10.3,10.1,10.2,10.4,10.3,10.4,10.6,10.2,10.2,9.5,9.9,11.0,8.9,9.2,9.6,9.5,9.7,9.5,9.4,9.2,9.3,9.0,9.1,9.0,8.8,9.2,8.4,8.6,8.5,8.7,8.6,9.1,8.7,8.4,8.5,7.3,8.0,8.4,8.0,7.9,8.3,7.5,8.3,8.5,9.1,8.6,8.2,7.7,8.7,8.8,8.7,8.4,8.6,8.4,9.0,8.7,8.7,9.4,7.9,9.0,9.7,9.7,10.2,10.4,9.8,10.5,10.7,11.7,12.3,13.1,14.2,17.2,16.0,16.3,17.8,18.9,19.8,20.1,20.0,19.9,20.4,22.1,22.3,25.2,22.3,21.0,20.3,21.2,21.0,21.9,21.5,21.1,21.5,20.9,21.6,22.4,22.0,22.4,22.0,20.6,20.8,20.5,20.8,19.7,19.2,19.1,19.9,20.4,17.5,18.4,18.8,19.9,18.6,17.7,15.8,17.2,17.6,17.1,17.1,17.0,16.2,16.5,16.5,16.3,17.1,17.3,15.4,15.9,15.8,15.7,14.6,13.8,13.1,12.9,13.4,13.6,13.0,12.9,13.2,12.9,12.0,11.5]\n",
       "},\n",
       "\"ggsize\":{\n",
       "\"width\":900.0,\n",
       "\"height\":400.0\n",
       "},\n",
       "\"kind\":\"plot\",\n",
       "\"scales\":[{\n",
       "\"aesthetic\":\"x\",\n",
       "\"datetime\":true\n",
       "},{\n",
       "\"aesthetic\":\"y\"\n",
       "},{\n",
       "\"aesthetic\":\"y\",\n",
       "\"name\":\"unemployment rate\"\n",
       "}],\n",
       "\"layers\":[{\n",
       "\"mapping\":{\n",
       "},\n",
       "\"stat\":\"identity\",\n",
       "\"position\":\"identity\",\n",
       "\"geom\":\"line\",\n",
       "\"tooltips\":{\n",
       "\"tooltip_min_width\":170,\n",
       "\"tooltip_anchor\":\"top_left\",\n",
       "\"formats\":[{\n",
       "\"field\":\"date\",\n",
       "\"format\":\"%B %Y\"\n",
       "}],\n",
       "\"lines\":[\"@uempmed % in @date\"]\n",
       "},\n",
       "\"data\":{\n",
       "}\n",
       "}]\n",
       "};\n",
       "           var plotContainer = document.getElementById(\"QhIVR6\");\n",
       "           window.letsPlotCall(function() {{\n",
       "               LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
       "           }});\n",
       "       })();    \n",
       "   </script>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "letsPlot(economics.toMap()){x=\"date\"; y=\"uempmed\"} +\n",
    " geomLine(tooltips=layerTooltips()\n",
    "               .line(\"@uempmed % in @date\")\n",
    "               .format(\"date\", \"%B %Y\")\n",
    "               .anchor(\"top_left\")\n",
    "               .minWidth(170)) +\n",
    " scaleXDateTime() +\n",
    " scaleYContinuous() +\n",
    " ylab(\"unemployment rate\") +\n",
    " ggsize(900, 400)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Add the unemployment rate mean.\n",
    "\n",
    "The `geomText` label is formatted using the `labelFormat` parameter."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"ZqF8tL\"></div>\n",
       "   <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n",
       "       (function() {\n",
       "           var plotSpec={\n",
       "\"ggtitle\":{\n",
       "\"text\":\"The US Unemployment Rates 2000-2016.\"\n",
       "},\n",
       "\"mapping\":{\n",
       "\"x\":\"date\",\n",
       "\"y\":\"uempmed\"\n",
       "},\n",
       "\"data\":{\n",
       "\"date\":[9.467028E11,9.493812E11,9.518868E11,9.545652E11,9.571536E11,9.59832E11,9.62424E11,9.651024E11,9.677808E11,9.703728E11,9.730548E11,9.756468E11,9.783252E11,9.810036E11,9.834228E11,9.861012E11,9.886896E11,9.91368E11,9.9396E11,9.966384E11,9.993168E11,1.0019088E12,1.0045908E12,1.0071828E12,1.0098612E12,1.0125396E12,1.0149588E12,1.0176372E12,1.0202256E12,1.022904E12,1.025496E12,1.0281744E12,1.0308528E12,1.0334448E12,1.0361268E12,1.0387188E12,1.0413972E12,1.0440756E12,1.0464948E12,1.0491732E12,1.0517616E12,1.05444E12,1.057032E12,1.0597104E12,1.0623888E12,1.0649808E12,1.0676628E12,1.0702548E12,1.0729332E12,1.0756116E12,1.0781172E12,1.0807956E12,1.083384E12,1.0860624E12,1.0886544E12,1.0913328E12,1.0940112E12,1.0966032E12,1.0992852E12,1.1018772E12,1.1045556E12,1.107234E12,1.1096532E12,1.1123316E12,1.11492E12,1.1175984E12,1.1201904E12,1.1228688E12,1.1255472E12,1.1281392E12,1.1308212E12,1.1334132E12,1.1360916E12,1.13877E12,1.1411892E12,1.1438676E12,1.146456E12,1.1491344E12,1.1517264E12,1.1544048E12,1.1570832E12,1.1596752E12,1.1623572E12,1.1649492E12,1.1676276E12,1.170306E12,1.1727252E12,1.1754E12,1.177992E12,1.1806704E12,1.1832624E12,1.1859408E12,1.1886192E12,1.1912112E12,1.1938896E12,1.1964852E12,1.1991636E12,1.201842E12,1.2043476E12,1.2070224E12,1.2096144E12,1.2122928E12,1.2148848E12,1.2175632E12,1.2202416E12,1.2228336E12,1.225512E12,1.2281076E12,1.230786E12,1.2334644E12,1.2358836E12,1.2385584E12,1.2411504E12,1.2438288E12,1.2464208E12,1.2490992E12,1.2517776E12,1.2543696E12,1.257048E12,1.2596436E12,1.262322E12,1.2650004E12,1.2674196E12,1.2700944E12,1.2726864E12,1.2753648E12,1.2779568E12,1.2806352E12,1.2833136E12,1.2859056E12,1.288584E12,1.2911796E12,1.293858E12,1.2965364E12,1.2989556E12,1.3016304E12,1.3042224E12,1.3069008E12,1.3094928E12,1.3121712E12,1.3148496E12,1.3174416E12,1.32012E12,1.3227156E12,1.325394E12,1.3280724E12,1.330578E12,1.3332528E12,1.3358448E12,1.3385232E12,1.3411152E12,1.3437936E12,1.346472E12,1.349064E12,1.3517424E12,1.354338E12,1.3570164E12,1.3596948E12,1.362114E12,1.3647888E12,1.3673808E12,1.3700592E12,1.3726512E12,1.3753296E12,1.378008E12,1.3806E12,1.3832784E12,1.385874E12,1.3885524E12,1.3912308E12,1.39365E12,1.3963248E12,1.3989168E12,1.4015952E12,1.4041872E12,1.4068656E12,1.409544E12,1.412136E12,1.4148144E12,1.41741E12,1.4200884E12,1.4227668E12,1.425186E12,1.4278608E12],\n",
       "\"uempmed\":[5.8,6.1,6.0,6.1,5.8,5.7,6.0,6.3,5.2,6.1,6.1,6.0,5.8,6.1,6.6,5.9,6.3,6.0,6.8,6.9,7.2,7.3,7.7,8.2,8.4,8.3,8.4,8.9,9.5,11.0,8.9,9.0,9.5,9.6,9.3,9.6,9.6,9.5,9.7,10.2,9.9,11.5,10.3,10.1,10.2,10.4,10.3,10.4,10.6,10.2,10.2,9.5,9.9,11.0,8.9,9.2,9.6,9.5,9.7,9.5,9.4,9.2,9.3,9.0,9.1,9.0,8.8,9.2,8.4,8.6,8.5,8.7,8.6,9.1,8.7,8.4,8.5,7.3,8.0,8.4,8.0,7.9,8.3,7.5,8.3,8.5,9.1,8.6,8.2,7.7,8.7,8.8,8.7,8.4,8.6,8.4,9.0,8.7,8.7,9.4,7.9,9.0,9.7,9.7,10.2,10.4,9.8,10.5,10.7,11.7,12.3,13.1,14.2,17.2,16.0,16.3,17.8,18.9,19.8,20.1,20.0,19.9,20.4,22.1,22.3,25.2,22.3,21.0,20.3,21.2,21.0,21.9,21.5,21.1,21.5,20.9,21.6,22.4,22.0,22.4,22.0,20.6,20.8,20.5,20.8,19.7,19.2,19.1,19.9,20.4,17.5,18.4,18.8,19.9,18.6,17.7,15.8,17.2,17.6,17.1,17.1,17.0,16.2,16.5,16.5,16.3,17.1,17.3,15.4,15.9,15.8,15.7,14.6,13.8,13.1,12.9,13.4,13.6,13.0,12.9,13.2,12.9,12.0,11.5]\n",
       "},\n",
       "\"ggsize\":{\n",
       "\"width\":900.0,\n",
       "\"height\":400.0\n",
       "},\n",
       "\"kind\":\"plot\",\n",
       "\"scales\":[{\n",
       "\"aesthetic\":\"x\",\n",
       "\"datetime\":true,\n",
       "\"format\":\"%b %Y\"\n",
       "},{\n",
       "\"aesthetic\":\"y\",\n",
       "\"format\":\"{} %\"\n",
       "},{\n",
       "\"aesthetic\":\"y\",\n",
       "\"name\":\"unemployment rate\"\n",
       "}],\n",
       "\"layers\":[{\n",
       "\"mapping\":{\n",
       "},\n",
       "\"stat\":\"identity\",\n",
       "\"position\":\"identity\",\n",
       "\"geom\":\"line\",\n",
       "\"tooltips\":{\n",
       "\"lines\":[\"Unemployment rate:|^y %\"],\n",
       "\"tooltip_min_width\":170,\n",
       "\"tooltip_anchor\":\"top_center\"\n",
       "},\n",
       "\"data\":{\n",
       "}\n",
       "},{\n",
       "\"mapping\":{\n",
       "},\n",
       "\"stat\":\"identity\",\n",
       "\"yintercept\":12.378260869565219,\n",
       "\"color\":\"red\",\n",
       "\"linetype\":\"dashed\",\n",
       "\"position\":\"identity\",\n",
       "\"geom\":\"hline\",\n",
       "\"tooltips\":\"none\",\n",
       "\"data\":{\n",
       "}\n",
       "},{\n",
       "\"mapping\":{\n",
       "},\n",
       "\"stat\":\"identity\",\n",
       "\"color\":\"red\",\n",
       "\"label_format\":\"{.2f} %\",\n",
       "\"x\":9.467028E11,\n",
       "\"y\":12.878260869565219,\n",
       "\"position\":\"identity\",\n",
       "\"label\":\"12.378260869565219\",\n",
       "\"geom\":\"text\",\n",
       "\"data\":{\n",
       "}\n",
       "}]\n",
       "};\n",
       "           var plotContainer = document.getElementById(\"ZqF8tL\");\n",
       "           window.letsPlotCall(function() {{\n",
       "               LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n",
       "           }});\n",
       "       })();    \n",
       "   </script>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val unemploymentMean = economics.uempmed.mean()\n",
    "\n",
    "\n",
    "letsPlot(economics.toMap()){x=\"date\"; y=\"uempmed\"} + \n",
    " geomLine(tooltips=layerTooltips()\n",
    "        .line(\"Unemployment rate:|^y %\")\n",
    "        .anchor(\"top_center\")\n",
    "        .minWidth(170)) + \n",
    " geomHLine(yintercept=unemploymentMean, color=\"red\", linetype=\"dashed\", tooltips=tooltipsNone) +\n",
    " geomText(label=unemploymentMean.toString(), \n",
    "           labelFormat=\"{.2f} %\",\n",
    "           x=startDate.toEpochMilliseconds(), y=unemploymentMean!! + 0.5, \n",
    "           color=\"red\") +\n",
    " scaleXDateTime(format=\"%b %Y\") + \n",
    " scaleYContinuous(format=\"{} %\") + \n",
    " ylab(\"unemployment rate\") +\n",
    " ggtitle(\"The US Unemployment Rates 2000-2016.\") +\n",
    " ggsize(900, 400)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Kotlin",
   "language": "kotlin",
   "name": "kotlin"
  },
  "language_info": {
   "codemirror_mode": "text/x-kotlin",
   "file_extension": ".kt",
   "mimetype": "text/x-kotlin",
   "name": "kotlin",
   "nbconvert_exporter": "",
   "pygments_lexer": "kotlin",
   "version": "1.8.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}