[seaborn] 09/14: Improve kde computation

Andreas Tille tille at debian.org
Fri Jan 20 15:00:43 UTC 2017


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to tag v0.2.1
in repository seaborn.

commit e790f19e7ac2b8c743cfd7033b38e94f2bc7e13b
Author: mwaskom <mwaskom at stanford.edu>
Date:   Mon Jan 13 23:35:01 2014 -0800

    Improve kde computation
---
 examples/plotting_distributions.ipynb |  20 +++---
 seaborn/distributions.py              | 127 +++++++++++++++++++++++++---------
 seaborn/tests/test_distributions.py   |  52 ++++++++++++++
 3 files changed, 158 insertions(+), 41 deletions(-)

diff --git a/examples/plotting_distributions.ipynb b/examples/plotting_distributions.ipynb
index ed4583e..2e62790 100644
--- a/examples/plotting_distributions.ipynb
+++ b/examples/plotting_distributions.ipynb
@@ -604,7 +604,7 @@
       {
        "metadata": {},
        "output_type": "display_data",
-       "png": "iVBORw0KGgoAAAANSUhEUgAAAYMAAAF8CAYAAAAtoNfeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3WVgFFfbgOF7oxsPcWKEkBBIgDgEd2mRolVapNBSoHhx\nd6doKS9tgeIUd3dJkARNgAAB4kSJy+5+P/hoCdmNYNm05/oHe2by7OzMPDNHJQqFQoEgCILwn6ZR\n1gEIgiAIZU8kA0EQBEEkA0EQBEEkA0EQBAGRDARBEAREMhAEQRAArbIO4E08e5ZW1iEUYmKiB0Bq\nalYZR1Iy5Sne8hQriHjfNxHvm7O0NFL5mXgzEARBEEQyEARBEEQyEARBEBDJQBAEQUAkA0EQBAGR\nDARBEAREMhAEQRAQyUAQBEFAJANBEAQBkQwEQRAEyjAZBAYG0rRpUwCCg4Oxt7enadOmNG3alK1b\nt5ZVWIIgC [...]
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAFtCAYAAAAXupEAAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3WdAFFfXwPH/0jtIlyYiiIJKV+y9JJZYU00s0cSoscfe\nezfWqI9J1NiNvfdewAJ2VERUulTpZXffD74mIruwKCqQ+/ume2f27DBzdvbOvedK5HK5HEEQBKHM\nU/vYAQiCIAglQyR0QRCEckIkdEEQhHJCJHRBEIRyQiR0QRCEckIkdEEQhHJC42O98fPnqR/rrZUy\nNtYFICUl8yNHopqyFG9ZihVEvO+biPftWVgYKn1N3KELgiCUEyKhC4IglBMioQuCIJQTIqELgiCU\nEyKhC4IglBMioQuCIJQTIqELgiCUEyKhC4IglBMioQuCIJQTIqELgiCUE++U0AMCAmjatCkAQUFB\n2NnZ0bRpU [...]
        "text": [
         "<matplotlib.figure.Figure at 0xFFFFFFFFF>"
        ]
@@ -660,7 +660,7 @@
       {
        "metadata": {},
        "output_type": "display_data",
-       "png": "iVBORw0KGgoAAAANSUhEUgAAAYMAAAF8CAYAAAAtoNfeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXVYlVn3v+9Dg3SqoGIhNmEgJmJjd+trjO3M6Khjd3fO\nWGO3YndhIAZhi2BgII2Skuf8/vDnfGfGE6Sg7vu63ut6Z87a+1nPmcPzefbae60lkclkMgQCgUDw\nQ6NW0A4IBAKBoOARYiAQCAQCIQYCgUAgEGIgEAgEAoQYCAQCgQAhBgKBQCAANAragZwQFZWQr/Mb\nGekCEBf3MV+vk18I/wsW4X/BIvxXjIWFgcLPxMpAIBAIBEIMBAKBQCDEQCAQCAQIMRAIBAIBQgwE\nAoFAgBADgUAgECDEQCAQCAQIMRAIBAIBQgwEAoFAgBADgUAgEFCAYnDr1i3c3NwAePbsGfXq1aNB\ngwYMHz4c0 [...]
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAFtCAYAAAAXupEAAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXVYlOn6xz8DQ0qnCioGiE0YiAnY2GLnGmu7u7rq2t2d\nu9baiWJ3YSAGYaEIBgbSKCk58/vD4/7WdYIUxfdzXee6zjlzP897vyPznWfu9w6RVCqVIiAgICDw\n3aNS1A4ICAgICBQMgqALCAgIFBMEQRcQEBAoJgiCLiAgIFBMEARdQEBAoJggCLqAgIBAMUFcVBeO\niUkq1P319bUASEj4UKjXKSwE/4sWwf+iRfBfPqamunJfE07oAgICAsUEQdAFBAQEigmCoAsICAgU\nEwRBFxAQECgmCIIuICAgUEwQBF1AQECgmCAIuoCAgEAxQRB0AQEBgWKCIOgCAgICxQRB0AUEBASK\nCfkS9Fu3b [...]
        "text": [
         "<matplotlib.figure.Figure at 0xFFFFFFFFF>"
        ]
@@ -680,7 +680,7 @@
       {
        "metadata": {},
        "output_type": "display_data",
-       "png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAF8CAYAAAAgvqeZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnWV4VMfbh++V7GbjSlwggSRAcHd3hwItVChFC7QFihV3\np1CkAi3FrTi0OLSUYsElQCBIICHu2ayd9wMv/CmF6IbNtue+Lj5wsWfmx5w55zkz84hEEAQBERER\nERERQGpqASIiIiIixQfRKIiIiIiIvEA0CiIiIiIiLxCNgoiIiIjIC0SjICIiIiLyAtEoiIiIiIi8\nQG5qAQVBo9GRkpJlahk5Ym+vAhB1GglRp/EwB40g6jQ29vYqFIrcX/niSkFERERE5AWiURARERER\neYFoFEREREREXiAaBRERERGRF4hGQURERETkBaJREBERERF5gWgUREREREReIBoFEREREZEXiEZB\nREREROQFo [...]
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAXYAAAFtCAYAAAATT0E9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnWV4VMfbh++V7GbjSlwggRAguLu7Q4EWKpSiBVqkWHF3\nCkUq0FLcikOLQ6EUS3AIIRAkkBD3bNbO+4E/LaUQ3ZAs77mviw9c7M78mDnz7JyZRySCIAiIiIiI\niLwzSItagIiIiIiIcRENu4iIiMg7hmjYRURERN4xRMMuIiIi8o4hGnYRERGRdwzRsIuIiIi8Y8iL\nqmONRkdycmZRdZ8rbG1VAKJOIyHqNB6moBFEncbG1laFQpGz2RZ37CIiIiLvGKJhFxEREXnHEA27\niIiIyDuGaNhFRERE3jFEwy4iIiLyjiEadhEREZF3DNGwi4iIiLxjiIZdRERE5B1DNOwiIiIi7xii\nYRcRERF5x [...]
        "text": [
         "<matplotlib.figure.Figure at 0xFFFFFFFFF>"
        ]
@@ -740,7 +740,7 @@
       {
        "metadata": {},
        "output_type": "display_data",
-       "png": "iVBORw0KGgoAAAANSUhEUgAAAeMAAAECCAYAAADNb78fAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl0VOXBP/DvXWbLJJOA7PsSwx6MLNGELeCCpS5YsS6o\nVEXRLr4tb3sq73nfnp9tlZ/v79S37anUV1tcanGFKIoLRRAhBAir7BAWZRNkyUySmbnb8/sjEEXI\nZJ08M5Pv5xwOTO7Nvd/nDDPfuTN3nqsIIQSIiIhIGlV2ACIioraOZUxERCQZy5iIiEgyljEREZFk\nLGMiIiLJWMZERESSxSxjx3Ewa9YsFBQUoKioCOXl5Rcsf+aZZzB06FAUFRWhqKgIe/bsiWtYIiKi\nVKTHWlhcXAzDMFBSUoK1a9di9uzZKC4url2+ceNGvPLKK8jLy4t7UCIiolQV88h49erVmDx5MgAg\nPz8fZWVlF [...]
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAekAAAECCAYAAADaTS/WAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl0HOWd7/93Lb2ppZZtYeN9t7zL2BgL1Ea2MMY2u8k4\nw2BnEuIYnAQymWicOzC/nN+9zEzIye+e5CYZ4pAQREJyPVkMCmY3YDBIlkAG77sxGK8Y26hb6lYv\nVfX7Q0jYWGptLVUv39c5OlJ31fP05+lW97eruroexbIsCyGEEEKkHNXuAEIIIYRomxRpIYQQIkVJ\nkRZCCCFSlBRpIYQQIkVJkRZCCCFSlBRpIYQQIkXpiRaapsm3vvUtduzYgcvl4rHHHmPcuHGXrHfP\nPfdQUFDAww8/DMCsWbPIz88HYOzYsfz2t7/thehCCCFEZktYpCsrK4lGo1RXV1NbW0t5eTmVlZUX\nrfPoo4+ya [...]
        "text": [
         "<matplotlib.figure.Figure at 0xFFFFFFFFF>"
        ]
@@ -794,7 +794,7 @@
       {
        "metadata": {},
        "output_type": "display_data",
-       "png": "iVBORw0KGgoAAAANSUhEUgAAAeMAAAECCAYAAADNb78fAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlYE+fiPfCThC0swbXuC2DdRVEEBEVwRXFXrG3dFbX2\ntlqp/am9vb3XLtrefmt369Wq1Spai2ABte4iIFRwr1oVrbuCVkmQaEgyvz+stFQJa3iTcD7P46Nh\nkpnzCslhkpl3ZJIkSSAiIiJh5KIDEBERVXcsYyIiIsFYxkRERIKxjImIiARjGRMREQnGMiYiIhLM\nZBkbjUbMmDEDgYGBCA0NRVZWVpHlS5YsQfv27REaGorQ0FCcPXvWrGGJiIhskZ2phXFxcdDpdEhN\nTUV6ejqioqIQFxdXuPzw4cNYu3YtfHx8zB6UiIjIVpncM05JSUFYWBgAwN/fHxkZGUWWZ2Zm4v33\n30ePHj2we [...]
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAekAAAECCAYAAADaTS/WAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlclPXe//HXbMgwMIOaKS6ZqbiTOwaG4oa7YdGmLR6k\ntO104rbfqU7nPtl9ynPuzuk+beZJo7Iic8MkFUlJEwRBTTOXlMxK3BdmkIFhlt8fBkdcRpaBa2b4\nPB8PHjpzXd8v7+8sfOa65rq+l8rlcrkQQgghhNdRKx1ACCGEEFcnRVoIIYTwUlKkhRBCCC8lRVoI\nIYTwUlKkhRBCCC8lRVoIIYTwUlp3C51OJ4899hi7d++mWbNmLFy4kM6dO1+x3iOPPELLli159dVX\nAejfvz8mkwmAW265hUWLFjVAdCGEEMK/uS3SaWlp2Gw2cnJyyMvLIzk5mbS0tGrrLFiwgD179jB8\n+HAAysrKA [...]
        "text": [
         "<matplotlib.figure.Figure at 0xFFFFFFFFF>"
        ]
@@ -823,7 +823,7 @@
       {
        "metadata": {},
        "output_type": "display_data",
-       "png": "iVBORw0KGgoAAAANSUhEUgAAAeMAAAECCAYAAADNb78fAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xd8VGW+P/DP9EzKpEACISGhhA6hE0wgIYKAoigo6ioq\nK6JgWffKen8r3r27F3eVdb3rVXftimVdLJRIEBCkk5Bg6B0SagLpZNImmXLO74+BEyJkEtKemcnn\nva99ke/MmZnPY8p3zplznkcly7IMIiIiEkYtOgAREVFHx2ZMREQkGJsxERGRYGzGREREgrEZExER\nCcZmTEREJJjLZixJEubPn4/4+HgkJycjJyen3v1vvvkmBg8ejOTkZCQnJ+PkyZNtGpaIiMgbaV3d\nmZKSAqvVivT0dGRmZmLhwoVISUlR7t+7dy++/PJLDB8+vM2DEhEReSuXe8ZpaWmYOnUqACAuLg5Z\nWVn17t+zZ [...]
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAekAAAECCAYAAADaTS/WAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl8VPW9+P/XLElmskwSAoSQEJZAAIGwE8xgICASVFSs\nqC24RhRtvdfKpd/q/fbeb+291evtr7a1bnWJ1VasgkRRFCMEkYQEg0BYBELYIWENmayznfn9MXBC\nahgSSHJmJu/n48GD+cw5nzPvd5KZ95zt89F5PB4PQgghhPA7eq0DEEIIIUTrpEgLIYQQfkqKtBBC\nCOGnpEgLIYQQfkqKtBBCCOGnpEgLIYQQfsroa6GiKDz22GOUlZURFhbGG2+8QUpKyg/We/jhh4mL\ni+PZZ58FYNy4cURHRwMwaNAg3nzzzU4IXQghhAhuPot0Xl4eDoeDoqIiSkpKWLx4MXl5eS3Wee21\n19ixYwfTp [...]
        "text": [
         "<matplotlib.figure.Figure at 0xFFFFFFFFF>"
        ]
@@ -851,7 +851,7 @@
       {
        "metadata": {},
        "output_type": "display_data",
-       "png": "iVBORw0KGgoAAAANSUhEUgAAAQUAAAGpCAYAAACESCMEAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl8VPW9//HXOXNmy56wSCDsqwioLLIpNIJLRetWWvHi\nVtuqv3ur17b21vYuLdda9baK7XVp60Jrre11Q3ErVMEFRQUUEGQRBGUPWxKSmcxyzu+PEWRQkswk\nOTOTvJ+PRx9WMjPnw5h5z/d8z/f7OYbjOA4iIp8xM12AiGQXhYKIJFEoiEgShYKIJFEoiEgShYKI\nJGlRKOzevZuePXuyfv361qpHRDIs7VCIRqNcc8015Ofnt2Y9IpJhaYfCTTfdxHXXXUd5eXlr1iMi\nGZZWKMyZM4cuXbpw5plnAqBFkSLth5HOMufJkydjGAaGYfD+++8zePBgnnnmGY477rgvfbxtO8Ri\n8RYX6wbL8 [...]
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAQgAAAGpCAYAAABxtqi0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XmcFPWd//FXVVdfc/QwwHAOIDAcKqKIyi2OV1SMt8Y7\nZkmi+eVwXX9mY/Z37M81cTcbE0w2Rl0P4kbdRA1EjYmaiBoRD8ALkVNF7uGcs6/qqt8fDQaVHmb6\nqOnueT8fDx/iTPf3U+VMv6n61rc+Zbiu6yIichBmT2+AiBQvBYSIZKSAEJGMFBAikpECQkQyUkCI\nSEY5BURTUxPDhg1jzZo1+doeESkiWQdEMpnk2muvpbKyMp/bIyJFJOuAuOmmm/jGN77B4MGD87k9\nIlJEsgqI+fPnU1dXx+mnnw6AFmOKlCcjm6XWs2fPxjAMDMPgrbfeYty4cfz+979n4MCBB32947jY\ndirnjc3Es [...]
        "text": [
         "<matplotlib.figure.Figure at 0xFFFFFFFFF>"
        ]
@@ -878,7 +878,7 @@
       {
        "metadata": {},
        "output_type": "display_data",
-       "png": "iVBORw0KGgoAAAANSUhEUgAAAeMAAAERCAYAAABILc8qAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlwFOedN/Bvd889oxkdiEsSl0AYBALMISJxCV9siA+8\nYTcbn4mXmDgbuzZstmKntlLl7Nqs/4jfbGrtpd6ssddvQrwb22TxFWODsUEWWAJzCRCIQwgQSIDm\nnumZ7n7/EBKWQSNpNKOe4/upcoE0rZnfYzHznWf66d8jaJqmgYiIiHQj6l0AERFRtmMYExER6Yxh\nTEREpDOGMRERkc4YxkRERDpjGBMREeksZhirqoq1a9eiqqoKNTU1aG5u7nX7iy++iBkzZqCmpgY1\nNTVoampKarFERESZyBDrxs2bN0OWZdTW1mL37t1Yt24dNm/e3HP73r178frrr2POnDlJL5SIiChT\nxZwZ79q1C [...]
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAekAAAERCAYAAABfD1/jAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlwXOWZ+PvvWXqXurVYtmV5wbYsb1iAMRZIYBCrCRBi\najy/XGySEMfBIYHJxONUIJWaKuY3IcmtylQmQwy3CIZwM55MAuj+zGRIzMTYwbJE5ID3Vd6wJXm3\nulu9nO4+5/4hJCxstWWppd6eT5XL6j6Lnkfdp59+z3nP+yqWZVkIIYQQIuOo6Q5ACCGEEJcnRVoI\nIYTIUFKkhRBCiAwlRVoIIYTIUFKkhRBCiAwlRVoIIYTIUHqyhaZp8uSTT7J9+3YcDgcvv/wyU6dO\nvWS9r3/965SWlvL8888DMHfuXHw+HwBTpkzhl7/85TCELoQQQuS2pEW6oaEBwzBobGykubmZlStX\n0tDQ0Gedl [...]
        "text": [
         "<matplotlib.figure.Figure at 0xFFFFFFFFF>"
        ]
@@ -954,7 +954,7 @@
       {
        "metadata": {},
        "output_type": "display_data",
-       "png": "iVBORw0KGgoAAAANSUhEUgAAAW4AAAFxCAYAAABTIkLBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAD4RJREFUeJzt3X9o3Hf9wPHX5eJmlnaXiocouPmFoX85JtNvMW2aXMSg\naBHHItWtc1hERXCI+Ie17I+QRS2I7T8bgsVIO1CUdTJx0EG/qa1hA/8Q/AGWyczmH279suQso6VZ\nLt8/upXv5q5N7kc+90ofj/+Sz919Xlzunnnnk/vclVZXV1cDgDT6ih4AgPURboBkhBsgGeEGSEa4\nAZIRboBk2gr3Sy+9FO9973vj7NmznZoHgGtoOdzLy8vxla98JQYHBzs5DwDX0HK4v/3tb8fXvva1\nePe7393JeQC4hpbCPTs7G9VqNSYmJiIiwsmXABun1Mop76Ojo1EqlaJUKsUf//jH+MAHPhC//vWv\n413vetdbX [...]
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAW4AAAFxCAYAAABTIkLBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAD3VJREFUeJzt3V2InPW9wPHfZKfmrHmZTesgCs3phdQri61IiBM3O1FT\noQ1ScUVtY6VBVASlFAuxF2JQVxfE5EYpNHQlyqEoxmIpaIrGJWsUelHoCyhazOqFLz1mJ0GSk307\nF1XP8WWS3ZnZfea3+XxuQubt+TE7890/z84zT2l2dnY2AEhjWdEDADA/wg2QjHADJCPcAMkIN0Ay\nwg2QTFvh/uCDD+Kb3/xmvPHGG52aB4BTaDnck5OTccstt8SKFSs6OQ8Ap9ByuO+666647bbb4pxz\nzunkPACcQkvhHhkZiWq1Gps3b46ICAdfAiyeUiuHvG/cuDFKpVKUSqX4y1/+Eueff378/ve/j7PP\nPvsrb3/ix [...]
        "text": [
         "<matplotlib.figure.Figure at 0xFFFFFFFFF>"
        ]
@@ -1041,7 +1041,7 @@
       {
        "metadata": {},
        "output_type": "display_data",
-       "png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAFxCAYAAACImejjAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsvVlsZNd97vvbu+aZRVZxqOJMNnse1eqW1IoTJU5sQI4v\nZFhA9OCLHMsd4NgXcE4CA3oIECBBjCAPVp5sGJDhgyiBcpALR+cqPshJAAXRiQc5GmI51tDdbLKb\nZHEeap723us+rKpikc1mk8W5uH4AUazaZNUqFuurtb/1X99fE0IIFAqFQtFU6Ac9AIVCoVDsPkrc\nFQqFoglR4q5QKBRNiBJ3hUKhaEKUuCsUCkUTosRdoVAompCGxL1cLvOlL32JT33qU1y/fp033nhj\nzfGXX36Zc+fO8cwzz/DMM89w69atXRmsQqFQKLaGvZFf+pu/+Rui0Sivvvoqy8vLXLp0id/+7d+u\nHX/vvfd49 [...]
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAFxCAYAAACImejjAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X9wVPW9//HX2c1m82uzEAgkIVC8TfklRnOJoRrQLqVi\nJ9I7eC9tM62WGtLp1RkoOE6d1mpva5lOZy5we2egWiy02sv9NcoM19te28u1KN7CDTDSqdzKtV8l\nvxYChM0mJJvsnvP9Y8NChGzJZskmnzwfMw7sHnb3Tdw8PZ6cz1nLcRxHAACjuDI9AAAg/Yg7ABiI\nuAOAgYg7ABiIuAOAgYg7ABgopbgPDAzooYce0j333KOlS5dq//79Q7Zv27ZNixcvViAQUCAQ0Lvv\nvpuWYQEANyYrlQf9/Oc/V3FxsV588UV1dnbqjjvu0OrVqxPbjx07phdffFFVVVVpGxQAcOOsVBYx\n9fT0yHEcF [...]
        "text": [
         "<matplotlib.figure.Figure at 0xFFFFFFFFF>"
        ]
diff --git a/seaborn/distributions.py b/seaborn/distributions.py
index 159d409..278cc63 100644
--- a/seaborn/distributions.py
+++ b/seaborn/distributions.py
@@ -2,11 +2,13 @@
 from __future__ import division
 import colorsys
 import numpy as np
+from scipy import stats
 import pandas as pd
 import statsmodels.api as sm
 import matplotlib as mpl
 import matplotlib.pyplot as plt
 from six.moves import range
+import warnings
 import moss
 
 from seaborn.utils import (color_palette, husl_palette, blend_palette,
@@ -115,6 +117,7 @@ def _box_colors(vals, color):
 
     return colors, gray
 
+
 def boxplot(vals, groupby=None, names=None, join_rm=False, order=None,
             color=None, alpha=None, fliersize=3, linewidth=1.5, widths=.8,
             ax=None, **kwargs):
@@ -225,7 +228,6 @@ def boxplot(vals, groupby=None, names=None, join_rm=False, order=None,
 
 def violin(*args, **kwargs):
     """Deprecated old name for violinplot. Please update your code."""
-    import warnings
     warnings.warn("violin() is deprecated; please use violinplot()",
                   UserWarning)
     return violinplot(*args, **kwargs)
@@ -379,6 +381,14 @@ def violinplot(vals, groupby=None, inner="box", color=None, positions=None,
     return ax
 
 
+def _freedman_diaconis_bins(a):
+    """Calculate number of hist bins using Freedman-Diaconis rule."""
+    # From http://stats.stackexchange.com/questions/798/
+    a = np.asarray(a)
+    h = 2 * moss.iqr(a) / (len(a) ** (1 / 3))
+    return np.ceil((a.max() - a.min()) / h)
+
+
 def distplot(a, bins=None, hist=True, kde=True, rug=False, fit=None,
              hist_kws=None, kde_kws=None, rug_kws=None, fit_kws=None,
              color=None, vertical=False, axlabel=None, ax=None):
@@ -450,9 +460,7 @@ def distplot(a, bins=None, hist=True, kde=True, rug=False, fit=None,
 
     if hist:
         if bins is None:
-            # From http://stats.stackexchange.com/questions/798/
-            h = 2 * moss.iqr(a) * len(a) ** -(1 / 3)
-            bins = (a.max() - a.min()) / h
+            bins = _freedman_diaconis_bins(a)
         hist_alpha = hist_kws.pop("alpha", 0.4)
         orientation = "horizontal" if vertical else "vertical"
         hist_color = hist_kws.pop("color", color)
@@ -491,8 +499,8 @@ def distplot(a, bins=None, hist=True, kde=True, rug=False, fit=None,
     return ax
 
 
-def _univariate_kde(data, shade, vertical, kernel, bw, gridsize, cut,
-                    clip, legend, ax, **kwargs):
+def _univariate_kdeplot(data, shade, vertical, kernel, bw, gridsize, cut,
+                        clip, legend, ax, **kwargs):
     """Plot a univariate kernel density estimate on one of the axes."""
 
     # Sort out the clipping
@@ -500,10 +508,22 @@ def _univariate_kde(data, shade, vertical, kernel, bw, gridsize, cut,
         clip = (-np.inf, np.inf)
 
     # Calculate the KDE
-    fft = kernel == "gau"
-    kde = sm.nonparametric.KDEUnivariate(data)
-    kde.fit(kernel, bw, fft, gridsize=gridsize, cut=cut, clip=clip)
-    x, y = kde.support, kde.density
+    try:
+        # Prefer using statsmodels for kernel flexibility
+        x, y = _statsmodels_univariate_kde(data, kernel, bw,
+                                           gridsize, cut, clip)
+    except ImportError:
+        # Fall back to scipy if missing statsmodels
+        if kernel != "gau":
+            kernel = "gau"
+            msg = "Kernel other than `gau` requires statsmodels."
+            warnings.warn(msg, UserWarning)
+        x, y = _scipy_univariate_kde(data, bw, gridsize, cut, clip)
+
+    # Make sure the density is nonnegative
+    y = np.amax(np.c_[np.zeros_like(y), y], axis=1)
+
+    # Flip the data if the plot should be on the y axis
     if vertical:
         x, y = y, x
 
@@ -537,8 +557,29 @@ def _univariate_kde(data, shade, vertical, kernel, bw, gridsize, cut,
     return ax
 
 
-def _bivariate_kde(x, y, filled, kernel, bw, gridsize, cut, clip, axlabel, ax,
-                   **kwargs):
+def _statsmodels_univariate_kde(data, kernel, bw, gridsize, cut, clip):
+    """Compute a univariate kernel density estimate using statsmodels."""
+    from statsmodels import nonparametric
+    fft = kernel == "gau"
+    kde = nonparametric.kde.KDEUnivariate(data)
+    kde.fit(kernel, bw, fft, gridsize=gridsize, cut=cut, clip=clip)
+    grid, y = kde.support, kde.density
+    return grid, y
+
+
+def _scipy_univariate_kde(data, bw, gridsize, cut, clip):
+    """Compute a univariate kernel density estimate using scipy."""
+    kde = stats.gaussian_kde(data, bw_method=bw)
+    if isinstance(bw, str):
+        bw = "scotts" if bw == "scott" else bw
+        bw = getattr(kde, "%s_factor" % bw)()
+    grid = _kde_support(data, bw, gridsize, cut, clip)
+    y = kde(grid)
+    return grid, y
+
+
+def _bivariate_kdeplot(x, y, filled, kernel, bw, gridsize, cut, clip, axlabel,
+                       ax, **kwargs):
     """Plot a joint KDE estimate as a bivariate contour plot."""
 
     # Determine the clipping
@@ -548,18 +589,10 @@ def _bivariate_kde(x, y, filled, kernel, bw, gridsize, cut, clip, axlabel, ax,
         clip = [clip, clip]
 
     # Calculate the KDE
-    if isinstance(bw, str):
-        bw_func = getattr(sm.nonparametric.bandwidths, "bw_" + bw)
-        x_bw = bw_func(x)
-        y_bw = bw_func(y)
-        bw = [x_bw, y_bw]
-    elif np.isscalar(bw):
-        bw = [bw, bw]
-    kde = sm.nonparametric.KDEMultivariate([x, y], "cc", bw)
-    x_support = _kde_support(x, kde.bw[0], gridsize, cut, clip[0])
-    y_support = _kde_support(y, kde.bw[1], gridsize, cut, clip[1])
-    xx, yy = np.meshgrid(x_support, y_support)
-    z = kde.pdf([xx.ravel(), yy.ravel()]).reshape(xx.shape)
+    try:
+        xx, yy, z = _statsmodels_bivariate_kde(x, y, bw, gridsize, cut, clip)
+    except ImportError:
+        xx, yy, z = _scipy_bivariate_kde(x, y, bw, gridsize, cut, clip)
 
     # Plot the contours
     n_levels = kwargs.pop("n_levels", 10)
@@ -581,6 +614,38 @@ def _bivariate_kde(x, y, filled, kernel, bw, gridsize, cut, clip, axlabel, ax,
     return ax
 
 
+def _statsmodels_bivariate_kde(x, y, bw, gridsize, cut, clip):
+    """Compute a bivariate kde using statsmodels."""
+    from statsmodels import nonparametric
+    if isinstance(bw, str):
+        bw_func = getattr(nonparametric.bandwidths, "bw_" + bw)
+        x_bw = bw_func(x)
+        y_bw = bw_func(y)
+        bw = [x_bw, y_bw]
+    elif np.isscalar(bw):
+        bw = [bw, bw]
+    kde = nonparametric.kernel_density.KDEMultivariate([x, y], "cc", bw)
+    x_support = _kde_support(x, kde.bw[0], gridsize, cut, clip[0])
+    y_support = _kde_support(y, kde.bw[1], gridsize, cut, clip[1])
+    xx, yy = np.meshgrid(x_support, y_support)
+    z = kde.pdf([xx.ravel(), yy.ravel()]).reshape(xx.shape)
+    return xx, yy, z
+
+
+def _scipy_bivariate_kde(x, y, bw, gridsize, cut, clip):
+    """Compute a bivariate kde using scipy."""
+    data = np.c_[x, y]
+    kde = stats.gaussian_kde(data.T)
+    if isinstance(bw, str):
+        bw = "scotts" if bw == "scott" else bw
+        bw = getattr(kde, "%s_factor" % bw)()
+    x_support = _kde_support(data[:, 0], bw, gridsize, cut, clip[0])
+    y_support = _kde_support(data[:, 1], bw, gridsize, cut, clip[1])
+    xx, yy = np.meshgrid(x_support, y_support)
+    z = kde([xx.ravel(), yy.ravel()]).reshape(xx.shape)
+    return xx, yy, z
+
+
 def kdeplot(data, data2=None, shade=False, vertical=False, kernel="gau",
             bw="scott", gridsize=100, cut=3, clip=None, legend=True, ax=None,
             **kwargs):
@@ -630,22 +695,22 @@ def kdeplot(data, data2=None, shade=False, vertical=False, kernel="gau",
     bivariate = False
     if isinstance(data, np.ndarray) and np.ndim(data) > 1:
         bivariate = True
-        x, y = data.T
+        x, y = data.astype(np.float64).T
     elif isinstance(data, pd.DataFrame) and np.ndim(data) > 1:
         bivariate = True
-        x = data.iloc[:, 0]
-        y = data.iloc[:, 1]
+        x = data.iloc[:, 0].values.astype(np.float64)
+        y = data.iloc[:, 1].values.astype(np.float64)
     elif data2 is not None:
         bivariate = True
         x = data
         y = data2
 
     if bivariate:
-        ax = _bivariate_kde(x, y, shade, kernel, bw, gridsize,
-                            cut, clip, legend, ax, **kwargs)
+        ax = _bivariate_kdeplot(x, y, shade, kernel, bw, gridsize,
+                                cut, clip, legend, ax, **kwargs)
     else:
-        ax = _univariate_kde(data, shade, vertical, kernel, bw,
-                             gridsize, cut, clip, legend, ax, **kwargs)
+        ax = _univariate_kdeplot(data, shade, vertical, kernel, bw,
+                                 gridsize, cut, clip, legend, ax, **kwargs)
 
     return ax
 
diff --git a/seaborn/tests/test_distributions.py b/seaborn/tests/test_distributions.py
index 1b74aeb..ec88615 100644
--- a/seaborn/tests/test_distributions.py
+++ b/seaborn/tests/test_distributions.py
@@ -161,3 +161,55 @@ class TestBoxReshaping(object):
         with nt.assert_raises(ValueError):
             dist._box_reshape(self.x, None, None, range(5))
 
+
+class TestKDE(object):
+
+    rs = np.random.RandomState(0)
+    x = rs.randn(50)
+    y = rs.randn(50)
+    kernel = "gau"
+    bw = "scott"
+    gridsize = 128
+    clip = (-np.inf, np.inf)
+    cut = 3
+
+    def test_scipy_univariate_kde(self):
+        """Test the univariate KDE estimation with scipy."""
+        grid, y = dist._scipy_univariate_kde(self.x, self.bw, self.gridsize,
+                                             self.cut, self.clip)
+        nt.assert_equal(len(grid), self.gridsize)
+        nt.assert_equal(len(y), self.gridsize)
+        for bw in ["silverman", .2]:
+            dist._scipy_univariate_kde(self.x, bw, self.gridsize,
+                                       self.cut, self.clip)
+
+    def test_statsmodels_univariate_kde(self):
+        """Test the univariate KDE estimation with statsmodels."""
+        grid, y = dist._statsmodels_univariate_kde(self.x, self.kernel,
+                                                   self.bw, self.gridsize,
+                                                   self.cut, self.clip)
+        nt.assert_equal(len(grid), self.gridsize)
+        nt.assert_equal(len(y), self.gridsize)
+        for bw in ["silverman", .2]:
+            dist._statsmodels_univariate_kde(self.x, self.kernel, bw,
+                                             self.gridsize, self.cut,
+                                             self.clip)
+
+    def test_scipy_bivariate_kde(self):
+        """Test the bivariate KDE estimation with scipy."""
+        clip = [self.clip, self.clip]
+        x, y, z = dist._scipy_bivariate_kde(self.x, self.y, self.bw,
+                                            self.gridsize, self.cut, clip)
+        nt.assert_equal(x.shape, (self.gridsize, self.gridsize))
+        nt.assert_equal(y.shape, (self.gridsize, self.gridsize))
+        nt.assert_equal(len(z), self.gridsize)
+
+    def test_statsmodels_bivariate_kde(self):
+        """Test the bivariate KDE estimation with statsmodels."""
+        clip = [self.clip, self.clip]
+        x, y, z = dist._statsmodels_bivariate_kde(self.x, self.y, self.bw,
+                                                  self.gridsize,
+                                                  self.cut, clip)
+        nt.assert_equal(x.shape, (self.gridsize, self.gridsize))
+        nt.assert_equal(y.shape, (self.gridsize, self.gridsize))
+        nt.assert_equal(len(z), self.gridsize)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/seaborn.git



More information about the debian-science-commits mailing list