Skip to content

Instantly share code, notes, and snippets.

@msund
Last active June 6, 2016 12:08
Show Gist options
  • Save msund/11349097 to your computer and use it in GitHub Desktop.
Save msund/11349097 to your computer and use it in GitHub Desktop.
All of 'em
{
"metadata": {
"name": "Three new matplotlib plots"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": "20 Interactive Plots from matplotlib, prettyplotlib, Stack Overflow, and seaborn"
},
{
"cell_type": "code",
"collapsed": false,
"input": "%matplotlib inline\nimport matplotlib.pyplot as plt # side-stepping mpl backend\nimport matplotlib.gridspec as gridspec # subplots\nimport numpy as np",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 16
},
{
"cell_type": "code",
"collapsed": false,
"input": "from matplotlylib import fig_to_plotly\nusername = \"IPython.Demo\"\napi_key = \"1fw3zw2o13\"",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 17
},
{
"cell_type": "code",
"collapsed": false,
"input": "import plotly\nplotly.__version__",
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 18,
"text": "'0.5.9'"
}
],
"prompt_number": 18
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": "I. Plotly for Teaching: Software Carpentry Notebook"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "These first two are drawn from the excellent work at Software Carpenty. Check out [SWC repo](http://nbviewer.ipython.org/github/swcarpentry/notebooks/blob/master/matplotlib.ipynb) for more."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig1 = plt.figure()\n\n#generate some data\nx = np.array(range(20))\ny = 3 + 0.5 * x + np.random.randn(20)\n\n#plot the data\nplt.plot(x, y, 'bo')\n\nfig_to_plotly(fig1, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3183/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 19,
"text": "<IPython.core.display.HTML at 0x10bb19b90>"
}
],
"prompt_number": 19
},
{
"cell_type": "code",
"collapsed": false,
"input": "x = np.array(range(20))\ny = 3 + 0.5 * x + np.random.randn(20)\nz = 2 + 0.9 * x + np.random.randn(20)",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 20
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig2 = plt.figure()\n\n#plot the data\nplt.plot(x, y, 'bo')\nplt.hold(True)\nplt.plot(x, z, 'r^')\n\nfig_to_plotly(fig2, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3184/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 21,
"text": "<IPython.core.display.HTML at 0x10bbdf7d0>"
}
],
"prompt_number": 21
},
{
"cell_type": "markdown",
"metadata": {},
"source": "One special Plotly feature is that you'll get a URL for your call. The data always lives with the graph. The graph we just made is here:\n\nhttps://plot.ly/~IPython.Demo/3080\n\nAnd I've gone in to make a copy of the graph, and shared the data here:\n\nhttps://plot.ly/~MattSundquist/1190"
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": "II. matplotlib Gallery graphs"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "For matplotlib experts, you'll recognize these graphs from the [matplotlib gallery](matplotlib.org/gallery.html). Let us know if you find others you like or need translated. \n\nIn addition to matplotlib and Plotly's own Python API, You can also use Plotly's other [APIs](https://plot.ly/api) for MATLAB, R, Perl, Julia, and REST to write to graphs. \n\nThat means you and I could edit the same graph with any language. We can even edit the graph and data from the GUI, so technical and non-technical teams can work together. And all the graphs go to your profile, like this: https://plot.ly/~IPython.Demo.\n\nYou also control [the privacy](http://plot.ly/python/privacy) by setting `world_readable` to =false or =true, and can control your [sharing](http://plot.ly/python/file-sharing)."
},
{
"cell_type": "markdown",
"metadata": {},
"source": "First up, an example from [pylab](http://matplotlib.org/examples/pylab_examples/arctest.html)."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig3 = plt.figure()\n\nfrom pylab import *\n\ndef f(t):\n 'a damped exponential'\n s1 = cos(2*pi*t)\n e1 = exp(-t)\n return multiply(s1,e1)\n\nt1 = arange(0.0, 5.0, .2)\n\n\nl = plot(t1, f(t1), 'ro')\nsetp(l, 'markersize', 30)\nsetp(l, 'markerfacecolor', 'b')\n\nfig_to_plotly(fig3, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3185/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 22,
"text": "<IPython.core.display.HTML at 0x10dbac990>"
}
],
"prompt_number": 22
},
{
"cell_type": "markdown",
"metadata": {},
"source": "You can also plot with Plotly with pandas, NumPy, datetime, and more of your favorite Python tools. We've already imported numpy and matplotlib; here we've kept them in so you can simply copy and paste these examples into your own NB. "
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig4 = plt.figure()\n\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# make a little extra space between the subplots\nplt.subplots_adjust(wspace=0.5)\n\ndt = 0.01\nt = np.arange(0, 30, dt)\nnse1 = np.random.randn(len(t)) # white noise 1\nnse2 = np.random.randn(len(t)) # white noise 2\nr = np.exp(-t/0.05)\n\ncnse1 = np.convolve(nse1, r, mode='same')*dt # colored noise 1\ncnse2 = np.convolve(nse2, r, mode='same')*dt # colored noise 2\n\n# two signals with a coherent part and a random part\ns1 = 0.01*np.sin(2*np.pi*10*t) + cnse1\ns2 = 0.01*np.sin(2*np.pi*10*t) + cnse2\n\nplt.subplot(211)\nplt.plot(t, s1, 'b-', t, s2, 'g-')\nplt.xlim(0,5)\nplt.xlabel('time')\nplt.ylabel('s1 and s2')\nplt.grid(True)\n\nplt.subplot(212)\ncxy, f = plt.csd(s1, s2, 256, 1./dt)\nplt.ylabel('CSD (db)')\n\nfig_to_plotly(fig4, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3186/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 23,
"text": "<IPython.core.display.HTML at 0x10db4b090>"
}
],
"prompt_number": 23
},
{
"cell_type": "markdown",
"metadata": {},
"source": "Another subplotting example. Note if you double-click, Plotly auto-sizes the plot. We initially draw it based on matplotlib defaults, but you can change the zoom and then save and share it how you'd like."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig5 = plt.figure()\n\nfrom pylab import figure, show\nfrom numpy import arange, sin, pi\n\nt = arange(0.0, 1.0, 0.01)\n\nfig = figure(1)\n\nax1 = fig.add_subplot(211)\nax1.plot(t, sin(2*pi*t))\nax1.grid(True)\nax1.set_ylim( (-2,2) )\nax1.set_ylabel('1 Hz')\nax1.set_title('A sine wave or two')\n\nfor label in ax1.get_xticklabels():\n label.set_color('r')\n\n\nax2 = fig.add_subplot(212)\nax2.plot(t, sin(2*2*pi*t))\nax2.grid(True)\nax2.set_ylim( (-2,2) )\nl = ax2.set_xlabel('Hi mom')\nl.set_color('g')\nl.set_fontsize('large')\n\nfig_to_plotly(fig5, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3187/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 24,
"text": "<IPython.core.display.HTML at 0x10e69b810>"
}
],
"prompt_number": 24
},
{
"cell_type": "markdown",
"metadata": {},
"source": "From the gallery here we're shwoing [Anscombe's quartet](http://matplotlib.org/examples/pylab_examples/anscombe.html). You might also like Plotly's [blog post](blog.plot.ly/post/68951620673/why-graph-anscombes-quartet) on the subject."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig6 = plt.figure()\n\nfrom __future__ import print_function\n\"\"\"\nEdward Tufte uses this example from Anscombe to show 4 datasets of x\nand y that have the same mean, standard deviation, and regression\nline, but which are qualitatively different.\n\nmatplotlib fun for a rainy day\n\"\"\"\n\nfrom pylab import *\n\nx = array([10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5])\ny1 = array([8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84, 4.82, 5.68])\ny2 = array([9.14, 8.14, 8.74, 8.77, 9.26, 8.10, 6.13, 3.10, 9.13, 7.26, 4.74])\ny3 = array([7.46, 6.77, 12.74, 7.11, 7.81, 8.84, 6.08, 5.39, 8.15, 6.42, 5.73])\nx4 = array([8,8,8,8,8,8,8,19,8,8,8])\ny4 = array([6.58,5.76,7.71,8.84,8.47,7.04,5.25,12.50,5.56,7.91,6.89])\n\ndef fit(x):\n return 3+0.5*x\n\n\n\nxfit = array( [amin(x), amax(x) ] )\n\nsubplot(221)\nplot(x,y1,'ks', xfit, fit(xfit), 'r-', lw=2)\naxis([2,20,2,14])\nsetp(gca(), xticklabels=[], yticks=(4,8,12), xticks=(0,10,20))\ntext(3,12, 'I', fontsize=20)\n\nsubplot(222)\nplot(x,y2,'ks', xfit, fit(xfit), 'r-', lw=2)\naxis([2,20,2,14])\nsetp(gca(), xticklabels=[], yticks=(4,8,12), yticklabels=[], xticks=(0,10,20))\ntext(3,12, 'II', fontsize=20)\n\nsubplot(223)\nplot(x,y3,'ks', xfit, fit(xfit), 'r-', lw=2)\naxis([2,20,2,14])\ntext(3,12, 'III', fontsize=20)\nsetp(gca(), yticks=(4,8,12), xticks=(0,10,20))\n\nsubplot(224)\n\nxfit = array([amin(x4),amax(x4)])\nplot(x4,y4,'ks', xfit, fit(xfit), 'r-', lw=2)\naxis([2,20,2,14])\nsetp(gca(), yticklabels=[], yticks=(4,8,12), xticks=(0,10,20))\ntext(3,12, 'IV', fontsize=20)\n\n#verify the stats\npairs = (x,y1), (x,y2), (x,y3), (x4,y4)\nfor x,y in pairs:\n print ('mean=%1.2f, std=%1.2f, r=%1.2f'%(mean(y), std(y), corrcoef(x,y)[0][1]))\n\nfig_to_plotly(fig6, username, api_key, notebook= True)",
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": "mean=7.50, std=1.94, r=0.82\nmean=7.50, std=1.94, r=0.82\nmean=7.50, std=1.94, r=0.82\nmean=7.50, std=1.94, r=0.82\n"
},
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3188/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 25,
"text": "<IPython.core.display.HTML at 0x10e6cff90>"
}
],
"prompt_number": 25
},
{
"cell_type": "markdown",
"metadata": {},
"source": "Plotly also reads the label types in this [damped oscillation](http://matplotlib.org/examples/pylab_examples/legend_demo2.html) graph."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig7 = plt.figure()\n# Make a legend for specific lines.\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\nt1 = np.arange(0.0, 2.0, 0.1)\nt2 = np.arange(0.0, 2.0, 0.01)\n\n# note that plot returns a list of lines. The \"l1, = plot\" usage\n# extracts the first element of the list into l1 using tuple\n# unpacking. So l1 is a Line2D instance, not a sequence of lines\nl1, = plt.plot(t2, np.exp(-t2))\nl2, l3 = plt.plot(t2, np.sin(2 * np.pi * t2), '--go', t1, np.log(1 + t1), '.')\nl4, = plt.plot(t2, np.exp(-t2) * np.sin(2 * np.pi * t2), 'rs-.')\n\nplt.legend( (l2, l4), ('oscillatory', 'damped'), 'upper right', shadow=True)\nplt.xlabel('time')\nplt.ylabel('volts')\nplt.title('Damped oscillation')\n\nfig_to_plotly(fig7, username, api_key, notebook= True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3189/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 26,
"text": "<IPython.core.display.HTML at 0x10e813ad0>"
}
],
"prompt_number": 26
},
{
"cell_type": "markdown",
"metadata": {},
"source": "[histogram](http://matplotlib.org/examples/statistics/histogram_demo_features.html)"
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig8 = plt.figure()\n\nimport numpy as np\nimport matplotlib.mlab as mlab\nimport matplotlib.pyplot as plt\n\n\n# example data\nmu = 100 # mean of distribution\nsigma = 15 # standard deviation of distribution\nx = mu + sigma * np.random.randn(10000)\n\nnum_bins = 50\n# the histogram of the data\nn, bins, patches = plt.hist(x, num_bins, normed=1, facecolor='green', alpha=0.5)\n# add a 'best fit' line\ny = mlab.normpdf(bins, mu, sigma)\nplt.plot(bins, y, 'r--')\nplt.xlabel('Smarts')\nplt.ylabel('Probability')\nplt.title(r'Histogram of IQ: $\\mu=100$, $\\sigma=15$')\n\n# Tweak spacing to prevent clipping of ylabel\nplt.subplots_adjust(left=0.15)\n\nfig_to_plotly(fig8, username, api_key, notebook= True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3190/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 27,
"text": "<IPython.core.display.HTML at 0x10f511390>"
}
],
"prompt_number": 27
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": "III. Stack Overflow Answers"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "We love Stack Overflow, so wanted to show answers to a few questions from there, in Plotly. If you want to plot data you already have as a [histogram](http://stackoverflow.com/questions/5328556/histogram-matplotlib) and make it interactive, try this one out."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig9 = plt.figure()\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nmu, sigma = 100, 15\nx = mu + sigma * np.random.randn(10000)\nhist, bins = np.histogram(x, bins=50)\nwidth = 0.7 * (bins[1] - bins[0])\ncenter = (bins[:-1] + bins[1:]) / 2\nplt.bar(center, hist, align='center', width=width)\n\nfig_to_plotly(fig9, username, api_key, notebook= True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3191/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 28,
"text": "<IPython.core.display.HTML at 0x10f5c83d0>"
}
],
"prompt_number": 28
},
{
"cell_type": "markdown",
"metadata": {},
"source": "Here is how to create a [density plot](http://stackoverflow.com/questions/4150171/how-to-create-a-density-plot-in-matplotlib/4152016#4152016) like you might in R, but in matplotlib."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig10 = plt.figure()\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom scipy.stats import gaussian_kde\ndata = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8\ndensity = gaussian_kde(data)\nxs = np.linspace(0,8,200)\ndensity.covariance_factor = lambda : .25\ndensity._compute_covariance()\nplt.plot(xs,density(xs))\n\nfig_to_plotly(fig10, username, api_key, notebook= True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3192/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 29,
"text": "<IPython.core.display.HTML at 0x10bbe5450>"
}
],
"prompt_number": 29
},
{
"cell_type": "markdown",
"metadata": {},
"source": "Drawing a simple example of [different lines for different plots](http://stackoverflow.com/questions/4805048/how-to-get-different-lines-for-different-plots-in-a-single-figure/4805456#4805456) looks like this..."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig11 = plt.figure()\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nx = np.arange(10)\n\nplt.plot(x, x)\nplt.plot(x, 2 * x)\nplt.plot(x, 3 * x)\nplt.plot(x, 4 * x)\n\nfig_to_plotly(fig11, username, api_key, notebook= True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3193/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 30,
"text": "<IPython.core.display.HTML at 0x10bddd4d0>"
}
],
"prompt_number": 30
},
{
"cell_type": "markdown",
"metadata": {},
"source": "...but can get more exciting like this."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig12 = plt.figure()\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nnum_plots = 20\n\n# Have a look at the colormaps here and decide which one you'd like:\n# http://matplotlib.org/1.2.1/examples/pylab_examples/show_colormaps.html\ncolormap = plt.cm.gist_ncar\nplt.gca().set_color_cycle([colormap(i) for i in np.linspace(0, 0.9, num_plots)])\n\n# Plot several different functions...\nx = np.arange(10)\nlabels = []\nfor i in range(1, num_plots + 1):\n plt.plot(x, i * x + 5 * i)\n labels.append(r'$y = %ix + %i$' % (i, 5*i))\n\nfig_to_plotly(fig12, username, api_key, notebook= True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3194/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 31,
"text": "<IPython.core.display.HTML at 0x10bddc190>"
}
],
"prompt_number": 31
},
{
"cell_type": "markdown",
"metadata": {},
"source": "Plotly also shows LaTeX if you want to draw [variables as subscripts in math mode](http://stackoverflow.com/questions/23276918/writing-variables-as-subscripts-in-math-mode)."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig13 = plt.figure()\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport matplotlib.mlab as mlab\n\nmean = [10,12,16,22,25]\nvariance = [3,6,8,10,12]\n\nx = np.linspace(0,40,1000)\n\nfor i in range(4):\n sigma = np.sqrt(variance[i])\n y = mlab.normpdf(x,mean[i],sigma)\n plt.plot(x,y, label=r'$v_{}$'.format(i+1))\n\nplt.xlabel(\"X\")\nplt.ylabel(\"P(X)\") \n\nplt.legend()\n\nfig_to_plotly(fig13, username, api_key, notebook= True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3195/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 32,
"text": "<IPython.core.display.HTML at 0x10bdf0b50>"
}
],
"prompt_number": 32
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": "IV. Prettyplotlib graphs in Plotly"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "The gallery of [examples](http://nbviewer.ipython.org/github/olgabot/prettyplotlib/blob/master/ipython_notebooks/Examples%20of%20everything%20pretty%20and%20plotted!.ipynb?create=1) we really like from [prettyplotlib](https://github.com/olgabot/prettyplotlib) can be a fun one to make interactive. Here's a scatter; let us know if you make others or have issues. "
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig14 = plt.figure()\n\nimport prettyplotlib as ppl\n\n# Set the random seed for consistency\nnp.random.seed(12)\n\n# Show the whole color range\nfor i in range(8):\n x = np.random.normal(loc=i, size=1000)\n y = np.random.normal(loc=i, size=1000)\n ax = ppl.scatter(x, y, label=str(i))\n \nppl.legend(ax)\nax.set_title('prettyplotlib `scatter`')\n\nfig_to_plotly(fig14, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3196/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 33,
"text": "<IPython.core.display.HTML at 0x10f5d1050>"
}
],
"prompt_number": 33
},
{
"cell_type": "markdown",
"metadata": {},
"source": "prettyplotlib again improves on matplotlib's defaults, adding an appealing set of defaults. "
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig15 = plt.figure()\n\nimport prettyplotlib as ppl\n\n# Set the random seed for consistency\nnp.random.seed(12)\n\n# Show the whole color range\nfor i in range(8):\n y = np.random.normal(size=1000).cumsum()\n x = np.arange(1000)\n\n # For now, you need to specify both x and y :(\n # Still figuring out how to specify just one\n ppl.plot(x, y, label=str(i), linewidth=0.75)\n \nppl.legend()\n\nfig_to_plotly(fig15, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3197/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 34,
"text": "<IPython.core.display.HTML at 0x10fd206d0>"
}
],
"prompt_number": 34
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": "V. Plotting with seaborn"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "Another library we really difg is [seaborn](http://stanford.edu/~mwaskom/software/seaborn/index.html), an awesome project by Michael Waskom. You may need to [import six](http://stackoverflow.com/questions/13967428/importerror-no-module-named-six), which you can do from pip. Let's try a few."
},
{
"cell_type": "code",
"collapsed": false,
"input": "import seaborn as sns\nfrom matplotlylib import fig_to_plotly",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 35
},
{
"cell_type": "code",
"collapsed": false,
"input": "def sinplot(flip=1):\n x = np.linspace(0, 14, 100)\n for i in range(1, 7):\n plt.plot(x, np.sin(x + i * .5) * (7 - i) * flip)",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 36
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig = plt.figure()\n\nsns.set_style(\"dark\")\nsinplot()\n\nfig_to_plotly(fig, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3198/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 37,
"text": "<IPython.core.display.HTML at 0x1115dd110>"
}
],
"prompt_number": 37
},
{
"cell_type": "markdown",
"metadata": {},
"source": "You can also run subplots like this."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig16 = plt.figure()\n\nwith sns.axes_style(\"darkgrid\"):\n plt.subplot(211)\n sinplot()\nplt.subplot(212)\nsinplot(-1)\n\nfig_to_plotly(fig16, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3199/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 38,
"text": "<IPython.core.display.HTML at 0x110155150>"
}
],
"prompt_number": 38
},
{
"cell_type": "markdown",
"metadata": {},
"source": "To plot data as point, rather than line, try [visualizing the data for each sampling unit](http://stanford.edu/~mwaskom/software/seaborn/tutorial/timeseries_plots.html#specifying-input-data-with-multidimensional-arrays)."
},
{
"cell_type": "code",
"collapsed": false,
"input": "import numpy as np\nnp.random.seed(9221999)\nimport pandas as pd\nfrom scipy import stats, optimize\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nsns.set(palette=\"Set2\")",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 39
},
{
"cell_type": "code",
"collapsed": false,
"input": "def sine_wave(n_x, obs_err_sd=1.5, tp_err_sd=.3):\n x = np.linspace(0, (n_x - 1) / 2, n_x)\n y = np.sin(x) + np.random.normal(0, obs_err_sd) + np.random.normal(0, tp_err_sd, n_x)\n return y",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 40
},
{
"cell_type": "code",
"collapsed": false,
"input": "sines = np.array([sine_wave(31) for _ in range(20)])",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 41
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig17 = plt.figure()\n\nsns.tsplot(sines, err_style=\"unit_points\", color=\"mediumpurple\");\n\nfig_to_plotly(fig17, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3200/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 42,
"text": "<IPython.core.display.HTML at 0x110175790>"
}
],
"prompt_number": 42
},
{
"cell_type": "markdown",
"metadata": {},
"source": "As you'll see, you can get part of the way [plotting regressions](http://stanford.edu/~mwaskom/software/seaborn/tutorial/quantitative_linear_models.html#plotting-simple-regression-with-regplot); it's a work in process still at Plotly. "
},
{
"cell_type": "code",
"collapsed": false,
"input": "import numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 43
},
{
"cell_type": "markdown",
"metadata": {},
"source": "Load some data."
},
{
"cell_type": "code",
"collapsed": false,
"input": "np.random.seed(sum(map(ord, \"linear_quantitative\")))",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 44
},
{
"cell_type": "code",
"collapsed": false,
"input": "tips = sns.load_dataset(\"tips\")",
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 45
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig18 = plt.figure()\n\nx, y = np.random.multivariate_normal([1, 5], [(2, -.8), (-.8, 2)], 80).T\nax = sns.regplot(x, y, color=\"seagreen\")\nax.set(xlabel=\"x variable\", ylabel=\"y variable\");\nplt.show()\n\nfig_to_plotly(fig18, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\nD1okb9U42GWSAAAAAElFTkSuQmCC\n",
"text": "<matplotlib.figure.Figure at 0x1102ea390>"
},
{
"output_type": "stream",
"stream": "stderr",
"text": "/Users/matthewsundquist/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/matplotlylib/renderer.py:448: UserWarning: Dang! That path collection is out of this world. I totally don't know what to do with it yet! Plotly can only import path collections linked to 'data' coordinates\n warnings.warn(\"Dang! That path collection is out of this \"\n"
},
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3201/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 46,
"text": "<IPython.core.display.HTML at 0x1102aa090>"
}
],
"prompt_number": 46
},
{
"cell_type": "markdown",
"metadata": {},
"source": "However, this one does work."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig19 = plt.figure()\n\nsns.residplot(x, y);\n\nfig_to_plotly(fig19, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stderr",
"text": "/Users/matthewsundquist/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/matplotlylib/renderer.py:363: UserWarning: Bummer! Plotly can currently only draw Line2D objects from matplotlib that are in 'data' coordinates!\n warnings.warn(\"Bummer! Plotly can currently only draw Line2D \"\n"
},
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3202/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 47,
"text": "<IPython.core.display.HTML at 0x11038af90>"
}
],
"prompt_number": 47
},
{
"cell_type": "markdown",
"metadata": {},
"source": "And a final example, [graphing residuals](http://stanford.edu/~mwaskom/software/seaborn/tutorial/quantitative_linear_models.html#plotting-simple-regression-with-regplot)."
},
{
"cell_type": "code",
"collapsed": false,
"input": "fig20 = plt.figure()\n\ny = x + 1.5 * x ** 2 + np.random.randn(len(x))\nsns.residplot(x, y, color=\"indianred\");\n\nfig_to_plotly(fig20, username, api_key, notebook = True)",
"language": "python",
"metadata": {},
"outputs": [
{
"html": "<iframe height=\"500\" id=\"igraph\" scrolling=\"no\" seamless=\"seamless\" src=\"https://plot.ly/~IPython.Demo/3203/600/450\" width=\"650\"></iframe>",
"metadata": {},
"output_type": "pyout",
"prompt_number": 48,
"text": "<IPython.core.display.HTML at 0x111f07050>"
}
],
"prompt_number": 48
}
],
"metadata": {}
}
]
}
@cqcn1991
Copy link

cqcn1991 commented Jun 6, 2016

What about adding a sidebar it? So it would be easier to navigate through the notebook.
Mine is like this:
https://nbviewer.jupyter.org/github/cqcn1991/Wind-Speed-Analysis/blob/master/GMM.ipynb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment