{ "cells": [ { "cell_type": "markdown", "id": "bd6be7c5", "metadata": {}, "source": [ "# Lollipop Plot\n", "\n", "A lollipop plot displays each element of a dataset as a segment and a circle. It is usually combined with the `count` stat, and is especially useful when you have several bars of the same height." ] }, { "cell_type": "markdown", "id": "c5f3557a", "metadata": {}, "source": [ "1. [Parameters `size`, `stroke` and `linewidth`](#stroke)\n", "\n", "2. [Parameter `fatten`](#fatten)\n", "\n", "3. [Horizontal Sticks](#direction)\n", "\n", "4. [Sloped Baseline](#slope)\n", "\n", "5. [Parameter `stat`](#stat)\n", "\n", "6. [Lollipops in Marginal Layer](#ggmarginal)\n", "\n", "7. [Lollipops and a Regression Line](#slope_and_intercept)\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "ba071491", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%useLatestDescriptors\n", "%use lets-plot" ] }, { "cell_type": "code", "execution_count": 2, "id": "06477cad", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Lets-Plot Kotlin API v.4.4.0. Frontend: Notebook with dynamically loaded JS. Lets-Plot JS v.3.2.0." ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "LetsPlot.getInfo()" ] }, { "cell_type": "code", "execution_count": 3, "id": "66de6718", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%use dataframe" ] }, { "cell_type": "code", "execution_count": 4, "id": "d526d855", "metadata": {}, "outputs": [], "source": [ "import jetbrains.datalore.plot.base.stat.regression.LinearRegression\n", "import kotlin.random.Random" ] }, { "cell_type": "code", "execution_count": 5, "id": "166e457f", "metadata": {}, "outputs": [], "source": [ "val rnd = Random(0)\n", "val data = mapOf(\n", " \"x\" to (-15..14).toList(),\n", " \"y\" to (0..29).map { rnd.nextDouble(1.0, 5.0) },\n", " \"sugar\" to (150..179).toList()\n", ")" ] }, { "cell_type": "code", "execution_count": 6, "id": "75bf0748", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(data) { x = \"x\"; y = \"y\" } + geomLollipop() + ggsize(600, 200)" ] }, { "cell_type": "markdown", "id": "3a401867", "metadata": {}, "source": [ "\n", "\n", "#### 1. Parameters `size`, `stroke` and `linewidth`" ] }, { "cell_type": "code", "execution_count": 7, "id": "3007532a", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val plots = listOf(\n", " letsPlot(data) { x = \"x\"; y = \"y\"; size = \"sugar\" } + \n", " geomLollipop() + ggtitle(\"variable 'size'\"),\n", " letsPlot(data) { x = \"x\"; y = \"y\"; size = \"sugar\"; stroke = \"sugar\" } + \n", " geomLollipop() + ggtitle(\"variable 'size' and 'stroke'\"),\n", " letsPlot(data) { x = \"x\"; y = \"y\"; size = \"sugar\"; linewidth = \"sugar\" } + \n", " geomLollipop() + ggtitle(\"variable 'size' and 'linewidth'\")\n", ")\n", " \n", "gggrid(plots, ncol=1) + ggsize(800, 800)" ] }, { "cell_type": "markdown", "id": "e5d6d73f", "metadata": {}, "source": [ "\n", "\n", "#### 2. Parameter `fatten`" ] }, { "cell_type": "code", "execution_count": 8, "id": "e1de6c92", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gggrid(\n", " listOf(\n", " letsPlot(data) { x = \"x\"; y = \"y\"} + geomLollipop() + ggtitle(\"fatten=2.5 (default)\"),\n", " letsPlot(data) { x = \"x\"; y = \"y\"} + geomLollipop(fatten = 5) + ggtitle(\"fatten=5\"),\n", " )\n", ")" ] }, { "cell_type": "markdown", "id": "89b3fbaa", "metadata": {}, "source": [ "\n", "\n", "#### 3. Horizontal Sticks" ] }, { "cell_type": "code", "execution_count": 9, "id": "f1efe926", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(data) { x = \"y\"; y = \"x\" } + geomLollipop(dir = \"h\")" ] }, { "cell_type": "markdown", "id": "f5fcee23", "metadata": {}, "source": [ "\n", "\n", "#### 4. Sloped Baseline" ] }, { "cell_type": "code", "execution_count": 10, "id": "1fb4fb53", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val slope = 0.5\n", "val intercept = 1\n", "\n", "val abline = letsPlot(data) { x = \"x\"; y = \"y\" } +\n", " geomABLine(intercept = intercept, slope = slope, color = \"black\", linetype = \"dotted\", size = 1.5) + \n", " coordFixed(ylim = -12 to 12)\n", " \n", "gggrid(\n", " listOf(\n", " abline + geomLollipop(intercept = intercept, slope = slope, shape = 21) + ggtitle(\"dir='v' (default)\"),\n", " abline + geomLollipop(intercept = intercept, slope = slope, shape = 21, dir = \"h\") + ggtitle(\"dir='h'\"),\n", " abline + geomLollipop(intercept = intercept, slope = slope, shape = 21, dir = \"s\") + ggtitle(\"dir='s'\"),\n", " )\n", ")" ] }, { "cell_type": "markdown", "id": "36f3fc38", "metadata": {}, "source": [ "\n", "\n", "#### 5. Parameter `stat`" ] }, { "cell_type": "code", "execution_count": 11, "id": "6f895fd5", "metadata": {}, "outputs": [ { "data": { "application/kotlindataframe+json": "{\"nrow\":3,\"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\"}]}", "text/html": [ " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "\n", "

DataFrame: rowsCount = 3, columnsCount = 12

\n", " \n", " \n", " " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val df = DataFrame.readCSV(\"https://raw.githubusercontent.com/JetBrains/lets-plot-docs/master/data/mpg.csv\")\n", "df.head(3)" ] }, { "cell_type": "code", "execution_count": 12, "id": "66fac357", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gggrid(\n", " listOf(\n", " letsPlot(df.toMap()) { x = \"class\" } + geomLollipop(stat = Stat.count()) + ggtitle(\"stat='count'\"),\n", " letsPlot(df.toMap()) { x = \"hwy\" } + geomLollipop(stat = Stat.bin()) + ggtitle(\"stat='bin'\"),\n", " letsPlot(df.toMap()) { x = \"hwy\" } + geomLollipop(stat = Stat.density(n=30)) + ggtitle(\"stat='density'\")\n", " )\n", ")" ] }, { "cell_type": "markdown", "id": "aa9cd80d", "metadata": {}, "source": [ "\n", "\n", "#### 6. Lollipops in Marginal Layer" ] }, { "cell_type": "code", "execution_count": 13, "id": "d17028b4", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "letsPlot(df.toMap()) { x = \"hwy\"; y = \"cty\" } +\n", " geomBin2D(binWidth = 1 to 1) +\n", " ggmarginal(\"r\", size=.2,\n", " layer = geomLollipop(stat = Stat.count(), orientation = \"y\", size = 1) { color = \"..count..\" } )" ] }, { "cell_type": "markdown", "id": "7f91b9f7", "metadata": {}, "source": [ "\n", "\n", "#### 7. Lollipops and a Regression Line" ] }, { "cell_type": "code", "execution_count": 14, "id": "5ce3b9ac", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val xs = df[\"hwy\"].toList().map { (it as Number).toDouble() }\n", "val ys = df[\"cty\"].toList().map { (it as Number).toDouble() }\n", "\n", "fun linearModel(x: Double) = LinearRegression(xs, ys, 0.95).evalX(x).y\n", "\n", "val intercept = linearModel(0.0)\n", "val slope = linearModel(1.0) - intercept\n", "\n", "letsPlot(df.toMap()) { x = \"hwy\"; y = \"cty\" } +\n", " geomSmooth(level = 0.99) + \n", " geomLollipop(slope = slope, intercept = intercept,\n", " size = 1.2, shape = 21, color = \"black\", fill = \"magenta\") +\n", " coordFixed()" ] } ], "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": 5 }