{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### Creating multi-panel plots using `facets`.\n", "\n", "#### Problem\n", "\n", "You want to see more aspects of your data and it's not practical to use the regular `aesthetics` approach for that.\n", "\n", "#### Solution - `facets`\n", "\n", "You can add one or more new dimentions to your plot using `faceting`.\n", "\n", "This approach allows you to split up your data by one or more variables and plot the subsets of data together.\n", "\n", "\n", "In this demo we will explore how various faceting functions work, as well as the built-in `sorting` and `formatting` options." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:27:10.032779Z", "iopub.status.busy": "2024-04-17T07:27:10.032659Z", "iopub.status.idle": "2024-04-17T07:27:10.352739Z", "shell.execute_reply": "2024-04-17T07:27:10.352544Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import pandas as pd\n", "\n", "from lets_plot import *\n", "LetsPlot.setup_html()" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:27:10.366147Z", "iopub.status.busy": "2024-04-17T07:27:10.366003Z", "iopub.status.idle": "2024-04-17T07:27:10.713504Z", "shell.execute_reply": "2024-04-17T07:27:10.713303Z" } }, "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", "
miles per gallonnumber of cylindersengine displacement (cu. inches)engine horsepowervehicle weight (lbs.)time to accelerate (sec.)model yearorigin of carvehicle name
018.08307.0130350412.070USchevrolet chevelle malibu
115.08350.0165369311.570USbuick skylark 320
218.08318.0150343611.070USplymouth satellite
\n", "
" ], "text/plain": [ " miles per gallon number of cylinders engine displacement (cu. inches) \\\n", "0 18.0 8 307.0 \n", "1 15.0 8 350.0 \n", "2 18.0 8 318.0 \n", "\n", " engine horsepower vehicle weight (lbs.) time to accelerate (sec.) \\\n", "0 130 3504 12.0 \n", "1 165 3693 11.5 \n", "2 150 3436 11.0 \n", "\n", " model year origin of car vehicle name \n", "0 70 US chevrolet chevelle malibu \n", "1 70 US buick skylark 320 \n", "2 70 US plymouth satellite " ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = pd.read_csv('https://raw.githubusercontent.com/JetBrains/lets-plot-docs/master/data/mpg2.csv')\n", "data.head(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### One plot\n", "\n", "Create a scatter plot to show how `mpg` is related to a car's `engine horsepower`.\n", "\n", "Also use the `color` aesthetic to vizualise the region where a car was designed." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:27:10.714813Z", "iopub.status.busy": "2024-04-17T07:27:10.714725Z", "iopub.status.idle": "2024-04-17T07:27:10.749693Z", "shell.execute_reply": "2024-04-17T07:27:10.749489Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p = (ggplot(data, aes(x=\"engine horsepower\", y=\"miles per gallon\")) + \n", " geom_point(aes(color=\"origin of car\")))\n", "p + ggsize(800, 350)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### More dimentions\n", "\n", "There are two functions for faceting:\n", "\n", " - facet_grid()\n", " - facet_wrap()\n", "\n", "The first one creates a 2D matrix of plot panels and the second creates a one dimensional strip of plot panels.\n", "\n", "We will use the `number of cylinders` variable as 1st faceting variable, and sometimes the `origin of car` as a 2nd faceting variable. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### facet_grid()\n", "\n", "The data can be split up by one or two variables that vary on the X and/or Y direction." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### One facet\n", "\n", "Let's split up the data by `number of cylinders`." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:27:10.751364Z", "iopub.status.busy": "2024-04-17T07:27:10.751252Z", "iopub.status.idle": "2024-04-17T07:27:10.756729Z", "shell.execute_reply": "2024-04-17T07:27:10.756547Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + facet_grid(x=\"number of cylinders\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Two facets\n", "\n", "Split up the data by two faceting variables: `number of cylinders` and `origin of car`." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:27:10.758158Z", "iopub.status.busy": "2024-04-17T07:27:10.758030Z", "iopub.status.idle": "2024-04-17T07:27:10.763492Z", "shell.execute_reply": "2024-04-17T07:27:10.763319Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + facet_grid(x=\"number of cylinders\", y=\"origin of car\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Formatting and sorting.\n", "\n", "Apply a formatting template to the `number of cylinders` and\n", "sort the `origin of car` values in discending order.\n", "\n", "To learn more about formatting templates see: [Formatting](https://lets-plot.org/python/pages/formats.html). " ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:27:10.764549Z", "iopub.status.busy": "2024-04-17T07:27:10.764424Z", "iopub.status.idle": "2024-04-17T07:27:10.770093Z", "shell.execute_reply": "2024-04-17T07:27:10.769923Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + facet_grid(x=\"number of cylinders\", y=\"origin of car\", x_format=\"{d} cyl\", y_order=-1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### facet_wrap()\n", "\n", "The data can be split up by one or more variables. \n", "The panels layout is flexible and controlled by `ncol`, `nrow` and `dir` options." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### One facet\n", "\n", "Split data by the `number of cylinders` variable and arrange tiles in two rows." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:27:10.771184Z", "iopub.status.busy": "2024-04-17T07:27:10.771067Z", "iopub.status.idle": "2024-04-17T07:27:10.776386Z", "shell.execute_reply": "2024-04-17T07:27:10.776215Z" }, "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + facet_wrap(facets=\"number of cylinders\", nrow=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Two facets\n", "\n", "Split data by `origin of car` and `number of cylinders` and arrange tiles in 5 columns." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:27:10.777438Z", "iopub.status.busy": "2024-04-17T07:27:10.777309Z", "iopub.status.idle": "2024-04-17T07:27:10.782744Z", "shell.execute_reply": "2024-04-17T07:27:10.782572Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + facet_wrap(facets=[\"origin of car\", \"number of cylinders\"], ncol=5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "#### Arrange panels vertically.\n", "\n", "Use the `dir` parameter to arrange tiles by columns, in 3 columns (the default tile arrangment is \"by row\").\n", "\n", "Also, format `number of cylinders` labels and reverse the sorting direction for this facetting variable." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2024-04-17T07:27:10.783653Z", "iopub.status.busy": "2024-04-17T07:27:10.783576Z", "iopub.status.idle": "2024-04-17T07:27:10.789303Z", "shell.execute_reply": "2024-04-17T07:27:10.789125Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p + facet_wrap(facets=[\"origin of car\", \"number of cylinders\"], \n", " ncol=3,\n", " format=[None, \"{} cyl\"],\n", " order=[1, -1],\n", " dir=\"v\")" ] } ], "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": 4 }