{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "hide"
    ]
   },
   "outputs": [],
   "source": [
    "import seaborn as sns\n",
    "sns.set_theme(style=\"whitegrid\")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Assigning a single numeric variable shows its univariate distribution with points adjusted along on the other axis such that they don't overlap:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tips = sns.load_dataset(\"tips\")\n",
    "sns.swarmplot(data=tips, x=\"total_bill\")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Assigning a second variable splits the groups of points to compare categorical levels of that variable:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(data=tips, x=\"total_bill\", y=\"day\")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Show vertically-oriented swarms by swapping the assignment of the categorical and numerical variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(data=tips, x=\"day\", y=\"total_bill\")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Prior to version 0.12, the levels of the categorical variable had different colors by default. To get the same effect, assign the `hue` variable explicitly:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(data=tips, x=\"total_bill\", y=\"day\", hue=\"day\", legend=False)"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Or you can assign a distinct variable to `hue` to show a multidimensional relationship:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(data=tips, x=\"total_bill\", y=\"day\", hue=\"sex\")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "If the `hue` variable is numeric, it will be mapped with a quantitative palette by default (note that this was not the case prior to version 0.12):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(data=tips, x=\"total_bill\", y=\"day\", hue=\"size\")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Use `palette` to control the color mapping, including forcing a categorical mapping by passing the name of a qualitative palette:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(data=tips, x=\"total_bill\", y=\"day\", hue=\"size\", palette=\"deep\")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "By default, the different levels of the `hue` variable are intermingled in each swarm, but setting `dodge=True` will split them:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(data=tips, x=\"total_bill\", y=\"day\", hue=\"sex\", dodge=True)"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "The \"orientation\" of the plot (defined as the direction along which quantitative relationships are preserved) is usually inferred automatically. But in ambiguous cases, such as when both axis variables are numeric, it can be specified:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(data=tips, x=\"total_bill\", y=\"size\", orient=\"h\")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "When the local density of points is too high, they will be forced to overlap in the \"gutters\" of each swarm and a warning will be issued. Decreasing the size of the points can help to avoid this problem:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(data=tips, x=\"total_bill\", y=\"size\", orient=\"h\", size=3)"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "By default, the categorical variable will be mapped to discrete indices with a fixed scale (0, 1, ...), even when it is numeric:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(\n",
    "    data=tips.query(\"size in [2, 3, 5]\"),\n",
    "    x=\"total_bill\", y=\"size\", orient=\"h\",\n",
    ")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "To disable this behavior and use the original scale of the variable, set `native_scale=True` (notice how this also changes the order of the variables on the y axis):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(\n",
    "    data=tips.query(\"size in [2, 3, 5]\"),\n",
    "    x=\"total_bill\", y=\"size\", orient=\"h\",\n",
    "    native_scale=True,\n",
    ")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Further visual customization can be achieved by passing keyword arguments for :func:`matplotlib.axes.Axes.scatter`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.swarmplot(\n",
    "    data=tips, x=\"total_bill\", y=\"day\",\n",
    "    marker=\"x\", linewidth=1, \n",
    ")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "To make a plot with multiple facets, it is safer to use :func:`catplot` with `kind=\"swarm\"` than to work with :class:`FacetGrid` directly, because :func:`catplot` will ensure that the categorical and hue variables are properly synchronized in each facet:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.catplot(\n",
    "    data=tips, kind=\"swarm\",\n",
    "    x=\"time\", y=\"total_bill\", hue=\"sex\", col=\"day\",\n",
    "    aspect=.5\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py310",
   "language": "python",
   "name": "py310"
  },
  "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.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
