{ "cells": [ { "cell_type": "markdown", "id": "e18c42f4", "metadata": {}, "source": [ "# geom_pie()" ] }, { "cell_type": "markdown", "id": "65348da9", "metadata": {}, "source": [ "A pie chart is a circular statistical graphic, which is divided into slices to illustrate numerical proportion." ] }, { "cell_type": "markdown", "id": "4e5b3651", "metadata": {}, "source": [ "1. [Default presentation](#1.-Default-presentation)\n", "\n", " 1.1. [Basic pie chart](#1.1.-Basic-pie-chart)\n", "\n", " 1.2. [Improve appearance](#1.2.-Improve-appearance) \n", "\n", " 1.3. [Adding labels to pie sectors](#1.3.-Adding-labels-to-pie-sectors) \n", "\n", " 1.4. [Use \"count2d\" statistical transformation](#1.4.-Use-\"count2d\"-statistical-transformation)\n", "\n", "\n", "2. [Pie size depending on data](#2.-Pie-size-depending-on-data)\n", "\n", "\n", "3. [Explode](#3.-Explode)" ] }, { "cell_type": "code", "execution_count": 1, "id": "de93dd34", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.172971Z", "iopub.status.busy": "2024-04-17T07:31:10.172889Z", "iopub.status.idle": "2024-04-17T07:31:10.493361Z", "shell.execute_reply": "2024-04-17T07:31:10.493032Z" } }, "outputs": [], "source": [ "from lets_plot import *\n", "from lets_plot.mapping import *" ] }, { "cell_type": "code", "execution_count": 2, "id": "53eadd20", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.494821Z", "iopub.status.busy": "2024-04-17T07:31:10.494704Z", "iopub.status.idle": "2024-04-17T07:31:10.496701Z", "shell.execute_reply": "2024-04-17T07:31:10.496529Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "LetsPlot.setup_html() " ] }, { "cell_type": "code", "execution_count": 3, "id": "d5962f75", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.497720Z", "iopub.status.busy": "2024-04-17T07:31:10.497552Z", "iopub.status.idle": "2024-04-17T07:31:10.499241Z", "shell.execute_reply": "2024-04-17T07:31:10.499064Z" } }, "outputs": [], "source": [ "w,h = 400,250\n", "\n", "df = {\n", " 'name': ['a', 'b', 'c', 'd', 'b'],\n", " 'value': [40, 90, 10, 50, 20 ],\n", "}\n", "\n", "p = ggplot(df) + ggsize(w,h)" ] }, { "cell_type": "markdown", "id": "3920b3eb", "metadata": {}, "source": [ "## 1. Default presentation" ] }, { "cell_type": "markdown", "id": "131ea087", "metadata": {}, "source": [ "### 1.1. Basic pie chart" ] }, { "cell_type": "markdown", "id": "b9807822", "metadata": {}, "source": [ "Use \"identity\" statistical transformation to leave the data unchanged." ] }, { "cell_type": "code", "execution_count": 4, "id": "2a268816", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.500143Z", "iopub.status.busy": "2024-04-17T07:31:10.500069Z", "iopub.status.idle": "2024-04-17T07:31:10.531588Z", "shell.execute_reply": "2024-04-17T07:31:10.531291Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + geom_pie(aes(slice='value', fill='name'), stat='identity')" ] }, { "cell_type": "markdown", "id": "6b84c618", "metadata": {}, "source": [ "### 1.2. Improve appearance" ] }, { "cell_type": "markdown", "id": "f35cb83b", "metadata": {}, "source": [ "- add stroke (`stroke` and `stroke_color`)\n", "- make the pie bigger (`size`)\n", "- add hole to draw donut-like chart (`hole`)\n", "- use blank theme (remove axis and grid)\n", "- use better colors" ] }, { "cell_type": "code", "execution_count": 5, "id": "3c8043b0", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.532880Z", "iopub.status.busy": "2024-04-17T07:31:10.532800Z", "iopub.status.idle": "2024-04-17T07:31:10.535409Z", "shell.execute_reply": "2024-04-17T07:31:10.535235Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + \\\n", " geom_pie(aes(slice='value', fill='name'), stat='identity',\n", " size = 20, stroke = 1, hole = 0.5) + \\\n", " theme_void()" ] }, { "cell_type": "markdown", "id": "e28a0f21", "metadata": {}, "source": [ "### 1.3. Adding labels to pie sectors" ] }, { "cell_type": "markdown", "id": "87acfe50", "metadata": {}, "source": [ "Let's label the sectors with their names - configure annotations via `layer_labels()` function: " ] }, { "cell_type": "code", "execution_count": 6, "id": "7b47b4f5", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.536525Z", "iopub.status.busy": "2024-04-17T07:31:10.536375Z", "iopub.status.idle": "2024-04-17T07:31:10.539142Z", "shell.execute_reply": "2024-04-17T07:31:10.538970Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + \\\n", " geom_pie(aes(slice='value', fill='name'), stat='identity',\n", " size = 20, stroke = 1, hole = 0.5,\n", " labels = layer_labels().line('@name').size(16)) + \\\n", " theme_void() + \\\n", " theme(legend_position='none')" ] }, { "cell_type": "markdown", "id": "dd978c7c", "metadata": {}, "source": [ "### 1.4. Use \"count2d\" statistical transformation" ] }, { "cell_type": "markdown", "id": "a62041bd", "metadata": {}, "source": [ "`geom_pie()` uses `count2d` stat by default. \n", "It allows to make a slice sizes proportional to the number of cases in each group (or if the weight aesthetic is supplied, the sum of the weights). Also `count2d` provides variables for proportion ('..prop..') and proportion in percent ('..proppct..'). " ] }, { "cell_type": "markdown", "id": "326a89b9", "metadata": {}, "source": [ "Using `layer_tooltips()` prepare the information for tooltips by adding the variables provided by 'count2d':" ] }, { "cell_type": "code", "execution_count": 7, "id": "65efaa35", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.540049Z", "iopub.status.busy": "2024-04-17T07:31:10.539975Z", "iopub.status.idle": "2024-04-17T07:31:10.541441Z", "shell.execute_reply": "2024-04-17T07:31:10.541270Z" } }, "outputs": [], "source": [ "tooltip_content = (\n", " layer_tooltips()\n", " .line('count|@{..count..} (@{..prop..})')\n", " .line('total|@{..sum..}')\n", " .format('..prop..', '.0%')\n", " .format('..count..', '.1f')\n", " .format('..sum..', '.1f')\n", ")" ] }, { "cell_type": "markdown", "id": "fc18bdaa", "metadata": {}, "source": [ "Apply 'count2d' to get slices proportional to the number of cases." ] }, { "cell_type": "code", "execution_count": 8, "id": "8940c835", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.542219Z", "iopub.status.busy": "2024-04-17T07:31:10.542148Z", "iopub.status.idle": "2024-04-17T07:31:10.544839Z", "shell.execute_reply": "2024-04-17T07:31:10.544666Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + \\\n", " geom_pie(aes(fill='name'),\n", " size = 20, stroke = 1, hole = 0.5,\n", " labels = layer_labels().line('@name').size(16), \n", " tooltips=tooltip_content) + \\\n", " theme_void() + \\\n", " theme(legend_position='none')" ] }, { "cell_type": "markdown", "id": "e19243d4", "metadata": {}, "source": [ "Compute weighted sum instead of simple count with aesthetic `weight`." ] }, { "cell_type": "code", "execution_count": 9, "id": "94aa3ca0", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.545667Z", "iopub.status.busy": "2024-04-17T07:31:10.545590Z", "iopub.status.idle": "2024-04-17T07:31:10.548472Z", "shell.execute_reply": "2024-04-17T07:31:10.548297Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + \\\n", " geom_pie(aes(fill='name', weight='value'),\n", " size = 20, stroke = 1, hole = 0.5,\n", " labels = layer_labels().line('@name').size(16), \n", " tooltips=tooltip_content) + \\\n", " theme_void() + \\\n", " theme(legend_position='none')" ] }, { "cell_type": "markdown", "id": "488ca893", "metadata": {}, "source": [ "Order sectors by count.\n", "\n", "The following ordering rule is used for the pie chart: the first slice goes to the left of 12 o'clock and others go clockwise." ] }, { "cell_type": "code", "execution_count": 10, "id": "7ea44d46", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.549274Z", "iopub.status.busy": "2024-04-17T07:31:10.549202Z", "iopub.status.idle": "2024-04-17T07:31:10.552267Z", "shell.execute_reply": "2024-04-17T07:31:10.552097Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + \\\n", " geom_pie(aes(fill=as_discrete('name', order_by='..count..'), weight='value'),\n", " size = 20, stroke = 1, hole = 0.5,\n", " labels = layer_labels().line('@name').size(16), \n", " tooltips=tooltip_content) + \\\n", " theme_void() + \\\n", " theme(legend_position='none')" ] }, { "cell_type": "markdown", "id": "70824928", "metadata": {}, "source": [ "## 2. Pie size depending on data" ] }, { "cell_type": "markdown", "id": "4e9515b9", "metadata": {}, "source": [ "Make the size of the pie chart dependent on the data: map total count ('..sum..' variable) to the `size`.\n", "\n", "Note that it has its own special representation of the size in the legend." ] }, { "cell_type": "code", "execution_count": 11, "id": "ec19f3b0", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.553129Z", "iopub.status.busy": "2024-04-17T07:31:10.553053Z", "iopub.status.idle": "2024-04-17T07:31:10.556327Z", "shell.execute_reply": "2024-04-17T07:31:10.556155Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2 = {\n", " 'x': [1, 1, 1, 1, 1, 1.5, 1.5, 2, 2, 2 ],\n", " 'y': [1, 1, 1, 1, 1, 2, 2, 1.5, 1.5, 1.5],\n", " 's': [3, 1, 2, 1, 4, 1, 3, 3, 3, 1],\n", " 'n': ['a', 'b', 'a', 'c', 'a', 'a', 'b', 'c', 'a', 'b']\n", "}\n", "\n", "ggplot(df2) + \\\n", " geom_pie(aes('x', 'y', fill='n', weight='s', size='..sum..'), hole=0.3, \n", " tooltips=tooltip_content) + \\\n", " xlim(0.5,2.5) + ylim(0.5,2.5) " ] }, { "cell_type": "markdown", "id": "cfd202f6", "metadata": {}, "source": [ "Mapping `fill` and `size` to the same variable:" ] }, { "cell_type": "code", "execution_count": 12, "id": "0f5ee99b", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.557131Z", "iopub.status.busy": "2024-04-17T07:31:10.557060Z", "iopub.status.idle": "2024-04-17T07:31:10.559393Z", "shell.execute_reply": "2024-04-17T07:31:10.559223Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot({'n': [\"a\", \"b\", \"c\"], 's': [1, 2, 3]}) + \\\n", " geom_pie(aes(fill='n', slice='s', size='n'), stat=\"identity\") + \\\n", " theme_void()" ] }, { "cell_type": "markdown", "id": "3971f302", "metadata": {}, "source": [ "## 3. Explode" ] }, { "cell_type": "markdown", "id": "fd59da1f", "metadata": {}, "source": [ "Use values to explode slices away from their center point, detaching it from the main pie." ] }, { "cell_type": "code", "execution_count": 13, "id": "489e92ef", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.560241Z", "iopub.status.busy": "2024-04-17T07:31:10.560169Z", "iopub.status.idle": "2024-04-17T07:31:10.563125Z", "shell.execute_reply": "2024-04-17T07:31:10.562949Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "length = {\n", " 'name' : ['20-50 km', '50-75 km', '10-20 km', '75-100 km', '3-5 km', '7-10 km', '5-7 km', '>100 km', '2-3 km'],\n", " 'count': [1109, 696, 353, 192, 168, 86, 74, 65, 53],\n", " 'explode': [0, 0, 0, 0.1, 0.1, 0.2, 0.3, 0.4, 0.6]\n", "}\n", "\n", "ggplot(length) + \\\n", " geom_pie(aes(fill='name', slice='count', explode='explode'), stat='identity',\n", " stroke=1, color='black', size=20) + \\\n", " theme_void() + \\\n", " scale_fill_gradient(low='dark_blue', high='light_green')" ] }, { "cell_type": "code", "execution_count": 14, "id": "99eeb6ea", "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:31:10.563894Z", "iopub.status.busy": "2024-04-17T07:31:10.563821Z", "iopub.status.idle": "2024-04-17T07:31:10.567183Z", "shell.execute_reply": "2024-04-17T07:31:10.567005Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "calories = {\n", " 'slice': [35, 25, 25, 15],\n", " 'label': [\"Apples\", \"Bananas\", \"Cherries\", \"Dates\"],\n", " 'explode': [0.1, 0, 0, 0]\n", "}\n", "\n", "p4 = ggplot(calories) + \\\n", " theme_void() + \\\n", " ggsize(w, h)\n", "\n", "p_pie = p4 + \\\n", " geom_pie(aes(fill='label', slice='slice', explode='explode'), stat='identity', size=18)\n", "\n", "p_donut = p4 + \\\n", " geom_pie(aes(fill='label', slice='slice', explode='explode'), stat='identity', hole=0.8, size=18)\n", "\n", "bunch = GGBunch()\n", "bunch.add_plot(p_pie + theme(legend_position='none'), 0, 0)\n", "bunch.add_plot(p_donut, w, 0)\n", "bunch.show()" ] } ], "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 }