[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