{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "e9cff123", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%useLatestDescriptors\n", "%use lets-plot" ] }, { "cell_type": "code", "execution_count": 2, "id": "f27ed1dd", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Lets-Plot Kotlin API v.0.0.0-SNAPSHOT. Frontend: Notebook with dynamically loaded JS. Lets-Plot JS v.4.3.0." ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "LetsPlot.getInfo()" ] }, { "cell_type": "markdown", "id": "22bed5b6", "metadata": {}, "source": [ "#### Set `themeGrey()` as default theme. It improves plots readability." ] }, { "cell_type": "code", "execution_count": 3, "id": "19e17aad", "metadata": {}, "outputs": [], "source": [ "LetsPlot.theme = themeGrey()" ] }, { "cell_type": "markdown", "id": "8493d965", "metadata": {}, "source": [ "#### Data" ] }, { "cell_type": "code", "execution_count": 4, "id": "58d3ca1e", "metadata": {}, "outputs": [], "source": [ "val labelsData = mapOf(\n", " \"x\" to listOf(0, 1, 2, 3, 4, 5, 6, 7, 8),\n", " \"y\" to listOf(0, 45, 90, 135, 180, 225, 270, 315, 360),\n", " \"r_y\" to listOf(360, 315, 270, 225, 180, 135, 90, 45, 0),\n", " \"l\" to listOf(\"l0\", \"l45\", \"l90\", \"l135\", \"l180\", \"l225\", \"l270\", \"l315\", \"l360\"),\n", " \"g\" to listOf(\"g1\", \"g1\", \"g1\", \"g2\", \"g2\", \"g2\", \"g3\", \"g3\", \"g3\")\n", ")\n", "\n", "val lollipopData = mapOf(\n", " \"c\" to listOf(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"),\n", " \"x\" to listOf(1, 2, 3, 4, 5, 6),\n", " \"y\" to listOf(1, 2, 3, 4, 5, 6)\n", ")\n", "\n", "val studentData = mapOf(\n", " \"subj\" to listOf(\"progr\", \"math\", \"physic\", \"chemistry\", \"biology\"),\n", " \"subjId\" to listOf(1, 2, 3, 4, 5),\n", " \"student\" to List(5) { \"John\" },\n", " \"score\" to listOf(19, 15, 18, 12, 9)\n", ")" ] }, { "cell_type": "markdown", "id": "d66230d8", "metadata": {}, "source": [ "# Geoms" ] }, { "cell_type": "markdown", "id": "1701efea", "metadata": {}, "source": [ "## `geomArea()`\n", "Line get transformed into a circle:" ] }, { "cell_type": "code", "execution_count": 5, "id": "0e96441f", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot() + geomArea() { x = listOf(0, 1); y = listOf(1, 1) }\n", "\n", "gggrid(listOf(\n", " p,\n", " p + coordPolar()\n", "))" ] }, { "cell_type": "markdown", "id": "e71e86c1", "metadata": {}, "source": [ "### `flat = true`\n", "The plot can be transformed into a radar plot by using `flat = true` and a discrete x-scale." ] }, { "cell_type": "code", "execution_count": 6, "id": "310d15d7", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot(studentData) +\n", " geomArea(flat = true) { x = \"subjId\"; y = \"score\" } +\n", " geomPoint() { x = \"subjId\"; y = \"score\" }\n", "\n", "val labels = mapOf(1 to \"progr\", 2 to \"math\", 3 to \"physic\", 4 to \"chemistry\", 5 to \"biology\")\n", "\n", "val continuous = scaleXContinuous(labels = labels)\n", "val discrete = scaleXDiscrete(labels = labels)\n", "\n", "gggrid(listOf(\n", " p + continuous,\n", " p + continuous + coordPolar() + ggtitle(\"scaleXContinuous\"),\n", " p + discrete + coordPolar() + ggtitle(\"scaleXDiscrete\"),\n", "))" ] }, { "cell_type": "markdown", "id": "302a6755", "metadata": {}, "source": [ "## `geomSegment()`" ] }, { "cell_type": "code", "execution_count": 7, "id": "2631a836", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot() +\n", " geomSegment(x = 0, y = 0, xend = 4, yend = 4, arrow = arrow(), size = 1) +\n", " geomSegment(x = 8, y = 0, xend = 4, yend = 4, arrow = arrow(), size = 1)\n", "\n", "gggrid(listOf(\n", " p,\n", " p + coordPolar()\n", "))" ] }, { "cell_type": "markdown", "id": "905a37de", "metadata": {}, "source": [ "`sizeEnd`/`strokeEnd` precision length adjustment parameters:" ] }, { "cell_type": "code", "execution_count": 8, "id": "adcba1b0", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// known problem - zero-length segment because of second datapoint.\n", "// this is a temp workaround to sync stroke/stroke_end and size/size_ens domains\n", "val d = mapOf( \n", " \"x\" to listOf(0, 1),\n", " \"y\" to listOf(0, 0),\n", " \"size\" to listOf(8, 10), \n", " \"stroke\" to listOf(1, 2),\n", " \"size_end\" to listOf(10, 0), \n", " \"stroke_end\" to listOf(2, 0)\n", ")\n", "\n", "val p = letsPlot(d) { x = \"x\"; y = \"y\" } +\n", " geomPoint(shape = 21, alpha = 0.5, color = \"red\", showLegend = false) { size = \"size\"; stroke = \"stroke\" } +\n", " geomSegment(xend = 1, yend = 0, size = 2,\n", " arrow = arrow(ends = \"both\", type = \"open\", length = 22, angle = 30)) {\n", " sizeStart = \"size\" \n", " strokeStart = \"stroke\";\n", " sizeEnd = \"size_end\"\n", " strokeEnd = \"stroke_end\"\n", " } +\n", " scaleSizeIdentity()\n", "\n", "gggrid(listOf(\n", " p,\n", " p + coordPolar(xlim = -0.35 to 1.35, ylim = -2 to 2) // lims are only to make the figure smiling\n", "))" ] }, { "cell_type": "markdown", "id": "b6cdd2cb", "metadata": {}, "source": [ "## `geomLabel()`\n", "Regular scatter plot." ] }, { "cell_type": "code", "execution_count": 9, "id": "3a5077c9", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot(labelsData) { x = \"x\"; y = \"y\"; label = \"l\" } + geomLabel()\n", "\n", "gggrid(listOf(\n", " p, \n", " p + coordPolar() + ggtitle(\"coordPolar()\"),\n", " p + coordPolar(theta = \"y\") + ggtitle(\"theta=y\"),\n", "))" ] }, { "cell_type": "markdown", "id": "7bd3a25e", "metadata": {}, "source": [ "## `geomPath()`\n", "The transform resamples path data by converting straight segments into curves. The `flat` parameter controls this behaviour." ] }, { "cell_type": "code", "execution_count": 10, "id": "7b3acdd4", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot(labelsData) { x = \"x\"; y = \"y\"; color = \"y\" } + scaleColorBrewer(palette = \"GnBu\")\n", "\n", "gggrid(listOf(\n", " p + geomPath(size = 3) + coordPolar() + ggtitle(\"coordPolar()\"),\n", " p + geomPath(size = 3, flat = true) + coordPolar(theta = \"x\") + ggtitle(\"coordPolar(), flat=true\")\n", "), ncol=2)" ] }, { "cell_type": "markdown", "id": "b92bad8b", "metadata": {}, "source": [ "### Autoclose on a discrete x-scale" ] }, { "cell_type": "code", "execution_count": 11, "id": "82e42a31", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(studentData) + geomPath(flat = true) { x = \"subj\"; y = \"score\" } + coordPolar(ylim = 0 to 20)" ] }, { "cell_type": "markdown", "id": "a5a9f07e", "metadata": {}, "source": [ "## `geomLollipop()`\n", "See the `Params` section for details on using the `ylim` parameters." ] }, { "cell_type": "code", "execution_count": 12, "id": "97bbaa08", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot(lollipopData) { x = \"c\"; y = \"y\" } + geomLollipop()\n", "\n", "gggrid(listOf(\n", " p, \n", " p + coordPolar()\n", "))" ] }, { "cell_type": "markdown", "id": "151574dc", "metadata": {}, "source": [ "## `geomBar()` \n", "This works similarly to rects, but with the addition of tooltips." ] }, { "cell_type": "markdown", "id": "d7e89e70", "metadata": {}, "source": [ "### `position='stack'`" ] }, { "cell_type": "code", "execution_count": 13, "id": "37245cb7", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val barData = mapOf(\"foo\" to listOf(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3))\n", "val p = letsPlot(barData) + geomBar(size = 0) { fill = asDiscrete(\"foo\", order = 1) }\n", "\n", "gggrid(listOf(\n", " p,\n", " p + coordPolar(theta=\"y\") + ggtitle(\"position=stack, coord_polar(theta=y)\"),\n", " p + coordPolar(theta=\"x\") + ggtitle(\"position=stack, coord_polar(theta=x)\"),\n", "))" ] }, { "cell_type": "markdown", "id": "56d2d740", "metadata": {}, "source": [ "### `position='dodge'`" ] }, { "cell_type": "code", "execution_count": 14, "id": "79aeaf6f", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot(barData) + geomBar(size = 0, position = positionDodge()) { fill = asDiscrete(\"foo\", order = 1) }\n", "\n", "gggrid(listOf(\n", " p,\n", " p + coordPolar(theta=\"y\") + ggtitle(\"position=dodge, coord_polar(theta=y)\"),\n", " p + coordPolar(theta=\"x\") + ggtitle(\"position=dodge, coord_polar(theta=x)\"),\n", "))" ] }, { "cell_type": "markdown", "id": "d076e78b", "metadata": {}, "source": [ "### `stat='identity'`\n", "On a continuous x-scale the first and last bars stuck. The `expand` parameter can be used to fix this." ] }, { "cell_type": "code", "execution_count": 15, "id": "1fce12df", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val data = mapOf(\n", " \"x\" to listOf(1, 2, 3),\n", " \"y\" to listOf(5, 3, 4)\n", ")\n", "\n", "val barId = letsPlot(data) + geomBar(stat = Stat.identity, width = 0.8) { x = \"x\"; y = \"y\" } + coordPolar()\n", "\n", "gggrid(listOf(\n", " barId + ggtitle(\"Continuous x\"),\n", " barId + scaleXContinuous(expand = listOf(0, 0.1)) + ggtitle(\"scaleXContinuous(expand=[0, 0.1))\")\n", "))" ] }, { "cell_type": "code", "execution_count": 16, "id": "1372b27c", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "barId + scaleXDiscrete() + ggtitle(\"Discrete x\")" ] }, { "cell_type": "markdown", "id": "a7084648", "metadata": {}, "source": [ "## `geomHLine()`/`geomVLine()`" ] }, { "cell_type": "code", "execution_count": 17, "id": "4506efab", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot() +\n", " geomHLine(yintercept = 5, color = \"red\") +\n", " geomHLine(yintercept = 10, color = \"green\") +\n", " geomHLine(yintercept = 15, color = \"blue\") +\n", " geomHLine(yintercept = 20, color = \"orange\") +\n", " geomVLine(xintercept = 10, color = \"pink\") +\n", " geomVLine(xintercept = 20, color = \"magenta\") +\n", " geomVLine(xintercept = 30, color = \"dark_green\") +\n", " xlim(0 to 30) +\n", " ylim(0 to 20)\n", " \n", "gggrid(listOf(p, p + coordPolar()))" ] }, { "cell_type": "markdown", "id": "dc107ee4", "metadata": {}, "source": [ "## `geomTile()`" ] }, { "cell_type": "code", "execution_count": 18, "id": "4a7349b8", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fun meshgridPoints(x:List