{ "cells": [ { "cell_type": "markdown", "id": "f78cfe2b", "metadata": {}, "source": [ "# Stackable Position Adjustments" ] }, { "cell_type": "markdown", "id": "3ab13984", "metadata": {}, "source": [ "## Table of Contents\n", "\n", "1. [Default Presentation of `'stack'` and `'fill'`](#1.-Default-Presentation-of-'stack'-and-'fill')\n", "\n", "2. [Stacking Order](#2.-Stacking-Order)\n", "\n", "3. [Other Geometries](#3.-Other-Geometries)\n", "\n", "4. [Parameter `vjust`](#4.-Parameter-vjust)\n", "\n", "5. [Parameter `mode`](#5.-Parameter-mode)\n", "\n", "6. [Negative Values](#6.-Negative-Values)" ] }, { "cell_type": "code", "execution_count": 1, "id": "1572041f", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:58.933558Z", "iopub.status.busy": "2025-11-05T13:49:58.933472Z", "iopub.status.idle": "2025-11-05T13:49:58.936770Z", "shell.execute_reply": "2025-11-05T13:49:58.936518Z" } }, "outputs": [], "source": [ "import pandas as pd\n", "\n", "from lets_plot import *" ] }, { "cell_type": "code", "execution_count": 2, "id": "24920b1e", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:58.938032Z", "iopub.status.busy": "2025-11-05T13:49:58.937957Z", "iopub.status.idle": "2025-11-05T13:49:58.939956Z", "shell.execute_reply": "2025-11-05T13:49:58.939715Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "LetsPlot.setup_html()" ] }, { "cell_type": "code", "execution_count": 3, "id": "c30f9d65", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:58.940756Z", "iopub.status.busy": "2025-11-05T13:49:58.940684Z", "iopub.status.idle": "2025-11-05T13:49:59.027103Z", "shell.execute_reply": "2025-11-05T13:49:59.026708Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(234, 12)\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Unnamed: 0manufacturermodeldisplyearcyltransdrvctyhwyflclass
01audia41.819994auto(l5)f1829pcompact
12audia41.819994manual(m5)f2129pcompact
23audia42.020084manual(m6)f2031pcompact
34audia42.020084auto(av)f2130pcompact
45audia42.819996auto(l5)f1626pcompact
\n", "
" ], "text/plain": [ " Unnamed: 0 manufacturer model displ year cyl trans drv cty hwy \\\n", "0 1 audi a4 1.8 1999 4 auto(l5) f 18 29 \n", "1 2 audi a4 1.8 1999 4 manual(m5) f 21 29 \n", "2 3 audi a4 2.0 2008 4 manual(m6) f 20 31 \n", "3 4 audi a4 2.0 2008 4 auto(av) f 21 30 \n", "4 5 audi a4 2.8 1999 6 auto(l5) f 16 26 \n", "\n", " fl class \n", "0 p compact \n", "1 p compact \n", "2 p compact \n", "3 p compact \n", "4 p compact " ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv(\"https://raw.githubusercontent.com/JetBrains/lets-plot-docs/master/data/mpg.csv\")\n", "print(df.shape)\n", "df.head()" ] }, { "cell_type": "markdown", "id": "45c88372", "metadata": {}, "source": [ "#### 1. Default Presentation of `'stack'` and `'fill'`\n", "\n", "Stacking is the default behaviour for most area plots.\n", "Fill makes it easier to compare proportions." ] }, { "cell_type": "code", "execution_count": 4, "id": "aa2c468e", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.028029Z", "iopub.status.busy": "2025-11-05T13:49:59.027957Z", "iopub.status.idle": "2025-11-05T13:49:59.059667Z", "shell.execute_reply": "2025-11-05T13:49:59.059409Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"drv\", fill=\"year\", group=\"year\")) + \\\n", " geom_bar() + \\\n", " scale_fill_discrete(format=\"d\") + \\\n", " ggtitle(\"bar: position='stack' (default)\")" ] }, { "cell_type": "code", "execution_count": 5, "id": "02960166", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.060405Z", "iopub.status.busy": "2025-11-05T13:49:59.060331Z", "iopub.status.idle": "2025-11-05T13:49:59.065774Z", "shell.execute_reply": "2025-11-05T13:49:59.065526Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"drv\", fill=\"year\", group=\"year\")) + \\\n", " geom_bar(position='fill') + \\\n", " scale_fill_discrete(format=\"d\") + \\\n", " ggtitle(\"bar: position='fill'\")" ] }, { "cell_type": "code", "execution_count": 6, "id": "2769dac6", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.066477Z", "iopub.status.busy": "2025-11-05T13:49:59.066402Z", "iopub.status.idle": "2025-11-05T13:49:59.071847Z", "shell.execute_reply": "2025-11-05T13:49:59.071610Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"hwy\", fill=\"year\", group=\"year\")) + \\\n", " geom_histogram() + \\\n", " scale_fill_discrete(format=\"d\") + \\\n", " ggtitle(\"histogram: position='stack' (default)\")" ] }, { "cell_type": "code", "execution_count": 7, "id": "7a0cd8f3", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.072492Z", "iopub.status.busy": "2025-11-05T13:49:59.072424Z", "iopub.status.idle": "2025-11-05T13:49:59.077696Z", "shell.execute_reply": "2025-11-05T13:49:59.077459Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"hwy\", fill=\"year\", group=\"year\")) + \\\n", " geom_histogram(position='fill') + \\\n", " scale_fill_discrete(format=\"d\") + \\\n", " ggtitle(\"histogram: position='fill'\")" ] }, { "cell_type": "code", "execution_count": 8, "id": "abe5c551", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.078425Z", "iopub.status.busy": "2025-11-05T13:49:59.078336Z", "iopub.status.idle": "2025-11-05T13:49:59.095281Z", "shell.execute_reply": "2025-11-05T13:49:59.095089Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"hwy\", fill=\"year\", group=\"year\")) + \\\n", " geom_area(stat='density', color=\"black\") + \\\n", " scale_fill_discrete(format=\"d\") + \\\n", " ggtitle(\"area: position='stack' (default)\")" ] }, { "cell_type": "code", "execution_count": 9, "id": "959c55a8", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.096248Z", "iopub.status.busy": "2025-11-05T13:49:59.096177Z", "iopub.status.idle": "2025-11-05T13:49:59.111845Z", "shell.execute_reply": "2025-11-05T13:49:59.111651Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"hwy\", fill=\"year\", group=\"year\")) + \\\n", " geom_area(stat='density', position='fill', color=\"black\") + \\\n", " scale_fill_discrete(format=\"d\") + \\\n", " ggtitle(\"area: position='fill'\")" ] }, { "cell_type": "markdown", "id": "d12ed7c6", "metadata": {}, "source": [ "#### 2. Stacking Order\n", "\n", "Control the stacking order by changing the `order` parameter of the `as_discrete()` function." ] }, { "cell_type": "code", "execution_count": 10, "id": "b9022666", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.112829Z", "iopub.status.busy": "2025-11-05T13:49:59.112756Z", "iopub.status.idle": "2025-11-05T13:49:59.133183Z", "shell.execute_reply": "2025-11-05T13:49:59.132988Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"hwy\")) + \\\n", " geom_area(aes(fill=as_discrete(\"drv\")), stat='density', color=\"black\") + \\\n", " ggtitle(\"Default order of drive types\")" ] }, { "cell_type": "code", "execution_count": 11, "id": "f2ac8383", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.134166Z", "iopub.status.busy": "2025-11-05T13:49:59.134088Z", "iopub.status.idle": "2025-11-05T13:49:59.153128Z", "shell.execute_reply": "2025-11-05T13:49:59.152937Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"hwy\")) + \\\n", " geom_area(aes(fill=as_discrete(\"drv\", order=-1)), stat='density', color=\"black\") + \\\n", " ggtitle(\"Backward order of drive types\")" ] }, { "cell_type": "markdown", "id": "d1be5ff4", "metadata": {}, "source": [ "#### 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": 12, "id": "9269044d", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.154210Z", "iopub.status.busy": "2025-11-05T13:49:59.154137Z", "iopub.status.idle": "2025-11-05T13:49:59.160195Z", "shell.execute_reply": "2025-11-05T13:49:59.160014Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"drv\", color=\"year\", group=\"year\")) + \\\n", " geom_line(stat='count', position='stack') + \\\n", " geom_point(stat='count', position='stack') + \\\n", " scale_color_discrete(format=\"d\") + \\\n", " ggtitle(\"Line and point\")" ] }, { "cell_type": "code", "execution_count": 13, "id": "6fea6dd8", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.161197Z", "iopub.status.busy": "2025-11-05T13:49:59.161126Z", "iopub.status.idle": "2025-11-05T13:49:59.167360Z", "shell.execute_reply": "2025-11-05T13:49:59.167187Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"drv\")) + \\\n", " geom_area(aes(fill=\"year\", group=\"year\"), stat='count', position='stack', color=\"black\") + \\\n", " geom_line(aes(group=\"year\"), stat='count', position='stack', color=\"black\") + \\\n", " scale_fill_discrete(format=\"d\") + \\\n", " ggtitle(\"Area and line\")" ] }, { "cell_type": "markdown", "id": "83f4120e", "metadata": {}, "source": [ "#### 4. Parameter `vjust`\n", "\n", "The `vjust` argument of `position_stack()` is used to move the location of plot elements vertically (vjust stands for vertical adjustment)." ] }, { "cell_type": "code", "execution_count": 14, "id": "56c79857", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.168317Z", "iopub.status.busy": "2025-11-05T13:49:59.168248Z", "iopub.status.idle": "2025-11-05T13:49:59.173818Z", "shell.execute_reply": "2025-11-05T13:49:59.173642Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"drv\")) + \\\n", " geom_area(aes(fill=\"year\", group=\"year\"), stat='count', \\\n", " position='stack', color=\"black\") + \\\n", " geom_label(aes(label=\"..count..\", group=\"year\"), stat='count', \\\n", " position='stack', color=\"black\") + \\\n", " scale_fill_discrete(format=\"d\") + \\\n", " ggtitle(\"vjust=1 (default)\")" ] }, { "cell_type": "code", "execution_count": 15, "id": "689596f8", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.175073Z", "iopub.status.busy": "2025-11-05T13:49:59.175004Z", "iopub.status.idle": "2025-11-05T13:49:59.180747Z", "shell.execute_reply": "2025-11-05T13:49:59.180575Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"drv\")) + \\\n", " geom_area(aes(fill=\"year\", group=\"year\"), stat='count', \\\n", " position='stack', color=\"black\") + \\\n", " geom_label(aes(label=\"..count..\", group=\"year\"), stat='count', \\\n", " position=position_stack(vjust=.5), color=\"black\") + \\\n", " scale_fill_discrete(format=\"d\") + \\\n", " ggtitle(\"vjust=0.5\")" ] }, { "cell_type": "markdown", "id": "fba93796", "metadata": {}, "source": [ "#### 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='identity'`.\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": 16, "id": "4d1e5c20", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.182030Z", "iopub.status.busy": "2025-11-05T13:49:59.181960Z", "iopub.status.idle": "2025-11-05T13:49:59.186947Z", "shell.execute_reply": "2025-11-05T13:49:59.186775Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"hwy\", color=\"class\")) + \\\n", " geom_point(y=1, position=position_stack()) + \\\n", " coord_fixed() + ylim(1, 35) + \\\n", " ggtitle(\"mode='groups' (default)\")" ] }, { "cell_type": "code", "execution_count": 17, "id": "de17d673", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.188028Z", "iopub.status.busy": "2025-11-05T13:49:59.187954Z", "iopub.status.idle": "2025-11-05T13:49:59.192932Z", "shell.execute_reply": "2025-11-05T13:49:59.192759Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(df, aes(x=\"hwy\", color=\"class\")) + \\\n", " geom_point(y=1, position=position_stack(mode='all')) + \\\n", " coord_fixed() + ylim(1, 35) + \\\n", " ggtitle(\"mode='all'\")" ] }, { "cell_type": "markdown", "id": "ba6cd973", "metadata": {}, "source": [ "#### 6. Negative Values\n", "\n", "Stacking supports positive and negative shifts of the objects separately." ] }, { "cell_type": "code", "execution_count": 18, "id": "270a9a1e", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.194193Z", "iopub.status.busy": "2025-11-05T13:49:59.194123Z", "iopub.status.idle": "2025-11-05T13:49:59.195506Z", "shell.execute_reply": "2025-11-05T13:49:59.195330Z" } }, "outputs": [], "source": [ "data = {\n", " \"x\": [0, 1, 2, 0, 1, 2],\n", " \"y\": [4, 2, 3, 0, 1, -1],\n", " \"g\": [\"a\", \"a\", \"a\", \"b\", \"b\", \"b\"],\n", "}" ] }, { "cell_type": "code", "execution_count": 19, "id": "b3588ea3", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.196474Z", "iopub.status.busy": "2025-11-05T13:49:59.196405Z", "iopub.status.idle": "2025-11-05T13:49:59.199002Z", "shell.execute_reply": "2025-11-05T13:49:59.198829Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(data, aes(\"x\", \"y\", fill=\"g\")) + \\\n", " geom_bar(stat='identity') + \\\n", " geom_hline(yintercept=0, color=\"black\")" ] }, { "cell_type": "code", "execution_count": 20, "id": "5e4750bb", "metadata": { "execution": { "iopub.execute_input": "2025-11-05T13:49:59.199600Z", "iopub.status.busy": "2025-11-05T13:49:59.199531Z", "iopub.status.idle": "2025-11-05T13:49:59.202439Z", "shell.execute_reply": "2025-11-05T13:49:59.202269Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(data, aes(\"x\", \"y\")) + \\\n", " geom_bar(aes(fill=\"g\"), stat='identity', position='fill') + \\\n", " geom_label(aes(label=\"g\", group=\"g\"), stat='identity', \\\n", " position=position_fill(vjust=.5)) + \\\n", " geom_hline(yintercept=0, color=\"black\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.13" } }, "nbformat": 4, "nbformat_minor": 5 }