{ "cells": [ { "cell_type": "markdown", "id": "c19df4e5", "metadata": {}, "source": [ "# Stackable Position Adjustments" ] }, { "cell_type": "markdown", "id": "86364518", "metadata": {}, "source": [ "## Table of Contents\n", "\n", "1. [Stacking in Area Plots ](#default)\n", "\n", "2. [Stacking Order](#order)\n", "\n", "3. [Other Geometries](#other-geoms)\n", "\n", "4. [Parameter `vjust`](#vjust)\n", "\n", "5. [Parameter `mode`](#mode)\n", "\n", "6. [Negative Values](#negative)" ] }, { "cell_type": "code", "execution_count": 1, "id": "2b550c1b", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:36.551018Z", "iopub.status.busy": "2024-08-23T11:03:36.549881Z", "iopub.status.idle": "2024-08-23T11:03:39.170163Z", "shell.execute_reply": "2024-08-23T11:03:39.169847Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%useLatestDescriptors\n", "%use lets-plot\n", "%use dataframe" ] }, { "cell_type": "code", "execution_count": 2, "id": "68ae35a9", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:39.171811Z", "iopub.status.busy": "2024-08-23T11:03:39.171541Z", "iopub.status.idle": "2024-08-23T11:03:39.204732Z", "shell.execute_reply": "2024-08-23T11:03:39.204907Z" } }, "outputs": [ { "data": { "text/plain": [ "Lets-Plot Kotlin API v.4.7.2. Frontend: Notebook with dynamically loaded JS. Lets-Plot JS v.4.3.2." ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "LetsPlot.getInfo()" ] }, { "cell_type": "code", "execution_count": 3, "id": "5ee3317a", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:39.206823Z", "iopub.status.busy": "2024-08-23T11:03:39.206428Z", "iopub.status.idle": "2024-08-23T11:03:39.807859Z", "shell.execute_reply": "2024-08-23T11:03:39.807574Z" } }, "outputs": [ { "data": { "application/kotlindataframe+json": "{\"nrow\":5,\"ncol\":12,\"columns\":[\"untitled\",\"manufacturer\",\"model\",\"displ\",\"year\",\"cyl\",\"trans\",\"drv\",\"cty\",\"hwy\",\"fl\",\"class\"],\"kotlin_dataframe\":[{\"untitled\":1,\"manufacturer\":\"audi\",\"model\":\"a4\",\"displ\":1.8,\"year\":1999,\"cyl\":4,\"trans\":\"auto(l5)\",\"drv\":\"f\",\"cty\":18,\"hwy\":29,\"fl\":\"p\",\"class\":\"compact\"},{\"untitled\":2,\"manufacturer\":\"audi\",\"model\":\"a4\",\"displ\":1.8,\"year\":1999,\"cyl\":4,\"trans\":\"manual(m5)\",\"drv\":\"f\",\"cty\":21,\"hwy\":29,\"fl\":\"p\",\"class\":\"compact\"},{\"untitled\":3,\"manufacturer\":\"audi\",\"model\":\"a4\",\"displ\":2.0,\"year\":2008,\"cyl\":4,\"trans\":\"manual(m6)\",\"drv\":\"f\",\"cty\":20,\"hwy\":31,\"fl\":\"p\",\"class\":\"compact\"},{\"untitled\":4,\"manufacturer\":\"audi\",\"model\":\"a4\",\"displ\":2.0,\"year\":2008,\"cyl\":4,\"trans\":\"auto(av)\",\"drv\":\"f\",\"cty\":21,\"hwy\":30,\"fl\":\"p\",\"class\":\"compact\"},{\"untitled\":5,\"manufacturer\":\"audi\",\"model\":\"a4\",\"displ\":2.8,\"year\":1999,\"cyl\":6,\"trans\":\"auto(l5)\",\"drv\":\"f\",\"cty\":16,\"hwy\":26,\"fl\":\"p\",\"class\":\"compact\"}]}", "text/html": [ " \n", " \n", " \n", " \n", " \n", "
\n", "\n", "

DataFrame: rowsCount = 5, columnsCount = 12

\n", "
untitledmanufacturermodeldisplyearcyltransdrvctyhwyflclass
1audia41.80000019994auto(l5)f1829pcompact
2audia41.80000019994manual(m5)f2129pcompact
3audia42.00000020084manual(m6)f2031pcompact
4audia42.00000020084auto(av)f2130pcompact
5audia42.80000019996auto(l5)f1626pcompact
\n", " \n", " \n", " " ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val mpgDf = DataFrame.readCSV(\"https://raw.githubusercontent.com/JetBrains/lets-plot-kotlin/master/docs/examples/data/mpg.csv\")\n", "mpgDf.head()\n" ] }, { "cell_type": "code", "execution_count": 4, "id": "cdeb8a0b", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:39.810530Z", "iopub.status.busy": "2024-08-23T11:03:39.809970Z", "iopub.status.idle": "2024-08-23T11:03:39.837688Z", "shell.execute_reply": "2024-08-23T11:03:39.837379Z" } }, "outputs": [], "source": [ "val mpgData = mpgDf.toMap()" ] }, { "cell_type": "code", "execution_count": 5, "id": "mobile-terrain", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:39.839935Z", "iopub.status.busy": "2024-08-23T11:03:39.839492Z", "iopub.status.idle": "2024-08-23T11:03:39.878943Z", "shell.execute_reply": "2024-08-23T11:03:39.878612Z" } }, "outputs": [], "source": [ "val pairedPalette = scaleBrewer(listOf(\"color\", \"fill\"), palette = \"Paired\")" ] }, { "cell_type": "markdown", "id": "a6c57218", "metadata": {}, "source": [ "\n", "\n", "#### 1. Stacking in Area Plots \n", "\n", "Stacking is the default behaviour for most area plots.\n", "\n", "\"Fill\" makes it easier to compare proportions." ] }, { "cell_type": "code", "execution_count": 6, "id": "6bf7191d", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:39.881057Z", "iopub.status.busy": "2024-08-23T11:03:39.880691Z", "iopub.status.idle": "2024-08-23T11:03:40.027136Z", "shell.execute_reply": "2024-08-23T11:03:40.026916Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"drv\"; fill = asDiscrete(\"year\") } +\n", " geomBar() + \n", " pairedPalette +\n", " ggtitle(\"bar: position='stack' (default)\")" ] }, { "cell_type": "code", "execution_count": 7, "id": "52cc13c3", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.028892Z", "iopub.status.busy": "2024-08-23T11:03:40.028564Z", "iopub.status.idle": "2024-08-23T11:03:40.087153Z", "shell.execute_reply": "2024-08-23T11:03:40.087326Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"drv\"; fill = asDiscrete(\"year\") } +\n", " geomBar(position = positionFill()) + \n", " pairedPalette +\n", " ggtitle(\"bar: position='fill'\")" ] }, { "cell_type": "code", "execution_count": 8, "id": "29671b0b", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.089148Z", "iopub.status.busy": "2024-08-23T11:03:40.088822Z", "iopub.status.idle": "2024-08-23T11:03:40.153966Z", "shell.execute_reply": "2024-08-23T11:03:40.154142Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"hwy\"; fill = asDiscrete(\"year\") } +\n", " geomHistogram(bins = 12) +\n", " pairedPalette +\n", " ggtitle(\"histogram: position='stack' (default)\")" ] }, { "cell_type": "code", "execution_count": 9, "id": "9dd266b0", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.155548Z", "iopub.status.busy": "2024-08-23T11:03:40.155303Z", "iopub.status.idle": "2024-08-23T11:03:40.211449Z", "shell.execute_reply": "2024-08-23T11:03:40.211610Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"hwy\"; fill = asDiscrete(\"year\") } +\n", " geomHistogram(bins = 12, position = positionFill()) +\n", " pairedPalette +\n", " ggtitle(\"histogram: position='fill'\")" ] }, { "cell_type": "code", "execution_count": 10, "id": "41435d9b", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.213066Z", "iopub.status.busy": "2024-08-23T11:03:40.212816Z", "iopub.status.idle": "2024-08-23T11:03:40.289229Z", "shell.execute_reply": "2024-08-23T11:03:40.289007Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"hwy\"; fill = asDiscrete(\"year\") } +\n", " geomArea(stat = Stat.density(), color = \"white\") +\n", " pairedPalette +\n", " ggtitle(\"area: position='stack' (default)\")" ] }, { "cell_type": "code", "execution_count": 11, "id": "a53f3e3c", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.290498Z", "iopub.status.busy": "2024-08-23T11:03:40.290262Z", "iopub.status.idle": "2024-08-23T11:03:40.358146Z", "shell.execute_reply": "2024-08-23T11:03:40.358318Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"hwy\"; fill = asDiscrete(\"year\") } +\n", " geomArea(stat = Stat.density(), position = positionFill(), color = \"white\") +\n", " pairedPalette +\n", " ggtitle(\"area: position='fill'\")" ] }, { "cell_type": "markdown", "id": "ffdc861e", "metadata": {}, "source": [ "\n", "\n", "#### 2. Stacking Order\n", "\n", "Control the stacking order by changing the `order` parameter of the `asDiscrete()` function." ] }, { "cell_type": "code", "execution_count": 12, "id": "d2c3d6e0", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.359815Z", "iopub.status.busy": "2024-08-23T11:03:40.359563Z", "iopub.status.idle": "2024-08-23T11:03:40.422545Z", "shell.execute_reply": "2024-08-23T11:03:40.422713Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"hwy\" } +\n", " geomArea(stat = Stat.density(), color = \"white\") { fill = asDiscrete(\"drv\") } +\n", " pairedPalette +\n", " ggtitle(\"Default order of drive types\")" ] }, { "cell_type": "code", "execution_count": 13, "id": "3378676a", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.424041Z", "iopub.status.busy": "2024-08-23T11:03:40.423793Z", "iopub.status.idle": "2024-08-23T11:03:40.490718Z", "shell.execute_reply": "2024-08-23T11:03:40.490570Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"hwy\" } +\n", " geomArea(stat = Stat.density(), color = \"white\") { fill = asDiscrete(\"drv\", order = -1) } +\n", " pairedPalette +\n", " ggtitle(\"Backward order of drive types\")" ] }, { "cell_type": "markdown", "id": "8af903f8", "metadata": {}, "source": [ "\n", "\n", "#### 3. Other Geometries\n", "\n", "Let's have a look at the geometries, for which the default position adjustment differs from `'stack'` and `'fill'`.\n", "\n", "When stacking across multiple layers it's a good idea to set the **`group`** aesthetic - this ensures that all layers are stacked in the same way." ] }, { "cell_type": "code", "execution_count": 14, "id": "37bb8e38", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.492277Z", "iopub.status.busy": "2024-08-23T11:03:40.492020Z", "iopub.status.idle": "2024-08-23T11:03:40.559232Z", "shell.execute_reply": "2024-08-23T11:03:40.559015Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"drv\"; color = asDiscrete(\"year\") } +\n", " geomLine(stat = Stat.count(), position = positionStack(), size = 1.5) +\n", " geomPoint(stat = Stat.count(), position = positionStack(), size = 5) +\n", " pairedPalette +\n", " ggtitle(\"Line and point\")" ] }, { "cell_type": "code", "execution_count": 15, "id": "e5b4e5a4", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.561235Z", "iopub.status.busy": "2024-08-23T11:03:40.560969Z", "iopub.status.idle": "2024-08-23T11:03:40.625852Z", "shell.execute_reply": "2024-08-23T11:03:40.625723Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"drv\" } +\n", " geomArea(stat = Stat.count(), position = positionStack(), color = \"white\") { fill = asDiscrete(\"year\") } +\n", " geomLine(stat = Stat.count(), position = positionStack(), color = \"white\") { group = \"year\" } +\n", " pairedPalette +\n", " ggtitle(\"Area and line\")" ] }, { "cell_type": "markdown", "id": "d57f4b14", "metadata": {}, "source": [ "\n", "\n", "#### 4. Parameter `vjust`\n", "\n", "The `vjust` argument of `positionStack()` is used to move the location of plot elements vertically (vjust stands for vertical adjustment)." ] }, { "cell_type": "code", "execution_count": 16, "id": "59d57295", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.627764Z", "iopub.status.busy": "2024-08-23T11:03:40.627524Z", "iopub.status.idle": "2024-08-23T11:03:40.704910Z", "shell.execute_reply": "2024-08-23T11:03:40.704693Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"drv\" } +\n", " geomArea(stat = Stat.count(), position = positionStack(), color = \"white\") { fill = asDiscrete(\"year\") } +\n", " geomLabel(stat = Stat.count(), position = positionStack(), color = \"black\") {\n", " label = \"..count..\"; group = \"year\" \n", " } +\n", " pairedPalette +\n", " ggtitle(\"vjust=1 (default)\")" ] }, { "cell_type": "code", "execution_count": 17, "id": "b38dd461", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.706425Z", "iopub.status.busy": "2024-08-23T11:03:40.706262Z", "iopub.status.idle": "2024-08-23T11:03:40.776485Z", "shell.execute_reply": "2024-08-23T11:03:40.776360Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"drv\" } +\n", " geomArea(stat = Stat.count(), position = positionStack(), color = \"white\") { fill = asDiscrete(\"year\") } +\n", " geomLabel(stat = Stat.count(), position = positionStack(vjust = 0.5), color = \"black\") {\n", " label = \"..count..\"; group = \"year\" \n", " } +\n", " pairedPalette +\n", " ggtitle(\"vjust=0.5\")" ] }, { "cell_type": "markdown", "id": "19272796", "metadata": {}, "source": [ "\n", "\n", "#### 5. Parameter `mode`\n", "\n", "By default only objects from different groups are stacked over each other, and objects inside one group are positioned as in `position = positionIdentity`.\n", "\n", "This behaviour could be changed by switching `mode` parameter.\n", "\n", "`mode=\"all\"` means, that each object will be shifted." ] }, { "cell_type": "code", "execution_count": 18, "id": "9a3846ff", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.777895Z", "iopub.status.busy": "2024-08-23T11:03:40.777650Z", "iopub.status.idle": "2024-08-23T11:03:40.848899Z", "shell.execute_reply": "2024-08-23T11:03:40.849093Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"hwy\"; color = \"class\" } +\n", " geomPoint(y = 1, position = positionStack()) +\n", " coordFixed() + ylim(1 to 35) +\n", " ggtitle(\"mode='groups' (default)\")" ] }, { "cell_type": "code", "execution_count": 19, "id": "912b21fe", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.851586Z", "iopub.status.busy": "2024-08-23T11:03:40.851318Z", "iopub.status.idle": "2024-08-23T11:03:40.920864Z", "shell.execute_reply": "2024-08-23T11:03:40.921031Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(mpgData) { x = \"hwy\"; color = \"class\" } +\n", " geomPoint(y = 1, position = positionStack(mode = \"all\")) +\n", " coordFixed() + ylim(1 to 35) +\n", " ggtitle(\"mode='all'\") " ] }, { "cell_type": "markdown", "id": "c85c7b82", "metadata": {}, "source": [ "\n", "\n", "#### 6. Negative Values\n", "\n", "Stacking supports positive and negative shifts of the objects separately." ] }, { "cell_type": "code", "execution_count": 20, "id": "d54478e2", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.923302Z", "iopub.status.busy": "2024-08-23T11:03:40.923042Z", "iopub.status.idle": "2024-08-23T11:03:40.969617Z", "shell.execute_reply": "2024-08-23T11:03:40.969350Z" } }, "outputs": [], "source": [ "val data = mapOf(\n", " \"x\" to listOf(0, 1, 2, 0, 1, 2),\n", " \"y\" to listOf(4, 2, 3, 0, 1, -1),\n", " \"g\" to listOf(\"a\", \"a\", \"a\", \"b\", \"b\", \"b\")\n", ")" ] }, { "cell_type": "code", "execution_count": 21, "id": "3da949c1", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:40.971519Z", "iopub.status.busy": "2024-08-23T11:03:40.971139Z", "iopub.status.idle": "2024-08-23T11:03:41.033544Z", "shell.execute_reply": "2024-08-23T11:03:41.033330Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(data) { x = \"x\"; y = \"y\"; fill = \"g\" } +\n", " geomBar(stat = Stat.identity) +\n", " geomHLine(yintercept = 0, color = \"black\") +\n", " pairedPalette +\n", " theme(axisLine = \"blank\", axisTicks = \"blank\") " ] }, { "cell_type": "code", "execution_count": 22, "id": "edc9e013", "metadata": { "execution": { "iopub.execute_input": "2024-08-23T11:03:41.035547Z", "iopub.status.busy": "2024-08-23T11:03:41.035295Z", "iopub.status.idle": "2024-08-23T11:03:41.103775Z", "shell.execute_reply": "2024-08-23T11:03:41.103947Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(data) { x = \"x\"; y = \"y\" } +\n", " geomBar(stat = Stat.identity, position = positionFill()) { fill = \"g\"} +\n", " geomLabel(stat = Stat.identity, position = positionFill(vjust = 0.5)) { label = \"g\"; group = \"g\" } +\n", " geomHLine(yintercept=0, color=\"black\") +\n", " pairedPalette +\n", " theme(axisLine = \"blank\", axisTicks = \"blank\") " ] } ], "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.9.23" } }, "nbformat": 4, "nbformat_minor": 5 }