{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"\n",
    "    border: 2px solid #4CAF50; \n",
    "    padding: 15px; \n",
    "    background-color: #f4f4f4; \n",
    "    border-radius: 10px; \n",
    "    align-items: center;\">\n",
    "\n",
    "<h1 style=\"margin: 0; color: #4CAF50;\">Visualisierungen in Python 3: Visualisierungstypen</h1>\n",
    "<h2 style=\"margin: 5px 0; color: #555;\">DSAI</h2>\n",
    "<h3 style=\"margin: 5px 0; color: #555;\">Jakob Eggl</h3>\n",
    "\n",
    "<div style=\"flex-shrink: 0;\">\n",
    "    <img src=\"https://www.htl-grieskirchen.at/wp/wp-content/uploads/2022/11/logo_bildschirm-1024x503.png\" alt=\"Logo\" style=\"width: 250px; height: auto;\"/>\n",
    "</div>\n",
    "<p1> © 2024/25 Jakob Eggl. Nutzung oder Verbreitung nur mit ausdrücklicher Genehmigung des Autors.</p1>\n",
    "</div>\n",
    "<div style=\"flex: 1;\">\n",
    "</div>   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Boxplot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Wir kommen nun zu einem sehr essentiellen Tool um die Verteilung von Daten in einem Dataset darzustellen. Dazu werden wir auch statistische Größen verwenden."
   ]
  },
  {
   "attachments": {
    "boxplot_Quartile.png": {
     "image/png": "[encoded data, 20060 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![boxplot_Quartile.png](attachment:boxplot_Quartile.png)\n",
    "\n",
    "(von https://datatab.de/tutorial/boxplot)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Achtung:** Auch wenn es hier so aussieht, muss natürlich der Mittelwert (strichlierte Linie) nicht in der Mitte der \"Box\" liegen."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Kurze Wiederholung:\n",
    "* Wie ist der Median definiert?\n",
    "* Wie sind die Quartile definiert?\n",
    "* Was ist der Interquartilsabstand?\n",
    "* Wie nennt man den Abstand von dem größten und dem kleinsten Wert?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Eigenschaften eines Boxplots**:\n",
    "* Visualisiert die Verteilung eines Datensatzes anhand von Quartilen\n",
    "* Zeigt den Median, das untere und obere Quartil sowie mögliche Ausreißer\n",
    "* Die „Box“ stellt die Interquartilspanne (IQR) dar, welche die mittleren 50 % der Daten umfasst\n",
    "* Der Median wird als Linie innerhalb der Box dargestellt\n",
    "* Gut geeignet, um Verteilungen und Unterschiede zwischen mehreren Gruppen zu vergleichen\n",
    "* Nützlich zur Erkennung von Asymmetrien und Ausreißern in Daten\n",
    "* Oft verwendet in explorativen Datenanalysen und statistischen Visualisierungen\n",
    "* Zusätzliche Beschriftungen:\n",
    "    * Titel\n",
    "    * Achsenbeschriftungen (z.B. Kategorien und Wertebereiche)\n",
    "    * Legende, falls mehrere Gruppen dargestellt werden\n",
    "    * Mittelwert als strichlierte Linie\n",
    "\n",
    "* Andere Variante: Unterer und oberer Strich (genannt Whiskers) repräsentieren die Werte $q_1-1.5\\cdot \\text{IQR}$ bzw. $q_3+1.5\\cdot \\text{IQR}$. Werte außerhalb sind *Ausreißer* und werden oft mit Punkten angegeben"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ähnlich wie bei den Balkendiagrammen ist es auch möglich, mehrere Boxplots nebeneinander darzustellenn."
   ]
  },
  {
   "attachments": {
    "boxplot_5_0.png": {
     "image/png": "[encoded data, 21012 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![boxplot_5_0.png](attachment:boxplot_5_0.png)\n",
    "\n",
    "(von https://seaborn.pydata.org/_images/boxplot_5_0.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Daten laden (Titanic)\n",
    "\n",
    "titanic = sns.load_dataset('titanic') # ggf. etwas anders als unser bisheriges Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>survived</th>\n",
       "      <th>pclass</th>\n",
       "      <th>sex</th>\n",
       "      <th>age</th>\n",
       "      <th>sibsp</th>\n",
       "      <th>parch</th>\n",
       "      <th>fare</th>\n",
       "      <th>embarked</th>\n",
       "      <th>class</th>\n",
       "      <th>who</th>\n",
       "      <th>adult_male</th>\n",
       "      <th>deck</th>\n",
       "      <th>embark_town</th>\n",
       "      <th>alive</th>\n",
       "      <th>alone</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>male</td>\n",
       "      <td>22.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>7.2500</td>\n",
       "      <td>S</td>\n",
       "      <td>Third</td>\n",
       "      <td>man</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Southampton</td>\n",
       "      <td>no</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>female</td>\n",
       "      <td>38.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>71.2833</td>\n",
       "      <td>C</td>\n",
       "      <td>First</td>\n",
       "      <td>woman</td>\n",
       "      <td>False</td>\n",
       "      <td>C</td>\n",
       "      <td>Cherbourg</td>\n",
       "      <td>yes</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>female</td>\n",
       "      <td>26.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>7.9250</td>\n",
       "      <td>S</td>\n",
       "      <td>Third</td>\n",
       "      <td>woman</td>\n",
       "      <td>False</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Southampton</td>\n",
       "      <td>yes</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>female</td>\n",
       "      <td>35.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>53.1000</td>\n",
       "      <td>S</td>\n",
       "      <td>First</td>\n",
       "      <td>woman</td>\n",
       "      <td>False</td>\n",
       "      <td>C</td>\n",
       "      <td>Southampton</td>\n",
       "      <td>yes</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>male</td>\n",
       "      <td>35.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>8.0500</td>\n",
       "      <td>S</td>\n",
       "      <td>Third</td>\n",
       "      <td>man</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Southampton</td>\n",
       "      <td>no</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>886</th>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>male</td>\n",
       "      <td>27.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>13.0000</td>\n",
       "      <td>S</td>\n",
       "      <td>Second</td>\n",
       "      <td>man</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Southampton</td>\n",
       "      <td>no</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>887</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>female</td>\n",
       "      <td>19.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>30.0000</td>\n",
       "      <td>S</td>\n",
       "      <td>First</td>\n",
       "      <td>woman</td>\n",
       "      <td>False</td>\n",
       "      <td>B</td>\n",
       "      <td>Southampton</td>\n",
       "      <td>yes</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>888</th>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>female</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>23.4500</td>\n",
       "      <td>S</td>\n",
       "      <td>Third</td>\n",
       "      <td>woman</td>\n",
       "      <td>False</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Southampton</td>\n",
       "      <td>no</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>889</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>male</td>\n",
       "      <td>26.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>30.0000</td>\n",
       "      <td>C</td>\n",
       "      <td>First</td>\n",
       "      <td>man</td>\n",
       "      <td>True</td>\n",
       "      <td>C</td>\n",
       "      <td>Cherbourg</td>\n",
       "      <td>yes</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>890</th>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>male</td>\n",
       "      <td>32.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>7.7500</td>\n",
       "      <td>Q</td>\n",
       "      <td>Third</td>\n",
       "      <td>man</td>\n",
       "      <td>True</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Queenstown</td>\n",
       "      <td>no</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>891 rows × 15 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     survived  pclass     sex   age  sibsp  parch     fare embarked   class  \\\n",
       "0           0       3    male  22.0      1      0   7.2500        S   Third   \n",
       "1           1       1  female  38.0      1      0  71.2833        C   First   \n",
       "2           1       3  female  26.0      0      0   7.9250        S   Third   \n",
       "3           1       1  female  35.0      1      0  53.1000        S   First   \n",
       "4           0       3    male  35.0      0      0   8.0500        S   Third   \n",
       "..        ...     ...     ...   ...    ...    ...      ...      ...     ...   \n",
       "886         0       2    male  27.0      0      0  13.0000        S  Second   \n",
       "887         1       1  female  19.0      0      0  30.0000        S   First   \n",
       "888         0       3  female   NaN      1      2  23.4500        S   Third   \n",
       "889         1       1    male  26.0      0      0  30.0000        C   First   \n",
       "890         0       3    male  32.0      0      0   7.7500        Q   Third   \n",
       "\n",
       "       who  adult_male deck  embark_town alive  alone  \n",
       "0      man        True  NaN  Southampton    no  False  \n",
       "1    woman       False    C    Cherbourg   yes  False  \n",
       "2    woman       False  NaN  Southampton   yes   True  \n",
       "3    woman       False    C  Southampton   yes  False  \n",
       "4      man        True  NaN  Southampton    no   True  \n",
       "..     ...         ...  ...          ...   ...    ...  \n",
       "886    man        True  NaN  Southampton    no   True  \n",
       "887  woman       False    B  Southampton   yes   True  \n",
       "888  woman       False  NaN  Southampton    no  False  \n",
       "889    man        True    C    Cherbourg   yes   True  \n",
       "890    man        True  NaN   Queenstown    no   True  \n",
       "\n",
       "[891 rows x 15 columns]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "titanic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 891 entries, 0 to 890\n",
      "Data columns (total 15 columns):\n",
      " #   Column       Non-Null Count  Dtype   \n",
      "---  ------       --------------  -----   \n",
      " 0   survived     891 non-null    int64   \n",
      " 1   pclass       891 non-null    int64   \n",
      " 2   sex          891 non-null    object  \n",
      " 3   age          714 non-null    float64 \n",
      " 4   sibsp        891 non-null    int64   \n",
      " 5   parch        891 non-null    int64   \n",
      " 6   fare         891 non-null    float64 \n",
      " 7   embarked     889 non-null    object  \n",
      " 8   class        891 non-null    category\n",
      " 9   who          891 non-null    object  \n",
      " 10  adult_male   891 non-null    bool    \n",
      " 11  deck         203 non-null    category\n",
      " 12  embark_town  889 non-null    object  \n",
      " 13  alive        891 non-null    object  \n",
      " 14  alone        891 non-null    bool    \n",
      "dtypes: bool(2), category(2), float64(2), int64(4), object(5)\n",
      "memory usage: 80.7+ KB\n"
     ]
    }
   ],
   "source": [
    "titanic.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 27412 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.boxplot(data=titanic, x=\"class\", y=\"age\", hue=\"alive\", whis=(0,100)) # whis=(0,100) zeigt alle Datenpunkte an. Standard ist 1.5, welches alle Datenpunkte innerhalb von 1.5*IQR anzeigt\n",
    "plt.title(\"Boxplot: Alter nach Klasse und Überleben\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "andere Version:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 29852 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.boxplot(data=titanic, x=\"class\", y=\"age\", hue=\"alive\")\n",
    "plt.title(\"Boxplot: Alter nach Klasse und Überleben\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='age', ylabel='class'>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 19872 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Können auch horizontal gezeichnet werden\n",
    "sns.boxplot(data=titanic, x=\"age\", y=\"class\", hue=\"alive\", orient=\"h\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Das Boxplot erlaubt es, Unterschiede zwischen verschiedenen Gruppen zu zeichnen (und schnell zu erkennen)."
   ]
  },
  {
   "attachments": {
    "Box_Connect.png": {
     "image/png": "[encoded data, 48812 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![Box_Connect.png](attachment:Box_Connect.png)\n",
    "\n",
    "(from https://blogs.sas.com/content/graphicallyspeaking/2015/12/04/boxplot-with-connect/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Was sagen uns die Boxplots für das Titanic Dataset?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Violinen Diagramm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Um die Verteilung der Daten noch detailierter zu visualisieren, bearbeiten wir nun das sogenannte Violinen Diagramm (Violin Plot)."
   ]
  },
  {
   "attachments": {
    "violinplot_5_0.png": {
     "image/png": "[encoded data, 51652 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![violinplot_5_0.png](attachment:violinplot_5_0.png)\n",
    "\n",
    "(von https://seaborn.pydata.org/generated/seaborn.violinplot.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Eigenschaften eines Violin Plots**:\n",
    "* Kombiniert Eigenschaften eines Boxplots und eines Dichteplots, um die Verteilung eines Datensatzes darzustellen\n",
    "* Zeigt die Verteilung der Daten über die gesamte Wertebereich, visualisiert durch eine symmetrische Dichtekurve\n",
    "* Die Form der \"Violine\" repräsentiert die Dichte der Daten bei verschiedenen Werten – breite Bereiche zeigen, wo viele Datenpunkte liegen\n",
    "* Wie beim Boxplot zeigt der Violin Plot auch den Median und die Quartile\n",
    "* Gut geeignet, um sowohl die Verteilung als auch Unterschiede zwischen mehreren Gruppen zu vergleichen\n",
    "* Anders als beim Boxplot bietet der Violin Plot mehr Informationen über die zugrunde liegende Dichte der Daten\n",
    "* Kann verwendet werden, um bimodale oder komplexe Verteilungen besser zu erkennen, die im Boxplot schwer erkennbar sind\n",
    "* Zusätzliche Beschriftungen:\n",
    "    * Titel\n",
    "    * Achsenbeschriftungen (z.B. Kategorien und Wertebereiche)\n",
    "    * Legende, wenn mehrere Gruppen dargestellt werden\n",
    "* Nützlich zur Erkennung von Details in der Verteilung, die in einem Boxplot möglicherweise nicht sichtbar sind\n",
    "* Kann bei kleineren Datensätzen weniger aussagekräftig sein (wie Boxplot)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 66496 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Auch hier ist die Python implementierung mit Seaborn sehr einfach\n",
    "\n",
    "sns.violinplot(data=titanic, x=\"class\", y=\"age\", hue=\"alive\", inner='quart') # inner legt fest, ob die Box gezeichnet wird (default='box') andere optionen: quart, stick, box\n",
    "plt.title(\"Violinplot: Alter nach Klasse und Überleben\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 57328 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Wir können aber auch splitten bzw. die Füllung weglassen\n",
    "sns.violinplot(data=titanic, x=\"class\", y=\"age\", hue=\"alive\", split=True, inner='quart', fill=None)\n",
    "plt.title(\"Violinplot: Alter nach Klasse und Überleben\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 55592 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Wir können aber auch splitten bzw. die Füllung weglassen\n",
    "sns.violinplot(data=titanic, x=\"class\", y=\"age\", hue=\"alive\", split=True, inner='quart')\n",
    "plt.title(\"Violinplot: Alter nach Klasse und Überleben\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Scatter Plot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ein etwas anderes Konzept bietet das so genannte Streudiagramm (engl. Scatter Plot). Es stellt die Datenpunkte dar, indem sie an ihre räumliche Position im Diagramm platziert werden."
   ]
  },
  {
   "attachments": {
    "img_scatterplot-1.png": {
     "image/png": "[encoded data, 16420 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![img_scatterplot-1.png](attachment:img_scatterplot-1.png)\n",
    "\n",
    "(von https://www.w3schools.com/python/python_ml_scatterplot.asp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Eigenschaften eines Scatter Plots**:\n",
    "* Visualisiert die Beziehung zwischen zwei numerischen Variablen als Punkte in einem kartesischen Koordinatensystem\n",
    "* Jeder Datenpunkt ist ein Punkt im $\\mathbb{R}^d, d\\in \\mathbb{N}$ und zeigt die Werte beider Variablen für eine bestimmte Beobachtung (theoretisch macht nur $d\\leq 3$ Sinn, praktisch nur $d= 2$) Warum?\n",
    "* Gut geeignet um Muster, Trends oder Korrelationen zwischen Variablen zu erkennen\n",
    "* Kann verwendet werden, um positive, negative oder keine Korrelation darzustellen\n",
    "* Bei größeren Datenmengen können Overlaps entstehen, wodurch dichte Bereiche schwer erkennbar werden (Overplotting)\n",
    "* Zusätzliche Informationen können durch Farb- oder Größenkodierung der Punkte eingefügt werden, um eine dritte Variable darzustellen\n",
    "* Ideal, um Ausreißer oder Cluster zu identifizieren\n",
    "* Zusätzliche Beschriftungen:\n",
    "    * Titel\n",
    "    * Achsenbeschriftungen (für die x- und y-Achse, die jeweilige Variablen darstellen)\n",
    "    * Legende, falls weitere Dimensionen durch Farben oder Größen der Punkte kodiert sind\n",
    "    * Punkte direkt (wenn sehr wenig)\n",
    "* Eine Funktion (zum Beispiel eine Trendlinie) kann hinzugefügt werden, um den Trend zwischen den Variablen besser sichtbar zu machen\n",
    "* Sehr nützliches und oft verwendetes Tool für explorative Datenanalysen, um Zusammenhänge zwischen verschiedenen Variablen zu verstehen"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nun plotten wir verschiedene Scatter Plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Daten laden\n",
    "\n",
    "tips = sns.load_dataset('tips')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>total_bill</th>\n",
       "      <th>tip</th>\n",
       "      <th>sex</th>\n",
       "      <th>smoker</th>\n",
       "      <th>day</th>\n",
       "      <th>time</th>\n",
       "      <th>size</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>16.99</td>\n",
       "      <td>1.01</td>\n",
       "      <td>Female</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>10.34</td>\n",
       "      <td>1.66</td>\n",
       "      <td>Male</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>21.01</td>\n",
       "      <td>3.50</td>\n",
       "      <td>Male</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>23.68</td>\n",
       "      <td>3.31</td>\n",
       "      <td>Male</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>24.59</td>\n",
       "      <td>3.61</td>\n",
       "      <td>Female</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>239</th>\n",
       "      <td>29.03</td>\n",
       "      <td>5.92</td>\n",
       "      <td>Male</td>\n",
       "      <td>No</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>240</th>\n",
       "      <td>27.18</td>\n",
       "      <td>2.00</td>\n",
       "      <td>Female</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>241</th>\n",
       "      <td>22.67</td>\n",
       "      <td>2.00</td>\n",
       "      <td>Male</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>242</th>\n",
       "      <td>17.82</td>\n",
       "      <td>1.75</td>\n",
       "      <td>Male</td>\n",
       "      <td>No</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>243</th>\n",
       "      <td>18.78</td>\n",
       "      <td>3.00</td>\n",
       "      <td>Female</td>\n",
       "      <td>No</td>\n",
       "      <td>Thur</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>244 rows × 7 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     total_bill   tip     sex smoker   day    time  size\n",
       "0         16.99  1.01  Female     No   Sun  Dinner     2\n",
       "1         10.34  1.66    Male     No   Sun  Dinner     3\n",
       "2         21.01  3.50    Male     No   Sun  Dinner     3\n",
       "3         23.68  3.31    Male     No   Sun  Dinner     2\n",
       "4         24.59  3.61  Female     No   Sun  Dinner     4\n",
       "..          ...   ...     ...    ...   ...     ...   ...\n",
       "239       29.03  5.92    Male     No   Sat  Dinner     3\n",
       "240       27.18  2.00  Female    Yes   Sat  Dinner     2\n",
       "241       22.67  2.00    Male    Yes   Sat  Dinner     2\n",
       "242       17.82  1.75    Male     No   Sat  Dinner     2\n",
       "243       18.78  3.00  Female     No  Thur  Dinner     2\n",
       "\n",
       "[244 rows x 7 columns]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tips"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 244 entries, 0 to 243\n",
      "Data columns (total 7 columns):\n",
      " #   Column      Non-Null Count  Dtype   \n",
      "---  ------      --------------  -----   \n",
      " 0   total_bill  244 non-null    float64 \n",
      " 1   tip         244 non-null    float64 \n",
      " 2   sex         244 non-null    category\n",
      " 3   smoker      244 non-null    category\n",
      " 4   day         244 non-null    category\n",
      " 5   time        244 non-null    category\n",
      " 6   size        244 non-null    int64   \n",
      "dtypes: category(4), float64(2), int64(1)\n",
      "memory usage: 7.4 KB\n"
     ]
    }
   ],
   "source": [
    "tips.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='total_bill', ylabel='tip'>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 27340 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.scatterplot(data=tips, x=\"total_bill\", y=\"tip\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='total_bill', ylabel='tip'>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 50148 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.scatterplot(data=tips, x=\"total_bill\", y=\"tip\", hue=\"time\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='total_bill', ylabel='tip'>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 56272 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Wir können auch Styles hinzufügen\n",
    "sns.scatterplot(data=tips, x=\"total_bill\", y=\"tip\", hue=\"time\", style=\"time\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='total_bill', ylabel='tip'>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 54360 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "tip_rate = tips.eval(\"tip / total_bill\").rename(\"tip_rate\")\n",
    "sns.scatterplot(data=tips, x=\"total_bill\", y=\"tip\", hue=tip_rate)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='total_bill', ylabel='tip'>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 70712 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Eine weitere Möglichkeit ist es, die size zu verwenden\n",
    "\n",
    "sns.scatterplot(data=tips, x=\"total_bill\", y=\"tip\", hue=\"size\", size=\"size\", sizes=(20, 200), legend=\"full\") # Dabei kann sizes = (20, 200) weggelassen werden"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Natürlich können auch Daten in $\\mathbb{R}^3$ in einem Scatter Plot dargestellt werden, ist aber normalerweise sehr unübersichltich."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 165968 characters]",
      "text/plain": [
       "<Figure size 1000x700 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "from mpl_toolkits.mplot3d import Axes3D\n",
    "\n",
    "# Load Titanic dataset\n",
    "titanic = sns.load_dataset('titanic')\n",
    "\n",
    "# Set up the figure and 3D axis\n",
    "fig = plt.figure(figsize=(10, 7))\n",
    "ax = fig.add_subplot(111, projection='3d')\n",
    "\n",
    "# Plot the 3D scatter\n",
    "sc = ax.scatter(titanic['age'], titanic['fare'], titanic['pclass'])\n",
    "\n",
    "# Add labels\n",
    "ax.set_xlabel('Age')\n",
    "ax.set_ylabel('Fare')\n",
    "ax.set_zlabel('Class')\n",
    "\n",
    "# Show plot\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Besser ist hier ein 2D Scatter Plot mit der Klasse als Farbe encodiert."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 86176 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 2D Scatterplot with Class being the color\n",
    "sns.scatterplot(data=titanic, x='fare', y='age', hue='pclass', palette='viridis')\n",
    "plt.title('Scatterplot of Age vs Fare with Class as color')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Histogramm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Wie im Notebook \"visualisierung_2.ipynb\" bereits geschrieben, könnten theoretisch solche Plots auftauchen, wenn wir immer Bar-Charts verwenden würden."
   ]
  },
  {
   "attachments": {
    "image.png": {
     "image/png": "[encoded data, 123756 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![image.png](attachment:image.png)\n",
    "\n",
    "(from Forstner SS2022; JKU)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Deswegen werden wir uns nun das Histogramm ansehen."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Um die Verteilung eines einzelnen Features in einem Dataset darzustellen, kommt oft ein Histogramm sehr gelegen."
   ]
  },
  {
   "attachments": {
    "histogram-temperatures.png": {
     "image/png": "[encoded data, 23276 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![histogram-temperatures.png](attachment:histogram-temperatures.png)\n",
    "\n",
    "(von https://www.pythoninformer.com/python-libraries/matplotlib/histograms/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Eigenschaften eines Histogramms**:\n",
    "* Visualisiert die Verteilung einer einzelnen numerischen Variable durch die Gruppierung der Daten in Intervalle (**Bins**)\n",
    "* Wie groß muss man die Bins wählen?\n",
    "* Die Höhe der Balken repräsentiert die Häufigkeit der Datenpunkte innerhalb eines Intervalls\n",
    "* Gut geeignet, um die Form der Verteilung, Schiefe und Streuung einer Variable zu erkennen\n",
    "* Zeigt Bereiche hoher oder niedriger Datenkonzentration sowie Ausreißer (je nach Bingröße)\n",
    "* Die Breite der Bins beeinflusst die Genauigkeit der Darstellung – zu breite Bins können Details verdecken, zu schmale Bins können die Daten verrauschen\n",
    "* Oft in Verbindung mit relativen Häufigkeiten oder Wahrscheinlichkeiten dargestellt, um die prozentuale Verteilung zu veranschaulichen\n",
    "* Zusätzliche Beschriftungen:\n",
    "    * Titel\n",
    "    * Achsenbeschriftungen (x-Achse für die Intervallbereiche, y-Achse für die Häufigkeiten)\n",
    "    * Legende, falls mehrere Datensätze oder Kategorien in einem Histogramm verglichen werden\n",
    "* Kann leicht mit anderen Diagrammen wie *Dichteplots* kombiniert werden, um die Verteilung noch detaillierter darzustellen\n",
    "* Besonders nützlich für explorative Datenanalysen, um schnell einen Überblick über die Verteilung der Daten zu erhalten"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "penguins = sns.load_dataset(\"penguins\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 22512 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.histplot(data=penguins, x=\"flipper_length_mm\", bins=10)\n",
    "plt.title(\"Histogramm: Flipperlänge\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Seaborn bietet uns hier wieder einige Möglichkeiten, die Histogramme zu modifizieren."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='flipper_length_mm', ylabel='Count'>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 14132 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Andere Bin-Größen\n",
    "sns.histplot(data=penguins, x=\"flipper_length_mm\", bins=1000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='flipper_length_mm', ylabel='Count'>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 17380 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.histplot(data=penguins, x=\"flipper_length_mm\", bins=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='flipper_length_mm', ylabel='Count'>"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 17208 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Aber auch Bin-Width kann eingestellt werden\n",
    "sns.histplot(data=penguins, x=\"flipper_length_mm\", binwidth=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='flipper_length_mm', ylabel='Count'>"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 32668 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Es kann auch ein Kernel Density Plot gezeichnet werden\n",
    "sns.histplot(data=penguins, x=\"flipper_length_mm\", kde=True) # default ist kde=False\n",
    "\n",
    "# Hier steht das kde für Kernel Density Estimation (Dichteschätzung)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='flipper_length_mm', ylabel='Count'>"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 23660 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Es kann auch eine weitere Information encoded werden mit Hilfe einer Farbe\n",
    "sns.histplot(data=penguins, x=\"flipper_length_mm\", hue=\"species\", element=\"step\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='flipper_length_mm', ylabel='Count'>"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 25380 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.histplot(data=penguins, x=\"flipper_length_mm\", hue=\"species\", multiple=\"stack\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dichte Plot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Wie bereits in den Histogrammen verwendet wollen wir nun auch die Dichteplots besprechen. Sie *schätzen* die Dichteverteilung der gegeben Daten."
   ]
  },
  {
   "attachments": {
    "density_plot.jpg": {
     "image/jpeg": "[encoded data, 39916 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![density_plot.jpg](attachment:density_plot.jpg)\n",
    "\n",
    "(von https://www.tutorialspoint.com/machine_learning/machine_learning_density_plots.htm)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Eigenschaften eines Dichteplots**:\n",
    "* Visualisiert die Verteilung einer numerischen Variable durch eine geglättete Kurve, die die Wahrscheinlichkeitsdichte darstellt\n",
    "* Zeigt die relative Häufigkeit von Werten ähnlich wie ein Histogramm, jedoch ohne die Daten in feste Intervalle (Bins) zu unterteilen\n",
    "* Gut geeignet, um die Form der Verteilung sanfter darzustellen, wodurch Muster wie Peaks oder Täler deutlicher erkennbar werden\n",
    "* Die Fläche unter der Kurve entspricht der Gesamtwahrscheinlichkeit von 1 (bei Wahrscheinlichkeitsdichte)\n",
    "* Glättung der Kurve wird durch einen sogenannten „Kernel“ bestimmt, dessen Breite (Bandbreite) die Glätte beeinflusst – größere Bandbreiten führen zu glatteren, aber weniger detaillierten Kurven\n",
    "* Nützlich, um multimodale Verteilungen oder subtile Variationen zu identifizieren, die in einem Histogramm schwerer zu erkennen wären\n",
    "* Kann auch verwendet werden, um mehrere Datensätze oder Gruppen zu vergleichen, indem mehrere Dichtekurven übereinander gelegt werden\n",
    "* Zusätzliche Beschriftungen:\n",
    "    * Titel\n",
    "    * Achsenbeschriftungen (x-Achse für die Werte der Variablen, y-Achse für die Dichte)\n",
    "    * Legende, falls mehrere Gruppen oder Verteilungen dargestellt werden\n",
    "* Besonders nützlich, um bei größeren Datensätzen kontinuierliche Verteilungen präzise darzustellen\n",
    "* Kann mit anderen Diagrammen wie Boxplots (ergibt Violin Plot) oder Histogrammen (siehe vorher) kombiniert werden, um eine detailliertere Analyse der Verteilung zu ermöglichen\n",
    "* **Wichtig**: Ist nur eine Schätzung. Somit kann es irreführend sein. Was könnte theoretisch falsch laufen?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "iris = sns.load_dataset(\"iris\")\n",
    "tips = sns.load_dataset(\"tips\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 34928 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.kdeplot(data=tips, x=\"total_bill\")\n",
    "plt.title(\"Kernel Density Plot: Total Bill\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='Density', ylabel='total_bill'>"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 26724 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# kann auch gedreht werden\n",
    "sns.kdeplot(data=tips, y=\"total_bill\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: ylabel='Density'>"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 54644 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.kdeplot(data=iris) # Verteilung der einzelnen Features im Iris dataset. Label ist hier nicht notwendig."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='total_bill', ylabel='Density'>"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 39320 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# We can change the kernel used for the density estimation (vergleiche mit vorher)\n",
    "sns.kdeplot(data=tips, x='total_bill', bw_adjust=0.2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='total_bill', ylabel='Density'>"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 43728 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# erneut können auch Farben verwendet werden um eine weitere Kategorie zu inkludieren\n",
    "sns.kdeplot(data=tips, x='total_bill', hue='time')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='total_bill', ylabel='Density'>"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 42644 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# auch die 'multiple' Option existiert wieder\n",
    "sns.kdeplot(data=tips, x='total_bill', hue='time', multiple='stack') # auch multiple='fill' ist möglich, default ist multiple='layer'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Eine sehr prominente Dichtefunktion ist die Normalverteilung (Gauss'sche Glockenkurve). Wir haben diese bereits besprochen, können aber jetzt nochmal mit Histogrammen und Density Plots bzw. Scatter Plots die Verteilung unter die Lupe nehmen."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = np.random.normal(loc=0, scale=1, size=10000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: ylabel='Count'>"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 28960 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Histogramm der Normalverteilung\n",
    "sns.histplot(data=data, kde=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-10.0, 30.0)"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 58076 characters]",
      "text/plain": [
       "<Figure size 600x600 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.random.normal(10, 1, 1000)\n",
    "y = np.random.normal(10, 8, 1000)\n",
    "\n",
    "df = pd.DataFrame({'x': x, 'y': y})\n",
    "\n",
    "sns.jointplot(data = df, x='x', y='y')\n",
    "plt.xlim(-10,30)\n",
    "plt.ylim(-10,30)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ohne der Einschränkung der Achsen würde der Plot so aussehen:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<seaborn.axisgrid.JointGrid at 0x7f879c2b2700>"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 75064 characters]",
      "text/plain": [
       "<Figure size 600x600 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.jointplot(data = df, x='x', y='y')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Pairplot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nun kommen wir noch zum Pairplot. Dieses kombiniert normalerweise das bisher bekannte Streudiagramm (Scatter Plot) mit einem Density Plot. Hier können alle Features \"gegeneinander\" geplottet werden."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Eigenschaften eines Pairplots**:\n",
    "* Ist symmetrisch bezüglich der 2. Mediane\n",
    "* Visualisiert die Beziehungen zwischen mehreren numerischen Variablen, indem alle möglichen Paarkombinationen der Variablen als Scatter Plots dargestellt werden\n",
    "* Zeigt Scatter Plots in einer Matrixform, wobei jede Zelle der Matrix die Beziehung zwischen zwei Variablen darstellt (es sind aber auch andere Diagrammtypen möglich)\n",
    "* Die Diagonale der Matrix enthält in der Regel Histogramme oder Dichteplots, um die Verteilung jeder einzelnen Variablen anzuzeigen\n",
    "* Gut geeignet, um Korrelationen, Trends und Ausreißer zwischen mehreren Variablen gleichzeitig zu erkennen\n",
    "* Ermöglicht das schnelle Erkennen von Mustern, linearen oder nichtlinearen Beziehungen sowie Clustern\n",
    "* Farb- oder Symbolkodierungen können verwendet werden, um eine dritte kategoriale Variable darzustellen und Unterschiede zwischen Gruppen hervorzuheben\n",
    "* Nützlich für explorative Datenanalysen, insbesondere bei größeren Datensätzen mit vielen Variablen\n",
    "* Zusätzliche Beschriftungen:\n",
    "    * Titel (optional, da die Matrix oft selbsterklärend ist)\n",
    "    * Achsenbeschriftungen für jede Zelle (Variablenbezeichnungen entlang der x- und y-Achsen)\n",
    "    * Legende, falls Farben zur Darstellung einer kategorialen Variable verwendet werden\n",
    "* Kann aufgrund der Vielzahl von Plots bei vielen Variablen unübersichtlich werden\n",
    "* Besonders hilfreich, um multivariate Zusammenhänge zu analysieren und Hypothesen über die Beziehungen zwischen Variablen zu generieren"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<seaborn.axisgrid.PairGrid at 0x7f879c2575b0>"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 341660 characters]",
      "text/plain": [
       "<Figure size 1117.75x1000 with 20 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.pairplot(data=iris, hue='species')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<seaborn.axisgrid.PairGrid at 0x7f879779a340>"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 561436 characters]",
      "text/plain": [
       "<Figure size 1117.75x1000 with 20 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.pairplot(data=iris, hue='species', kind='kde')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Aufgabe"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* Lade das Cars Dataset `cars.csv`\n",
    "* Führe zuerst notwendige Vorverarbeitungsschritte durch (sind (viele) Werte leer, unmöglich, Normalisieren, etc.) und Informieren Sie sich auch über das Dataset (zBsp. über https://www.kaggle.com/datasets/goyalshalini93/car-data)\n",
    "* Geben Sie verschiedene Zentral und Streumaße an für Features, wo Sie es für notwendig halten\n",
    "* Testen Sie die verschiedenen, bisher gelernten, Visualisierungsmöglichkeiten und Visualisieren Sie die Daten in einigen *sinnvollen* Grafiken\n",
    "* Dokumentieren Sie alle Ergebnisse!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Your code here"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "dsai",
   "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.9.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
