{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Stacked Bar Graph with pandas ans matplotlib\n", "\n", "##### Germain Salvato Vallverdu [germain.vallverdu@univ-pau.fr](germain.vallverdu@univ-pau.fr)\n", "\n", "Quelques notions sur [Stacked Bar Graph sur le datavizcatalogue](http://www.datavizcatalogue.com/methods/stacked_bar_graph.html).\n", "\n", "Ce notebook présente la construction d'un stacked bar graph avec pandas et matplotlib. \n", "\n", "Concernant pandas, ce notebook montre comment :\n", "\n", "* appliquer une fonction colonne par colonne\n", "* Transformer un score en catégorie\n", "* Extraire le pourcentatge d'une catégorie par colonne" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "sns.set(style=\"white\", font_scale=1.5)\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## Création d'une data frame aléatoire" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "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", "
ABCD
02422
15242
21556
35513
45261
55664
65252
73634
81121
91416
\n", "
" ], "text/plain": [ " A B C D\n", "0 2 4 2 2\n", "1 5 2 4 2\n", "2 1 5 5 6\n", "3 5 5 1 3\n", "4 5 2 6 1\n", "5 5 6 6 4\n", "6 5 2 5 2\n", "7 3 6 3 4\n", "8 1 1 2 1\n", "9 1 4 1 6" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N = 10\n", "df = pd.DataFrame({k: np.random.randint(low=1, high=7, size=N) for k in \"ABCD\"})\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Transformer le score en catégorie\n", "\n", "L'idée est de transformer le score du questionnaire en une catégorie : \"défavorise\", \"neutre\", \"favrorise\".\n", "\n", "Le point le plus difficile est l'écriture de la fonction. Avec `df.apply()` on va appliquer la fonction à l'ensemble du tableau. On peut le faire de deux manières différentes.\n", "\n", "### Version 1: fonction par colonne\n", "\n", "Ici je vais appliquer la fonction colonne par colonne (`axis=0`). Il faut donc que la fonction prenne commme argument la colonne et retourne la liste des nouvelles valeurs de la colonne.\n", "\n", "Donc \n", "\n", "* On commence par créer une liste vide\n", "* On fait une boucle sur les éléments de la colonne\n", "* On remplit la liste" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def cat_column(column):\n", " values = list()\n", " for val in column:\n", " if val <= 2:\n", " cat = \"defavorise\"\n", " elif val >= 5:\n", " cat = \"favorise\"\n", " else:\n", " cat = \"neutre\"\n", " values.append(cat)\n", " return values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sur le principe, voici comme ça marche avec :" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['defavorise', 'defavorise', 'neutre', 'neutre', 'favorise', 'favorise']\n" ] } ], "source": [ "liste = [1, 2, 3, 4, 5, 6]\n", "values = cat_column(liste)\n", "print(values)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Maintenant on applique à notre tableau :" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "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", "
ABCD
0defavoriseneutredefavorisedefavorise
1favorisedefavoriseneutredefavorise
2defavorisefavorisefavorisefavorise
3favorisefavorisedefavoriseneutre
4favorisedefavorisefavorisedefavorise
5favorisefavorisefavoriseneutre
6favorisedefavorisefavorisedefavorise
7neutrefavoriseneutreneutre
8defavorisedefavorisedefavorisedefavorise
9defavoriseneutredefavorisefavorise
\n", "
" ], "text/plain": [ " A B C D\n", "0 defavorise neutre defavorise defavorise\n", "1 favorise defavorise neutre defavorise\n", "2 defavorise favorise favorise favorise\n", "3 favorise favorise defavorise neutre\n", "4 favorise defavorise favorise defavorise\n", "5 favorise favorise favorise neutre\n", "6 favorise defavorise favorise defavorise\n", "7 neutre favorise neutre neutre\n", "8 defavorise defavorise defavorise defavorise\n", "9 defavorise neutre defavorise favorise" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cat = df.apply(cat_column, axis=0)\n", "df_cat" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Version 2: sur tout le tableau\n", "\n", "Les opérations ne dépendent que d'une case du tableau. On peut donc utiliser une fonction qui ne connait que le contenu d'une case et retourne la bonne catégorie. La fonction est plus simple (pas de boucle), elle prend comme arguement le contenu d'une case et retourne la catégorie :" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def cat_cell(val):\n", " if val <= 2:\n", " cat = \"defavorise\"\n", " elif val >= 5:\n", " cat = \"favorise\"\n", " else:\n", " cat = \"neutre\"\n", "\n", " return cat" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Par exemple :" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "defavorise neutre\n" ] } ], "source": [ "print(cat_cell(2), cat_cell(3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On l'applique au tableau. Maintenant on doit utiliser la méthode `df.applymap()` au lieu de `apply()`." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "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", "
ABCD
0defavoriseneutredefavorisedefavorise
1favorisedefavoriseneutredefavorise
2defavorisefavorisefavorisefavorise
3favorisefavorisedefavoriseneutre
4favorisedefavorisefavorisedefavorise
5favorisefavorisefavoriseneutre
6favorisedefavorisefavorisedefavorise
7neutrefavoriseneutreneutre
8defavorisedefavorisedefavorisedefavorise
9defavoriseneutredefavorisefavorise
\n", "
" ], "text/plain": [ " A B C D\n", "0 defavorise neutre defavorise defavorise\n", "1 favorise defavorise neutre defavorise\n", "2 defavorise favorise favorise favorise\n", "3 favorise favorise defavorise neutre\n", "4 favorise defavorise favorise defavorise\n", "5 favorise favorise favorise neutre\n", "6 favorise defavorise favorise defavorise\n", "7 neutre favorise neutre neutre\n", "8 defavorise defavorise defavorise defavorise\n", "9 defavorise neutre defavorise favorise" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cat = df.applymap(cat_cell)\n", "df_cat" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pourcentage de chaque catégorie par colonne\n", "\n", "Maintenant on va calculer le nombre de fois que chaque catégorie apparaît dans une colonne. Il faut pour cela utiliser `pd.value_counts()` :" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "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", "
ABCD
defavorise4445
favorise5442
neutre1223
\n", "
" ], "text/plain": [ " A B C D\n", "defavorise 4 4 4 5\n", "favorise 5 4 4 2\n", "neutre 1 2 2 3" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cat.apply(pd.value_counts)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si on veut le pourcentage, il faut savoir combien il y a de lignes. Dans cet exemple, c'est `N` que l'on a définit tout au début. Sinon, il faut récupérer le nombre de lignes de la `DataFrame`. Cette information est contenu dans `df.shape` :" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 4\n" ] } ], "source": [ "nrows, ncols = df_cat.shape\n", "print(nrows, ncols)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "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", "
ABCD
defavorise40.040.040.050.0
favorise50.040.040.020.0
neutre10.020.020.030.0
\n", "
" ], "text/plain": [ " A B C D\n", "defavorise 40.0 40.0 40.0 50.0\n", "favorise 50.0 40.0 40.0 20.0\n", "neutre 10.0 20.0 20.0 30.0" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_percent = df_cat.apply(pd.value_counts) / nrows * 100\n", "df_percent" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Stacked histogram\n", "\n", "Avant de faire le graphique avec pandas, il faut transposer le tableau pour qu'il trace en fonction de A, B, C et D." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "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", "
defavorisefavoriseneutre
A40.050.010.0
B40.040.020.0
C40.040.020.0
D50.020.030.0
\n", "
" ], "text/plain": [ " defavorise favorise neutre\n", "A 40.0 50.0 10.0\n", "B 40.0 40.0 20.0\n", "C 40.0 40.0 20.0\n", "D 50.0 20.0 30.0" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_percent_t = df_percent.transpose()\n", "df_percent_t" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour que le graphique soit plus cohérent, on va réorganiser les colonnes de sorte que `\"neutre\"` soit au milieu :" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "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", "
defavoriseneutrefavorise
A40.010.050.0
B40.020.040.0
C40.020.040.0
D50.030.020.0
\n", "
" ], "text/plain": [ " defavorise neutre favorise\n", "A 40.0 10.0 50.0\n", "B 40.0 20.0 40.0\n", "C 40.0 20.0 40.0\n", "D 50.0 30.0 20.0" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_percent_t = df_percent_t[[\"defavorise\", \"neutre\", \"favorise\"]]\n", "df_percent_t" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Voici une première version, le principe étant de choisir un graphique de type `barh` avec `stacked` vrai. On choisit ensuite une [colormap divergente](http://matplotlib.org/examples/color/colormaps_reference.html) pour donner un sens aux couleurs." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nI3yqx4cAAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = plt.figure()\n", "ax = fig.add_subplot(111)\n", "df_percent_t.plot(kind=\"barh\", stacked=True, ax=ax, colormap=\"RdYlGn\", alpha=.8, xlim=(0, 101))\n", "ax.legend(ncol=3, loc='upper center', bbox_to_anchor=(0.5, 1.15), frameon=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un peu plus de détails, la partie compliquée est l'ajout des annotations." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 40.0, 50.0, 100.0]\n", "[0, 40.0, 60.0, 100.0]\n", "[0, 40.0, 60.0, 100.0]\n", "[0, 50.0, 80.0, 100.0]\n" ] }, { "data": { "image/png": "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\nTauI7t/fb92/v9/a3T1oBYAvXHJ6fzAYsd7xvV/VbNvWqt1++2M10WjccunCBTm10tfnV195ZXPJ\nVVd/qhsA5sydFty8abd748Zdzueff7v0xBNrWSvHgJhLjWX/pSxIJa1KIl6gxgFgqMLeb0nqVt/7\nwRqHP6H53g/WKCndMljlyKmX7F4IAIh4rEHnYNKtDSac7v2x0miRlfVyFDmSnggFHz7FU4FxRsal\nACYB+K2U8v+OYB00yrQUUpe1o/nFctRurcGk0hjCX2lHs33YmRfrvfDNSfdCAEB9CMFZfvQ8Phmi\nLIbQxZ1ozc8zoNHy8u83FiuKgnuWP1N7z/JnajPTy8o8sT+t+9HWoqKC1H33f7156ZInal944Z1J\ndXW+8EMP39BcUODIqZVHHlnju+SS+d1Op3FGxhlnzAx+9rPzeq679j4xfXpV6N9/cCVr5TiQsllS\n7Se5msu3h2prOmOTYgVquP3kwubhZ1549+T2QoS8tqC/3NYzeZNfxFxqqPOEQtbLUUTR9cPvakz/\niuf3R7grCePwxVYYv53xCynlx17B3Urte3XQeJVLOma9gSHP5W/cgQULThzMd1uOF088/gfPlU//\nFqhw8zWnY1d3UNOf3jp7vFdrqidCSnkngDtHuS1ERER0FBnLszOIiIjoGMYQQURERKYwRBAREZEp\nDBFERERkCkMEERERmcIQQURERKYwRBAREZEpDBFERERkCkMEERERmcIQQURERKYwRBAREZEpDBFE\nRERkypH8FPio60DMke82EI2lXsTtzc374HDYtHy35Xixp7XLjsEIoFr4mtOxayCcl89PUz8FPlYU\nRZmV7zYQjbFMcE/ktRXHF77mdFzQdX3beK9zQoUIIiIiOnpwTAQRERGZwhBBREREpjBEEBERkSkM\nEURERGQKQwQRERGZwhBBREREpjBEEBERkSkMEURERGQKQwQRERGZwhBBREREpjBEEBERkSkMEURE\nRGQKQwQRERGZwhBBREREpjBEEBERkSkMEURERGQKQwQRERGZwhBBREREpjBEEBERkSkMEURERGQK\nQwQRERGZwhBBREREpjBEEBERkSkMEURERGQKQwQRERGZwhBBREREpjBEEBERkSkMEURERGQKQwQR\nERGZwhBBREREpjBEEBERkSkMEURERGQKQwQRERGZwhBBREREpjBEEBERkSkMEURERGSKNd8NyKYo\n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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = plt.figure()\n", "ax = fig.add_subplot(111)\n", "df_percent_t.plot(kind=\"barh\", stacked=True, ax=ax, colormap=\"RdYlGn\", alpha=.8)\n", "ax.legend(ncol=3, loc='upper center', bbox_to_anchor=(0.5, 1.15), frameon=False)\n", "ax.set_frame_on(False)\n", "ax.set_xticks([])\n", "\n", "# add texts\n", "y = 0\n", "for index, row in df_percent_t.iterrows(): # boucle sur les lignes\n", " # on calcule les intervalles \n", " xbounds = [0]\n", " for i in range(len(row)): # len(row) est le nombre d'éléments sur la ligne, 3 ici\n", " xbounds.append(xbounds[i] + row[i])\n", " print(xbounds)\n", " # ajout du texte au centre de chaque intervalle\n", " for i in range(3):\n", " x = (xbounds[i] + xbounds[i+1]) / 2\n", " ax.text(x, y, \"%3.0f%%\" % row[i], \n", " verticalalignment=\"center\",\n", " horizontalalignment=\"center\")\n", " y += 1\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour y voir plus clair sur le calcul des intervalles, voici un exemple :" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 40, 90, 100]\n" ] } ], "source": [ "l = [40, 50, 10]\n", "x = [0]\n", "for i in range(3):\n", " x.append(x[i] + l[i])\n", "print(x)" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python [default]", "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.5.2" } }, "nbformat": 4, "nbformat_minor": 1 }