{ "cells": [ { "cell_type": "markdown", "id": "86341836-ddb1-4bce-b069-7f57e586cd14", "metadata": {}, "source": [ "# Polar Coordinate System\n", "\n", "The polar coordinate system is used for pie charts and polar plots.\n", "\n", "Note that the polar coordinate system may change the default expansion for position scales:\n", "\n", "- Discrete x-scale is expanded so that the first and last values don't overlap.\n", "- Continuous position scales have their expands set to zero so that the pie chart doesn't get an inner hole, and the first and last sectors don't get a gap." ] }, { "cell_type": "code", "execution_count": 1, "id": "d9dcefd7-0655-4e71-99e3-2e6c8bb8ff7a", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "\n", "from lets_plot import *\n", "from lets_plot.mapping import as_discrete" ] }, { "cell_type": "code", "execution_count": 2, "id": "583c0c27-38fe-4ecb-8339-cb71c411a9c6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "LetsPlot.setup_html()\n", "LetsPlot.set_theme(theme_grey())\n" ] }, { "cell_type": "code", "execution_count": 3, "id": "b1688318-4db9-4e13-9824-763fff8bec18", "metadata": {}, "outputs": [ { "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": [ "mpg = pd.read_csv('https://raw.githubusercontent.com/JetBrains/lets-plot-docs/master/data/mpg.csv')\n", "mpg.head()" ] }, { "cell_type": "markdown", "id": "b85f05e5-bcdb-4cd1-a789-cdaab649c982", "metadata": {}, "source": [ "## Pie Chart\n", "`geom_bar()` with `coord_polar()` get transformed into a pie chart. Note the `theta='y'` parameter." ] }, { "cell_type": "code", "execution_count": 4, "id": "959a1afa-b7bf-494b-83ed-120cd8db0f15", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bars = ggplot(mpg) + geom_bar(aes(fill=as_discrete('cyl')), size=0)\n", "gggrid([\n", " bars + ggtitle('From Bar Chart'),\n", " bars + coord_polar(theta='y') + ggtitle('To Pie Chart')\n", "])" ] }, { "cell_type": "markdown", "id": "58093f34-86dc-4173-bde4-88d79b4b0d17", "metadata": {}, "source": [ "## Various Bar Charts in the Polar Coordinate System" ] }, { "cell_type": "code", "execution_count": 5, "id": "8a64bfa8-cec9-4477-8343-0b065d825343", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bull_eye = ggplot(mpg) \\\n", " + geom_bar(aes(fill=as_discrete('cyl')), size=0, show_legend=False)\n", " \n", "radial_bar = ggplot(mpg) \\\n", " + geom_bar(aes(fill=as_discrete('cyl')), size=0, position='dodge', show_legend=False)\n", " \n", "coxcomb = ggplot(mpg) \\\n", " + geom_bar(aes(fill=as_discrete('cyl')), size=0, position='dodge', show_legend=False)\n", "\n", "\n", "gggrid([\n", " bull_eye + coord_polar() + ggtitle('Bulls eye'),\n", " radial_bar + coord_polar(theta='y') + ggtitle('Radial bar chart'),\n", " coxcomb + coord_polar() + ggtitle('Coxcomb plot'),\n", "\n", " bull_eye + ggtitle('was:'),\n", " radial_bar + ggtitle('was:'),\n", " coxcomb + ggtitle('was:'),\n", "], ncol=3)" ] }, { "cell_type": "markdown", "id": "b13b1bda-0647-46ae-84ea-75e70251c6aa", "metadata": {}, "source": [ "## Radar Plot\n", "Use the `flat` parameter in path-based geoms to construct a radar plot." ] }, { "cell_type": "code", "execution_count": 6, "id": "9df93573-b325-4b9a-87f9-47dc31949ef7", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "student_df = {\n", " 'subj': ['progr', 'math', 'physic', 'chemistry', 'biology'],\n", " 'subj_id': [1, 2, 3, 4, 5],\n", " 'student': ['John'] * 5,\n", " 'score': [19, 15, 18, 12, 9]\n", "}\n", "labels = { 1: 'progr', 2: 'math', 3: 'physic', 4: 'chemistry', 5: 'biology' }\n", "\n", "p = (ggplot(student_df) \n", " + geom_area(aes(x='subj_id', y='score'), \n", " flat=True) # <-- Flat. I.e., do not transform segments to curves.\n", " + geom_point(aes(x='subj_id', y='score')) \n", " + scale_x_discrete(labels=labels) \n", " + coord_polar())\n", "p" ] }, { "cell_type": "markdown", "id": "c0ac4b5a-166f-432e-aabc-bfb70ad03bdf", "metadata": {}, "source": [ "## Heatmap Plot" ] }, { "cell_type": "code", "execution_count": 7, "id": "7e69cbc0-f761-4c70-8f5b-bfe5b4b8cd50", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from scipy.interpolate import griddata\n", "\n", "max_r = 100\n", "max_theta = 2.0 * np.pi\n", "number_points = 5_000\n", "np.random.seed = 42\n", "\n", "grid_r, grid_theta = np.meshgrid(\n", " np.linspace(0, max_r, 200), # r\n", " np.linspace(0.0, max_theta, 100) # theta\n", ")\n", "\n", "points = np.random.rand(number_points, 2) * [max_r, max_theta]\n", "values = points[:,0] * np.sin(points[:,1])**2 * np.cos(points[:,1])**2\n", "data = griddata(points, values, (grid_r, grid_theta), method='cubic',fill_value=0)\n", "\n", "df = {\n", " 'x': grid_theta.flatten(), \n", " 'y': grid_r.flatten(), \n", " 'z': data.flatten()\n", "}\n", "\n", "p = ggplot(df) \\\n", " + geom_tile(aes('x', 'y', color='z', fill='z'), size=1, tooltips='none') \\\n", " + scale_brewer(['color', 'fill'], palette='Spectral', direction=-1) \\\n", " + theme(axis_title=element_blank())\n", "\n", "gggrid([\n", " p + coord_cartesian(),\n", " p + coord_polar() + theme(legend_position='none'),\n", "])" ] }, { "cell_type": "markdown", "id": "72b78261-b29f-499f-8dfa-c99f73f630fd", "metadata": {}, "source": [ "## Theming\n", "\n", "The polar coordinate system supports axis theme options, incorporates specialized logic for the theme's `panel_inset` parameter, and offers its own `transform_bkgr` option to manage plot panel transformation:" ] }, { "cell_type": "code", "execution_count": 8, "id": "fef0ebd9-399b-4ed6-8f4a-d9a7e81c4456", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ggplot(mpg) \\\n", " + geom_bar(aes(x='model', y='cty', fill='cty'), stat='identity', position='dodge') \\\n", " + scale_fill_gradient(low='red', high='white', limits=(5,40)) \\\n", " + theme(\n", " axis_line_y=element_line(color='red', size=2),\n", " axis_line_x=element_line(color='blue', size=2),\n", " axis_ticks_length_y=5,\n", " axis_ticks_length_x=10,\n", " axis_ticks_y=element_line(size=5, color='red'), \n", " axis_ticks_x=element_line(size=3, color='blue'),\n", " axis_text_x=element_text(color='blue', angle=10),\n", " axis_text_y=element_text(color='red'),\n", " panel_inset=[20, 140, 30, 135] # New! Expand the panel to fit axis labels.\n", " ) \\\n", " + ggsize(900, 500) \\\n", " + coord_polar(transform_bkgr=False) # Keep the old school rectangular background." ] } ], "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.8.15" } }, "nbformat": 4, "nbformat_minor": 5 }