{ "cells": [ { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "# Lets-Plot Usage Guide\n", "\n", "<a href=\"https://opensource.org/licenses/MIT\">\n", "<img src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"Couldn't load MIT license svg\"/>\n", "</a>\n", "\n", "\n", "- [Installation](#install)\n", "- [Understanding architecture](#implementation)\n", "- [Learning API](#api)\n", "- [Getting started](#gsg)\n", "\n", "\n", "**Lets-Plot** is an open-source plotting library for statistical data. It is implemented using the \n", "[Kotlin programming language](https://kotlinlang.org/) that has a multi-platform nature.\n", "That's why Lets-Plot provides the plotting functionality that \n", "is packaged as a JavaScript library, a JVM library, and a native Python extension.\n", "\n", "The design of the Lets-Plot library is heavily influenced by [ggplot2](https://ggplot2.tidyverse.org) library.\n", "\n", "<a name=\"Installation\" id=\"install\"></a>\n", "## Installation\n", "\n", "Library is distributed via [Maven Central](https://central.sonatype.com/artifact/org.jetbrains.lets-plot/lets-plot-kotlin).\n", "You can include it in your Kotlin or Java project using Maven or Gradle configuration files (see also [Developer guide](https://github.com/JetBrains/lets-plot-kotlin/blob/master/USAGE_BATIK_JFX_JS.md)),\n", "or include it in your Jupyter notebook script via `%use lets-plot` annotation (see [Kotlin kernel for IPython/Jupyter](https://github.com/Kotlin/kotlin-jupyter)).\n", "\n", "<a name=\"Implementation\" id=\"implementation\"></a>\n", "## Understanding Lets-Plot architecture\n", "In `lets-plot`, the **plot** is represented at least by one\n", "**layer**. It can be built based on the default dataset with the aesthetics mappings, set of scales, or additional \n", "features applied.\n", "\n", "The **Layer** is responsible for creating the objects painted on the ‘canvas’ and it contains the following elements:\n", "- **Data** - the set of data specified either once for all layers or on a per layer basis.\n", "One plot can combine multiple different datasets (one per layer).\n", "- **Aesthetic mapping** - describes how variables in the dataset are mapped to the visual properties of the layer, such as color, shape, size, or position.\n", "- **Geometric object** - a geometric object that represents a particular type of charts.\n", "- **Statistical transformation** - computes some kind of statistical summary on the raw input data. \n", "For example, `bin` statistics is used for histograms and `smooth` is used for regression lines. \n", "Most stats take additional parameters to specify details of the statistical transformation of data.\n", "- **Position adjustment** - a method used to compute the final coordinates of geometry. \n", "Used to build variants of the same `geom` object or to avoid overplotting.\n", "\n", "\n", "\n", "<a name=\"API\" id=\"api\"></a>\n", "## Learning API\n", "The typical code fragment that plots a Lets-Plot chart looks as follows:\n", "\n", "```\n", "import org.jetbrains.letsPlot.*\n", "import org.jetbrains.letsPlot.geom.*\n", "import org.jetbrains.letsPlot.stat.*\n", "\n", "p = letsPlot(<dataframe>) \n", "p + geom<ChartType>(stat=<stat>, position=<adjustment>) { <aesthetics mapping> }\n", "```\n", "\n", "### Geometric objects `geom`\n", "\n", "You can add a new geometric object (or plot layer) by creating it using the `geomXxx()` function and then adding this object to `ggplot`:\n", "\n", "```\n", "p = letsPlot(data=df)\n", "p + geomPoint()\n", "```\n", "\n", "See the [geom reference](https://lets-plot.org/kotlin/api-reference/-lets--plot--kotlin/org.jetbrains.letsPlot.geom/index.html) for more information about the supported\n", "geometric objects, their arguments, and default values.\n", "\n", "There is also a few `statXxx()` functions which also create a plot layer.\n", "Occasionally, it feels more naturally to use `statXxx()` instead of `geomXxx()` function to add a new plot layer.\n", "For example, you might prefer to use `statCount()` instead of `geomBar()`.\n", "\n", "See the [stat layer reference](https://lets-plot.org/kotlin/api-reference/-lets--plot--kotlin/org.jetbrains.letsPlot.stat/index.html) for more information about the supported\n", "stat plot-layer objects, their arguments, and default values.\n", "\n", "\n", "### Collections of plots\n", "With the [GGBunch()](https://lets-plot.org/kotlin/api-reference/-lets--plot--kotlin/org.jetbrains.letsPlot/-g-g-bunch/index.html) object, you can\n", "render a collection of plots.\n", "Use the `addPlot()` method to add a plot to the bunch and set an arbitrary location and size for plots inside the grid:\n", "\n", "```\n", "bunch = GGBunch()\n", " .addPlot(plot1, 0, 0)\n", " .addPlot(plot2, 0, 200)\n", "bunch.show()\n", "```\n", "\n", "See the [ggbunch.ipynb](https://nbviewer.org/github/JetBrains/lets-plot-docs/blob/master/source/kotlin_examples/cookbook/ggbunch.ipynb)\n", " example for more information.\n", "\n", "### Stat `stat`\n", "\n", "Add `stat` as an argument to `geomXxx()` function to define statistical data transformations:\n", "\n", "`geomPoint(stat=Stat.count())`\n", "\n", "Supported statistical transformations:\n", "\n", "- `identity`: leave the data unchanged\n", "- `count`: calculate the number of points with same x-axis coordinate\n", "- `bin`: calculate the number of points falling in each of adjacent equally sized ranges along the x-axis\n", "- `bin2d`: calculate the number of points falling in each of adjacent equal sized rectangles on the plot plane\n", "- `smooth`: perform smoothing\n", "- `contour`, `contourFilled`, : calculate contours of 3D data\n", "- `boxplot`: calculate components of a box plot.\n", "- `density`, `density2D`, `density2DFilled`: perform a kernel density estimation for 1D and 2D data\n", "\n", "See the [stat reference](https://lets-plot.org/kotlin/api-reference/-lets--plot--kotlin/org.jetbrains.letsPlot/-stat/index.html) for more information about the supported\n", "stat objects, their arguments, and default values.\n", "\n", "\n", "### Aesthetic mappings `mapping`\n", "With mappings, you can define how variables in dataset are mapped to the visual elements of the chart.\n", "Add the `{x=< >; y=< >; ...}` closure to `geom`, where:\n", "- `x`: the dataframe column to map to the x axis. \n", "- `y`: the dataframe column to map to the y axis.\n", "- `...`: other visual properties of the chart, such as color, shape, size, or position.\n", "\n", "`geom_point() {x = \"cty\"; y = \"hwy\"; color=\"cyl\"}`\n", "\n", "### Position adjustment `position`\n", "\n", "All layers have a position adjustment that computes the final coordinates of geometry.\n", "Position adjustment is used to build variances of the same plots and resolve overlapping.\n", "Override the default settings by using the `position` argument in the `geom` functions:\n", "\n", "`geomBar(position=positionFill)`\n", "\n", "or\n", "\n", "`geomBar(position=positionDodge(width=1.01))`\n", "\n", "Available adjustments:\n", "- `dodge`\n", "- `jitter`\n", "- `jitterdodge`\n", "- `nudge`\n", "- `identity`\n", "- `fill`\n", "- `stack`\n", "\n", "See [position functions reference](https://lets-plot.org/kotlin/api-reference/-lets--plot--kotlin/org.jetbrains.letsPlot.pos/index.html)\n", "for more information about position adjustments.\n", "\n", "### Features affecting the entire plot\n", "\n", "#### Scales\n", "\n", "Enables choosing a reasonable scale for each mapped variable depending on the variable attributes. Override default scales to tweak\n", "details like the axis labels or legend keys, or to use a completely different translation from data to aesthetic.\n", "For example, to override the fill color on the histogram:\n", "\n", "`p + geomHistogram() + scaleFillContinuous(\"red\", \"green\")`\n", "\n", "See the list of the available `scale` methods in the [scale reference](https://lets-plot.org/kotlin/api-reference/-lets--plot--kotlin/org.jetbrains.letsPlot.scale/index.html)\n", "\n", "#### Coordinated system\n", "\n", "The coordinate system determines how the x and y aesthetics combine to position elements in the plot.\n", "For example, to override the default X and Y ratio:\n", "\n", "`p + coordFixed(ratio=2)`\n", "\n", "See the list of the available methods in [coordinates reference](https://lets-plot.org/kotlin/api-reference/-lets--plot--kotlin/org.jetbrains.letsPlot.coord/index.html)\n", "\n", "#### Legend\n", "The axes and legends help users interpret plots.\n", "Use the `guide` methods or the `guide` argument of the `scale` method to customize the legend.\n", "For example, to define the number of columns in the legend:\n", "\n", "`p + scaleColorDiscrete(guide=guideLegend(ncol=2))`\n", "\n", "See more information about the `guideColorbar, guideLegend` functions in the [scale reference](https://lets-plot.org/kotlin/api-reference/-lets--plot--kotlin/org.jetbrains.letsPlot.scale/index.html)\n", "\n", "Adjust legend location on plot using the `theme` legendPosition, legendJustification and legendDirection methods, see:\n", "[theme reference](https://lets-plot.org/kotlin/api-reference/-lets--plot--kotlin/org.jetbrains.letsPlot.themes/index.html)\n", "\n", "#### Sampling\n", "\n", "Sampling is a special technique of data transformation built into Lets-Plot and it is applied after stat transformation.\n", "Sampling helps prevents UI freezes and out-of-memory crashes when attempting to plot an excessively large number of geometries.\n", "By default, the technique applies automatically when the data volume exceeds a certain threshold.\n", "The `samplingNone` value disables any sampling for the given layer. The sampling methods can be chained together using the + operator.\n", "\n", "Available methods:\n", "- `samplingRandomStratified`: randomly selects points from each group proportionally to the group size but also ensures\n", "that each group is represented by at least a specified minimum number of points.\n", "- `samplingRandom`: selects data points at randomly chosen indices without replacement.\n", "- `samplingPick`: analyses X-values and selects all points which X-values get in the set of first `n` X-values found in the population.\n", "- `samplingSystematic`: selects data points at evenly distributed indices.\n", "- `samplingCertexDP`, `samplingVertexVW`: simplifies plotting of polygons.\n", "There is a choice of two implementation algorithms: Douglas-Peucker (`DP`) and\n", "Visvalingam-Whyatt (`VW`).\n", "\n", "For more details, see the [sampling reference](https://lets-plot.org/kotlin/api-reference/-lets--plot--kotlin/org.jetbrains.letsPlot.sampling/index.html)." ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "<a name=\"GSG\" id=\"gsg\"></a>\n", "### Getting started\n", "\n", "Let's plot a point chart built using the mpg dataset.\n", "\n", "Create the `DataFrame` object and retrieve the data." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "pycharm": { "is_executing": false, "name": "#%%\n" } }, "outputs": [ { "data": { "text/html": [ " <div id=\"wTNvDm\"></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.3.3/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(\"wTNvDm\").appendChild(div);\n", " };\n", " var e = document.getElementById(\"wTNvDm\");\n", " e.appendChild(script);\n", " })();\n", " </script>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%useLatestDescriptors\n", "%use lets-plot\n", "@file:DependsOn(\"com.github.doyaaaaaken:kotlin-csv-jvm:0.7.3\")\n", "\n", "import com.github.doyaaaaaken.kotlincsv.client.*\n", "\n", "val csvData = java.io.File(\"mpg.csv\")\n", "\n", "val mpg: List<Map<String, String>> = CsvReader().readAllWithHeader(csvData)\n", "\n", "fun col(name: String, discrete: Boolean=false): List<*> {\n", " return mpg.map {\n", " val v = it[name]\n", " if(discrete) v else v?.toDouble()\n", " }\n", "}\n", "\n", "val df = mapOf(\n", " \"displ\" to col(\"displ\"),\n", " \"hwy\" to col(\"hwy\"),\n", " \"cyl\" to col(\"cyl\"),\n", " \"index\" to col(\"\"),\n", " \"cty\" to col(\"cty\"),\n", " \"drv\" to col(\"drv\", true),\n", " \"year\" to col(\"year\")\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot the basic point chart." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Perform the following aesthetic mappings:\n", " - `x` = displ (the **displ** column of the dataframe)\n", " - `y` = hwy (the **hwy** column of the dataframe)\n", " - `color` = cyl (the **cyl** column of the dataframe)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "pycharm": { "is_executing": false, "name": "#%%\n" } }, "outputs": [ { "data": { "text/html": [ " <div id=\"RpoXVU\"></div>\n", " <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n", " (function() {\n", " var plotSpec={\n", "\"mapping\":{\n", "\"x\":\"displ\",\n", "\"y\":\"hwy\",\n", "\"color\":\"cyl\"\n", "},\n", "\"data\":{\n", "},\n", "\"kind\":\"plot\",\n", "\"scales\":[],\n", "\"layers\":[{\n", "\"mapping\":{\n", "},\n", "\"stat\":\"identity\",\n", "\"data\":{\n", "\"cyl\":[4.0,4.0,4.0,4.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,6.0,6.0,6.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,4.0,4.0,6.0,6.0,6.0,4.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,8.0,8.0,8.0,8.0,8.0,6.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,6.0,6.0,6.0,6.0,8.0,8.0,6.0,6.0,8.0,8.0,8.0,8.0,8.0,6.0,6.0,6.0,6.0,8.0,8.0,8.0,8.0,8.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,6.0,6.0,6.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,6.0,6.0,8.0,8.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,8.0,6.0,6.0,6.0,6.0,8.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,8.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,4.0,8.0,8.0,4.0,4.0,4.0,6.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,6.0,4.0,4.0,4.0,4.0,4.0,5.0,5.0,6.0,6.0,4.0,4.0,4.0,4.0,5.0,5.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0],\n", "\"displ\":[1.8,1.8,2.0,2.0,2.8,2.8,3.1,1.8,1.8,2.0,2.0,2.8,2.8,3.1,3.1,2.8,3.1,4.2,5.3,5.3,5.3,5.7,6.0,5.7,5.7,6.2,6.2,7.0,5.3,5.3,5.7,6.5,2.4,2.4,3.1,3.5,3.6,2.4,3.0,3.3,3.3,3.3,3.3,3.3,3.8,3.8,3.8,4.0,3.7,3.7,3.9,3.9,4.7,4.7,4.7,5.2,5.2,3.9,4.7,4.7,4.7,5.2,5.7,5.9,4.7,4.7,4.7,4.7,4.7,4.7,5.2,5.2,5.7,5.9,4.6,5.4,5.4,4.0,4.0,4.0,4.0,4.6,5.0,4.2,4.2,4.6,4.6,4.6,5.4,5.4,3.8,3.8,4.0,4.0,4.6,4.6,4.6,4.6,5.4,1.6,1.6,1.6,1.6,1.6,1.8,1.8,1.8,2.0,2.4,2.4,2.4,2.4,2.5,2.5,3.3,2.0,2.0,2.0,2.0,2.7,2.7,2.7,3.0,3.7,4.0,4.7,4.7,4.7,5.7,6.1,4.0,4.2,4.4,4.6,5.4,5.4,5.4,4.0,4.0,4.6,5.0,2.4,2.4,2.5,2.5,3.5,3.5,3.0,3.0,3.5,3.3,3.3,4.0,5.6,3.1,3.8,3.8,3.8,5.3,2.5,2.5,2.5,2.5,2.5,2.5,2.2,2.2,2.5,2.5,2.5,2.5,2.5,2.5,2.7,2.7,3.4,3.4,4.0,4.7,2.2,2.2,2.4,2.4,3.0,3.0,3.5,2.2,2.2,2.4,2.4,3.0,3.0,3.3,1.8,1.8,1.8,1.8,1.8,4.7,5.7,2.7,2.7,2.7,3.4,3.4,4.0,4.0,2.0,2.0,2.0,2.0,2.8,1.9,2.0,2.0,2.0,2.0,2.5,2.5,2.8,2.8,1.9,1.9,2.0,2.0,2.5,2.5,1.8,1.8,2.0,2.0,2.8,2.8,3.6],\n", "\"hwy\":[29.0,29.0,31.0,30.0,26.0,26.0,27.0,26.0,25.0,28.0,27.0,25.0,25.0,25.0,25.0,24.0,25.0,23.0,20.0,15.0,20.0,17.0,17.0,26.0,23.0,26.0,25.0,24.0,19.0,14.0,15.0,17.0,27.0,30.0,26.0,29.0,26.0,24.0,24.0,22.0,22.0,24.0,24.0,17.0,22.0,21.0,23.0,23.0,19.0,18.0,17.0,17.0,19.0,19.0,12.0,17.0,15.0,17.0,17.0,12.0,17.0,16.0,18.0,15.0,16.0,12.0,17.0,17.0,16.0,12.0,15.0,16.0,17.0,15.0,17.0,17.0,18.0,17.0,19.0,17.0,19.0,19.0,17.0,17.0,17.0,16.0,16.0,17.0,15.0,17.0,26.0,25.0,26.0,24.0,21.0,22.0,23.0,22.0,20.0,33.0,32.0,32.0,29.0,32.0,34.0,36.0,36.0,29.0,26.0,27.0,30.0,31.0,26.0,26.0,28.0,26.0,29.0,28.0,27.0,24.0,24.0,24.0,22.0,19.0,20.0,17.0,12.0,19.0,18.0,14.0,15.0,18.0,18.0,15.0,17.0,16.0,18.0,17.0,19.0,19.0,17.0,29.0,27.0,31.0,32.0,27.0,26.0,26.0,25.0,25.0,17.0,17.0,20.0,18.0,26.0,26.0,27.0,28.0,25.0,25.0,24.0,27.0,25.0,26.0,23.0,26.0,26.0,26.0,26.0,25.0,27.0,25.0,27.0,20.0,20.0,19.0,17.0,20.0,17.0,29.0,27.0,31.0,31.0,26.0,26.0,28.0,27.0,29.0,31.0,31.0,26.0,26.0,27.0,30.0,33.0,35.0,37.0,35.0,15.0,18.0,20.0,20.0,22.0,17.0,19.0,18.0,20.0,29.0,26.0,29.0,29.0,24.0,44.0,29.0,26.0,29.0,29.0,29.0,29.0,23.0,24.0,44.0,41.0,29.0,26.0,28.0,29.0,29.0,29.0,28.0,29.0,26.0,26.0,26.0]\n", "},\n", "\"position\":\"identity\",\n", "\"geom\":\"point\"\n", "}]\n", "};\n", " var plotContainer = document.getElementById(\"RpoXVU\");\n", " window.letsPlotCall(function() {{\n", " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n", " }});\n", " })();\n", " </script>" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// Mapping\n", "letsPlot(df) {x = \"displ\"; y = \"hwy\"; color = \"cyl\"} + geomPoint(df)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apply statistical data transformation to count the number of cases at each x position." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "pycharm": { "is_executing": false, "name": "#%%\n" } }, "outputs": [ { "data": { "text/html": [ " <div id=\"Qfd25O\"></div>\n", " <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n", " (function() {\n", " var plotSpec={\n", "\"mapping\":{\n", "},\n", "\"data\":{\n", "},\n", "\"kind\":\"plot\",\n", "\"scales\":[],\n", "\"layers\":[{\n", "\"mapping\":{\n", "\"x\":\"displ\",\n", "\"color\":\"..count..\",\n", "\"size\":\"..count..\"\n", "},\n", "\"stat\":\"count\",\n", "\"data\":{\n", "\"..count..\":[14.0,21.0,10.0,6.0,4.0,6.0,8.0,1.0,2.0,1.0,1.0,13.0,5.0,2.0,8.0,9.0,8.0,15.0,3.0,3.0,17.0,5.0,2.0,11.0,8.0,2.0,5.0,20.0,8.0,1.0,1.0,1.0,6.0,4.0,3.0],\n", "\"displ\":[1.8,2.0,2.8,3.1,4.2,5.3,5.7,6.0,6.2,7.0,6.5,2.4,3.5,3.6,3.0,3.3,3.8,4.0,3.7,3.9,4.7,5.2,5.9,4.6,5.4,5.0,1.6,2.5,2.7,6.1,4.4,5.6,2.2,3.4,1.9]\n", "},\n", "\"position\":\"identity\",\n", "\"geom\":\"point\"\n", "}]\n", "};\n", " var plotContainer = document.getElementById(\"Qfd25O\");\n", " window.letsPlotCall(function() {{\n", " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n", " }});\n", " })();\n", " </script>" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot(df)\n", "p + geomPoint(df, stat = Stat.count()) {x = \"displ\"; color = \"..count..\"; size = \"..count..\"}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Change the pallete and the legend, add the title. " ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "pycharm": { "is_executing": false, "name": "#%%\n" } }, "outputs": [ { "data": { "text/html": [ " <div id=\"RiCH8Z\"></div>\n", " <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n", " (function() {\n", " var plotSpec={\n", "\"ggtitle\":{\n", "\"text\":\"Displacement by horsepower\"\n", "},\n", "\"mapping\":{\n", "\"x\":\"displ\",\n", "\"y\":\"hwy\",\n", "\"color\":\"cyl\"\n", "},\n", "\"data\":{\n", "},\n", "\"kind\":\"plot\",\n", "\"scales\":[{\n", "\"aesthetic\":\"color\",\n", "\"scale_mapper_kind\":\"color_gradient\",\n", "\"high\":\"green\",\n", "\"low\":\"red\",\n", "\"guide\":{\n", "\"name\":\"legend\",\n", "\"ncol\":2\n", "}\n", "}],\n", "\"layers\":[{\n", "\"mapping\":{\n", "},\n", "\"stat\":\"identity\",\n", "\"data\":{\n", "\"cyl\":[4.0,4.0,4.0,4.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,6.0,6.0,6.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,4.0,4.0,6.0,6.0,6.0,4.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,8.0,8.0,8.0,8.0,8.0,6.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,6.0,6.0,6.0,6.0,8.0,8.0,6.0,6.0,8.0,8.0,8.0,8.0,8.0,6.0,6.0,6.0,6.0,8.0,8.0,8.0,8.0,8.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,6.0,6.0,6.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,8.0,6.0,6.0,8.0,8.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,8.0,6.0,6.0,6.0,6.0,8.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,8.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,4.0,8.0,8.0,4.0,4.0,4.0,6.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,6.0,4.0,4.0,4.0,4.0,4.0,5.0,5.0,6.0,6.0,4.0,4.0,4.0,4.0,5.0,5.0,4.0,4.0,4.0,4.0,6.0,6.0,6.0],\n", "\"displ\":[1.8,1.8,2.0,2.0,2.8,2.8,3.1,1.8,1.8,2.0,2.0,2.8,2.8,3.1,3.1,2.8,3.1,4.2,5.3,5.3,5.3,5.7,6.0,5.7,5.7,6.2,6.2,7.0,5.3,5.3,5.7,6.5,2.4,2.4,3.1,3.5,3.6,2.4,3.0,3.3,3.3,3.3,3.3,3.3,3.8,3.8,3.8,4.0,3.7,3.7,3.9,3.9,4.7,4.7,4.7,5.2,5.2,3.9,4.7,4.7,4.7,5.2,5.7,5.9,4.7,4.7,4.7,4.7,4.7,4.7,5.2,5.2,5.7,5.9,4.6,5.4,5.4,4.0,4.0,4.0,4.0,4.6,5.0,4.2,4.2,4.6,4.6,4.6,5.4,5.4,3.8,3.8,4.0,4.0,4.6,4.6,4.6,4.6,5.4,1.6,1.6,1.6,1.6,1.6,1.8,1.8,1.8,2.0,2.4,2.4,2.4,2.4,2.5,2.5,3.3,2.0,2.0,2.0,2.0,2.7,2.7,2.7,3.0,3.7,4.0,4.7,4.7,4.7,5.7,6.1,4.0,4.2,4.4,4.6,5.4,5.4,5.4,4.0,4.0,4.6,5.0,2.4,2.4,2.5,2.5,3.5,3.5,3.0,3.0,3.5,3.3,3.3,4.0,5.6,3.1,3.8,3.8,3.8,5.3,2.5,2.5,2.5,2.5,2.5,2.5,2.2,2.2,2.5,2.5,2.5,2.5,2.5,2.5,2.7,2.7,3.4,3.4,4.0,4.7,2.2,2.2,2.4,2.4,3.0,3.0,3.5,2.2,2.2,2.4,2.4,3.0,3.0,3.3,1.8,1.8,1.8,1.8,1.8,4.7,5.7,2.7,2.7,2.7,3.4,3.4,4.0,4.0,2.0,2.0,2.0,2.0,2.8,1.9,2.0,2.0,2.0,2.0,2.5,2.5,2.8,2.8,1.9,1.9,2.0,2.0,2.5,2.5,1.8,1.8,2.0,2.0,2.8,2.8,3.6],\n", "\"hwy\":[29.0,29.0,31.0,30.0,26.0,26.0,27.0,26.0,25.0,28.0,27.0,25.0,25.0,25.0,25.0,24.0,25.0,23.0,20.0,15.0,20.0,17.0,17.0,26.0,23.0,26.0,25.0,24.0,19.0,14.0,15.0,17.0,27.0,30.0,26.0,29.0,26.0,24.0,24.0,22.0,22.0,24.0,24.0,17.0,22.0,21.0,23.0,23.0,19.0,18.0,17.0,17.0,19.0,19.0,12.0,17.0,15.0,17.0,17.0,12.0,17.0,16.0,18.0,15.0,16.0,12.0,17.0,17.0,16.0,12.0,15.0,16.0,17.0,15.0,17.0,17.0,18.0,17.0,19.0,17.0,19.0,19.0,17.0,17.0,17.0,16.0,16.0,17.0,15.0,17.0,26.0,25.0,26.0,24.0,21.0,22.0,23.0,22.0,20.0,33.0,32.0,32.0,29.0,32.0,34.0,36.0,36.0,29.0,26.0,27.0,30.0,31.0,26.0,26.0,28.0,26.0,29.0,28.0,27.0,24.0,24.0,24.0,22.0,19.0,20.0,17.0,12.0,19.0,18.0,14.0,15.0,18.0,18.0,15.0,17.0,16.0,18.0,17.0,19.0,19.0,17.0,29.0,27.0,31.0,32.0,27.0,26.0,26.0,25.0,25.0,17.0,17.0,20.0,18.0,26.0,26.0,27.0,28.0,25.0,25.0,24.0,27.0,25.0,26.0,23.0,26.0,26.0,26.0,26.0,25.0,27.0,25.0,27.0,20.0,20.0,19.0,17.0,20.0,17.0,29.0,27.0,31.0,31.0,26.0,26.0,28.0,27.0,29.0,31.0,31.0,26.0,26.0,27.0,30.0,33.0,35.0,37.0,35.0,15.0,18.0,20.0,20.0,22.0,17.0,19.0,18.0,20.0,29.0,26.0,29.0,29.0,24.0,44.0,29.0,26.0,29.0,29.0,29.0,29.0,23.0,24.0,44.0,41.0,29.0,26.0,28.0,29.0,29.0,29.0,28.0,29.0,26.0,26.0,26.0]\n", "},\n", "\"position\":\"nudge\",\n", "\"geom\":\"point\"\n", "}]\n", "};\n", " var plotContainer = document.getElementById(\"RiCH8Z\");\n", " window.letsPlotCall(function() {{\n", " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n", " }});\n", " })();\n", " </script>" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot(df) {x = \"displ\"; y = \"hwy\"; color = \"cyl\"}\n", "p + \n", " geomPoint(df, position = positionNudge()) + \n", " scaleGradient(\"color\", low = \"red\", high = \"green\", guide = guideLegend(ncol=2)) + \n", " ggtitle(\"Displacement by horsepower\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apply the randomly stratified sampling to select points from each group proportionally \n", "to the group size." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false }, "pycharm": { "is_executing": false, "name": "#%%\n" } }, "outputs": [ { "data": { "text/html": [ " <div id=\"THmTYS\"></div>\n", " <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n", " (function() {\n", " var plotSpec={\n", "\"mapping\":{\n", "\"x\":\"displ\",\n", "\"y\":\"hwy\",\n", "\"color\":\"cyl\"\n", "},\n", "\"data\":{\n", "},\n", "\"kind\":\"plot\",\n", "\"scales\":[{\n", "\"aesthetic\":\"color\",\n", "\"scale_mapper_kind\":\"color_gradient\",\n", "\"high\":\"pink\",\n", "\"low\":\"blue\",\n", "\"guide\":{\n", "\"name\":\"legend\",\n", "\"ncol\":2\n", "}\n", "}],\n", "\"layers\":[{\n", "\"mapping\":{\n", "},\n", "\"stat\":\"identity\",\n", "\"data\":{\n", "\"cyl\":[4.0,6.0,8.0,8.0,8.0,8.0,6.0,6.0,6.0,8.0,6.0,8.0,8.0,8.0,8.0,4.0,4.0,4.0,4.0,4.0,6.0,8.0,4.0,4.0,6.0,6.0,6.0,4.0,4.0,4.0,4.0,6.0,4.0,6.0,4.0,4.0,4.0,4.0,4.0,6.0],\n", "\"displ\":[2.0,2.8,5.3,5.3,5.7,5.7,3.8,4.0,3.7,4.7,3.9,4.7,5.7,4.6,4.6,1.8,1.8,2.4,2.0,2.0,2.7,4.7,2.4,2.5,3.5,3.0,3.0,2.5,2.5,2.5,2.5,3.4,2.2,3.0,2.2,1.8,2.7,2.0,2.0,2.8],\n", "\"hwy\":[31.0,26.0,20.0,15.0,17.0,15.0,21.0,23.0,18.0,12.0,17.0,12.0,17.0,16.0,17.0,34.0,36.0,31.0,26.0,28.0,24.0,17.0,29.0,31.0,27.0,26.0,25.0,25.0,24.0,26.0,27.0,19.0,27.0,26.0,29.0,30.0,20.0,26.0,29.0,26.0]\n", "},\n", "\"sampling\":{\n", "\"n\":40.0,\n", "\"name\":\"random_stratified\"\n", "},\n", "\"position\":\"nudge\",\n", "\"geom\":\"point\"\n", "}],\n", "\"computation_messages\":[\"sampling_random_stratified(n=40) was applied to [point/identity stat] layer\"]\n", "};\n", " var plotContainer = document.getElementById(\"THmTYS\");\n", " window.letsPlotCall(function() {{\n", " LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer);\n", " }});\n", " })();\n", " </script>" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val p = letsPlot(df) {x = \"displ\"; y = \"hwy\"; color = \"cyl\"}\n", "p + geomPoint(\n", " data=df, position = positionNudge(), \n", " sampling = samplingRandomStratified(40)\n", " ) + scaleGradient(\n", " \"color\", low = \"blue\", high = \"pink\",\n", " guide = guideLegend(ncol=2)\n", " )" ] } ], "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": 4 }