{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Rmagic Functions Extension" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "## Line magics" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "IPython has an `rmagic` extension that contains a some magic functions for working with R via rpy2. This extension can be loaded using the `%load_ext` magic as follows:" ] }, { "cell_type": "code", "execution_count": 85, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The rpy2.ipython extension is already loaded. To reload it, use:\n", " %reload_ext rpy2.ipython\n" ] }, { "data": { "text/plain": [ "'%.3f'" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%load_ext rpy2.ipython\n", "% precision 3" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## A simple example: scatter-plot\n", "A typical use case one imagines is having some numpy arrays, wanting to compute some statistics of interest on these\n", " arrays and return the result back to python. Let's suppose we just want to fit a simple linear model to a scatterplot." ] }, { "cell_type": "code", "execution_count": 86, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# First we generate and plot the data in Python\n", "\n", "import numpy as np\n", "import pylab\n", "X = np.array([0,1,2,3,4])\n", "Y = np.array([3,5,4,6,7])\n", "pylab.scatter(X, Y)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Pushing Python variables into R, and executing R-commands in IPython\n", "\n", "We can accomplish this by first pushing variables to R, fitting a model and returning the results. The line magic %Rpush copies its arguments to variables of the same name in rpy2. The %R line magic evaluates the string in rpy2 and returns the results. In this case, the coefficients of a linear model." ] }, { "cell_type": "code", "execution_count": 87, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array([ 3.2, 0.9])" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%Rpush X Y\n", "%R lm(Y~X)$coef" ] }, { "cell_type": "code", "execution_count": 88, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array([ 9.5])" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Note: %Rpush is equivalent to calling %R with just -i and no trailing code.\n", "A = np.arange(20)\n", "%R -i A\n", "%R mean(A)" ] }, { "cell_type": "code", "execution_count": 89, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "(3.200, 0.900)" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# We can check that the computation in R is correct fairly easily:\n", "\n", "Xr = X - X.mean()\n", "Yr = Y - Y.mean()\n", "slope = (Xr*Yr).sum() / (Xr**2).sum()\n", "intercept = Y.mean() - X.mean() * slope\n", "(intercept, slope)" ] }, { "cell_type": "code", "execution_count": 90, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "array([-2.5, 0.9])" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# It is also possible to return more than one value with %R.\n", "%R resid(lm(Y~X)); coef(lm(X~Y))\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Capturing literal output from R into IPython" ] }, { "cell_type": "code", "execution_count": 91, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "R object with classes: ('summary.lm',) mapped to:\n", "\n", "[Vector, Formula, Array, ..., Float..., Float..., Matrix]\n", " call: \n", " R object with classes: ('lm',) mapped to:\n", "\n", "[RNULLType, Vector]\n", " terms: \n", " R object with classes: ('terms', 'formula') mapped to:\n", "\n", " residuals: \n", " R object with classes: ('array',) mapped to:\n", "\n", "[-0.200000, 0.900000, -1.000000, 0.100000, 0.200000]\n", " ...\n", " call: \n", " R object with classes: ('numeric',) mapped to:\n", "\n", "[0.746667]\n", " terms: \n", " R object with classes: ('numeric',) mapped to:\n", "\n", "[12.789474, 1.000000, 3.000000]\n", " residuals: \n", " R object with classes: ('matrix',) mapped to:\n", "\n", "[0.600000, -0.200000, -0.200000, 0.100000]" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Unfortunately, the literal output from R does not work directly (yet):\n", "%R summary(lm(Y~X))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Therefore we have to use a trick:\n", "* We first \"capture\" the output of the R-command\n", "* And then we display it, line-by-line\n", "\n", "Note: \"%%R\" executes multiple R-commandlines " ] }, { "cell_type": "code", "execution_count": 92, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "%%R\n", "X = c(1,2,3,4,5)\n", "Y = c(1,2,3,6,5)\n", "s = capture.output(summary(lm(Y~X)))\n" ] }, { "cell_type": "code", "execution_count": 93, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "lm(formula = Y ~ X)\n", "\n", "Residuals:\n", " 1 2 3 4 5 \n", "-2.22e-16 -2.00e-01 -4.00e-01 1.40e+00 -8.00e-01 \n", "\n", "Coefficients:\n", " Estimate Std. Error t value Pr(>|t|) \n", "(Intercept) -0.2000 1.0132 -0.197 0.8561 \n", "X 1.2000 0.3055 3.928 0.0294 *\n", "---\n", "Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n", "\n", "Residual standard error: 0.9661 on 3 degrees of freedom\n", "Multiple R-squared: 0.8372,\tAdjusted R-squared: 0.7829 \n", "F-statistic: 15.43 on 1 and 3 DF, p-value: 0.02937\n" ] } ], "source": [ "# and here we pass the string into Python, and print it line-by-line\n", "a =%R s\n", "for line in a[2:-1]:\n", " print(line)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Getting R-variables back into IPython\n", "\n", "There are two line magics, %Rpull and %Rget. Both are useful after some R code has been executed and there are variables\n", "in the rpy2 namespace that one would like to retrieve. The main difference is that one returns the value (%Rget), while the other pulls it to self.shell.user_ns (%Rpull).\n", "\n", "Imagine we've stored the results of some calculation in the variable \"a\" in rpy2's namespace. By using the %R magic, we can obtain these results and store them in b. We can also pull them directly to user_ns with %Rpull. They are both views on the same data." ] }, { "cell_type": "code", "execution_count": 94, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ -2.220e-16 -2.000e-01 -4.000e-01 1.400e+00 -8.000e-01]\n" ] } ], "source": [ "b = %R a=resid(lm(Y~X))\n", "%Rpull a\n", "print(a)\n", "assert id(b.data) == id(a.data)\n", "%R -o a" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "%Rpull is equivalent to calling %R with just -o\n" ] }, { "cell_type": "code", "execution_count": 95, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ -2.220e-16 -2.000e-01 -4.000e-01 1.400e+00 -8.000e-01]\n", "[-0.2 1.2]\n" ] } ], "source": [ "%R d=resid(lm(Y~X)); e=coef(lm(Y~X))\n", "%R -o d -o e\n", "%Rpull e\n", "print(d)\n", "print(e)\n", "import numpy as np\n", "np.testing.assert_almost_equal(d, a)" ] }, { "cell_type": "code", "execution_count": 96, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n", " 17, 18, 19], dtype=int32)" ] }, "execution_count": 96, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The magic %Rget retrieves one variable from R.\n", "%Rget A" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Plotting and capturing output\n", "\n", "R's console (i.e. its stdout() connection) is captured by ipython, as are any plots which are published as PNG files like the notebook with arguments --pylab inline. As a call to %R may produce a return value (see above) we must ask what happens to a magic like the one below. The R code specifies that something is published to the notebook. If anything is published to the notebook, that call to %R returns None." ] }, { "cell_type": "code", "execution_count": 97, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeAAAAHgCAMAAABKCk6nAAABwlBMVEUAAAAFBQUGBgYHBwcICAgJ\nCQkKCgoPDw8eHh4fHx8kJCQlJSUtLS0xMTEzMzM0NDQ1NTU2NjY3Nzc5OTk6Ojo7Ozs9PT0/Pz9A\nQEBCQkJDQ0NERERFRUVGRkZHR0dISEhLS0tMTExNTU1OTk5PT09RUVFSUlJUVFRVVVVWVlZXV1dY\nWFhaWlpbW1tdXV1fX19gYGBhYWFiYmJjY2NlZWVmZmZoaGhpaWlqampra2tvb29wcHB2dnZ3d3d4\neHh5eXl6enp7e3t8fHx/f3+Dg4OHh4eIiIiKioqLi4uMjIyOjo6QkJCUlJSVlZWXl5eYmJiZmZma\nmpqbm5ucnJydnZ2enp6fn5+goKCjo6OkpKSmpqaoqKipqamqqqqurq6wsLCxsbGysrKzs7O0tLS1\ntbW2tra4uLi7u7u9vb2/v7/AwMDBwcHCwsLFxcXGxsbHx8fIyMjJycnLy8vMzMzNzc3Q0NDS0tLV\n1dXW1tbb29vc3Nzd3d3f39/g4ODi4uLj4+Pk5OTl5eXn5+fp6enq6urr6+vs7Ozu7u7w8PDx8fHy\n8vLz8/P19fX29vb39/f4+Pj6+vr7+/v8/Pz9/f3+/v7///9IMF4kAAAI/UlEQVR4nO3d+58VZQGA\n8TErNVJDxq3EBU0wVFLLpgQz81JeDpqWlzJRoiYstSgRHbW4Jaglwi7z/3rmoOxZ9iyeubwzZ57z\nfH+Yz4dheOfdfXYu8DnDRLnQoq4noLAMDGdgOAPDGRjOwHAGhjMwnIHhDAxnYDgDwxkYzsBwBoYz\nMJyB4QwMZ2A4A8MZGM7AcAaGMzCcgeEMDGdgOAPDGRjOwHAGhjMwnIHhDAxnYDgDwxkYzsBwBoYz\nMJyB4QwMZ2A4A8MZGM7AcAaGMzCcgeEMDGdgOAPDGRjOwHAGhjMwnIHhagQ++czT6t5zS6ECv7Sz\n669NQ9e/Gyzwk9X/rBpzj4HZDAxnYDgDwxkYzsBwBoYzcDeOftzSjmoHzqI0j6MoXvMbBl7foevu\nWNzxv1Z2VTtwnOZJOuy8prCB17X0rSN5/uLuVvZVO/BwizhbteU/fzWy7d66c8N6JymWC63sq3bg\n4eGbDvI8TS6sOXJg5NbtdeeG9f6dw8Xyt1vZV/2brCQqJGvW33d7xSnxnbvh7/nyw4+1sq9wd9EG\n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\nDAxnYLjPALb3wPFaPXcPAAAAAElFTkSuQmCC\n" }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "v1 is: [ 10.2]\n", "v2 is: [ 10.2]\n" ] } ], "source": [ "v1 = %R plot(X,Y); print(summary(lm(Y~X))); vv=mean(X)*mean(Y)\n", "print('v1 is:', v1)\n", "v2 = %R mean(X)*mean(Y)\n", "print('v2 is:', v2)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## What value is returned from %R?\n", "\n", "Some calls have no particularly interesting return value, the magic %R will not return anything in this case. The return value in rpy2 is actually NULL so %R returns None." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Also, if the return value of a call to %R (in line mode) has just been printed to the console, then its value is also not returned." ] }, { "cell_type": "code", "execution_count": 98, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeAAAAHgCAMAAABKCk6nAAABvFBMVEUAAAAFBQUGBgYHBwcICAgJ\nCQkKCgoPDw8fHx8kJCQlJSUtLS0zMzM0NDQ2NjY3Nzc5OTk6Ojo7Ozs8PDw9PT0+Pj4/Pz9AQEBD\nQ0NERERFRUVGRkZHR0dISEhJSUlKSkpLS0tMTExPT09RUVFSUlJUVFRVVVVWVlZXV1dYWFhaWlpc\nXFxgYGBhYWFjY2NkZGRlZWVmZmZoaGhpaWlqampsbGxvb29wcHBxcXFzc3N0dHR2dnZ3d3d4eHh6\nenp7e3t8fHx9fX2Dg4OEhISGhoaHh4eIiIiKioqPj4+QkJCRkZGUlJSVlZWXl5eYmJiZmZmampqb\nm5ucnJyenp6goKCioqKjo6OlpaWoqKipqamqqqqurq6vr6+xsbG0tLS2tra4uLi6urq7u7u9vb2/\nv7/AwMDCwsLDw8PFxcXGxsbHx8fJycnKysrLy8vMzMzNzc3Q0NDR0dHS0tLT09PV1dXY2NjZ2dna\n2trb29vc3Nzd3d3f39/g4ODh4eHj4+Pn5+fo6Ojp6enq6urs7Ozt7e3u7u7w8PDx8fHy8vLz8/P0\n9PT29vb39/f4+Pj5+fn6+vr8/Pz9/f3+/v7////DiJ8HAAAI9UlEQVR4nO3di5fcVAGA8YuCD6jQ\ntBWpFgqUigJFIgqoiPISAgVRVB4CAamiooKiGB5Wy/Iu0Ef+YZJs6c7uztbJJDfZ+eb7nUMOmw3J\nnfnmJilnAqEUWhh7AIrLwHAGhjMwnIHhDAxnYDgDwxkYzsBwBoYzMJyB4QwMZ2A4A8MZGM7AcAaG\nMzCcgeEMDGdgOAPDGRjOwHAGhjMwnIHhDAxnYDgDwxkYzsBwBoYzMJyB4QwMZ2A4A8MZGM7AcAaG\nMzCcgeEMDGdgOAPDGRjOwHAGhjMwnIHhDAxnYDgDwxkYrkPglUd+rvE9ejJW4CeuG/u1qbLrtWiB\nD8//z6o3NxqYzcBwBoYzMJyB4QwMZ2A4A9Mcf3Pdj50D11uEEJJNvzDwGE5+d8/1O56bWNFH4Hqj\nIt34CwOP4f57y/LdS95eW9FD4CJZv+WLP2tc/b05x6gO9r9fLe7J11Z0DxyawMXaOfro7xrXHJhz\njOrgmreqxZ1H1lb0cJOVhLTMN29467faDU19ePI7n5T/2nl8bUW8u2gDj+IXO/ZcVUz8bGA4A8MZ\n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\nXwAAAABJRU5ErkJggg==\n" }, "metadata": {}, "output_type": "display_data" } ], "source": [ "v = %R plot(X)\n", "assert (v is None)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "But, if the last value did not print anything to console, the value is returned:\n" ] }, { "cell_type": "code", "execution_count": 99, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "v: [ 1. 2. 3. 4. 5.]\n" ] } ], "source": [ "v = %R print(summary(X)); X\n", "print('v:', v)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "The return value can be suppressed by a trailing ';' or an -n argument.\n" ] }, { "cell_type": "code", "execution_count": 100, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "%R -n X" ] }, { "cell_type": "code", "execution_count": 101, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "%R X; " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Cell level magic\n", "\n", "Often, we will want to do more than a simple linear regression model. There may be several lines of R code that we want to \n", "use before returning to python. This is the cell-level magic.\n", "\n", "\n", "For the cell level magic, inputs can be passed via the -i or --inputs argument in the line. These variables are copied \n", "from the shell namespace to R's namespace using rpy2.robjects.r.assign. It would be nice not to have to copy these into R: rnumpy ( http://bitbucket.org/njs/rnumpy/wiki/API ) has done some work to limit or at least make transparent the number of copies of an array. This seems like a natural thing to try to build on. Arrays can be output from R via the -o or --outputs argument in the line. All other arguments are sent to R's png function, which is the graphics device used to create the plots.\n", "\n", "We can redo the above calculations in one ipython cell. We might also want to add some output such as a summary\n", " from R or perhaps the standard plotting diagnostics of the lm." ] }, { "cell_type": "code", "execution_count": 102, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "image/png": "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\n" }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%R -i X,Y -o XYcoef\n", "XYlm = lm(Y~X)\n", "XYcoef = coef(XYlm)\n", "print(summary(XYlm))\n", "par(mfrow=c(2,2))\n", "plot(XYlm)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Passing data back and forth\n", "\n", "Currently, data is passed through RMagics.pyconverter when going from python to R and RMagics.Rconverter when \n", "going from R to python. These currently default to numpy.ndarray. Future work will involve writing better converters, most likely involving integration with http://pandas.sourceforge.net.\n", "\n", "Passing ndarrays into R seems to require a copy, though once an object is returned to python, this object is NOT copied, and it is possible to change its values.\n" ] }, { "cell_type": "code", "execution_count": 103, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "seq1 = np.arange(10)" ] }, { "cell_type": "code", "execution_count": 104, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "%%R -i seq1 -o seq2\n", "seq2 = rep(seq1, 2)\n", "print(seq2)" ] }, { "cell_type": "code", "execution_count": 105, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 0, 3, 0, 5, 0, 7, 0, 9, 0, 1, 0, 3, 0, 5, 0, 7, 0, 9], dtype=int32)" ] }, "execution_count": 105, "metadata": {}, "output_type": "execute_result" } ], "source": [ "seq2[::2] = 0\n", "seq2" ] }, { "cell_type": "code", "execution_count": 106, "metadata": { "collapsed": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%%R\n", "print(seq2)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Once the array data has been passed to R, modifring its contents does not modify R's copy of the data." ] }, { "cell_type": "code", "execution_count": 107, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)" ] }, "execution_count": 107, "metadata": {}, "output_type": "execute_result" } ], "source": [ "seq1[0] = 200\n", "%R print(seq1)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "But, if we pass data as both input and output, then the value of \"data\" in user_ns will be overwritten and the\n", "new array will be a view of the data in R's copy." ] }, { "cell_type": "code", "execution_count": 108, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[200 1 2 3 4 5 6 7 8 9]\n", "[200 1 2 3 4 5 6 7 8 9]\n" ] } ], "source": [ "print(seq1)\n", "%R -i seq1 -o seq1\n", "print(seq1)\n", "seq1[0] = 200\n", "%R print(seq1)\n", "seq1_view = %R seq1\n", "assert(id(seq1_view.data) == id(seq1.data))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exception handling\n", "\n", "Exceptions are handled by passing back rpy2's exception and the line that triggered it." ] }, { "cell_type": "code", "execution_count": 109, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Error in withVisible({ : object 'nosuchvar' not found\n" ] } ], "source": [ "try:\n", " %R -n nosuchvar\n", "except Exception as e:\n", " print(e.message)\n", " pass" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "slideshow": { "slide_type": "slide" } }, "source": [ "## R Graphics" ] }, { "cell_type": "code", "execution_count": 110, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeAAAAHgCAMAAABKCk6nAAABtlBMVEUAAAAFBQUGBgYHBwcICAgJ\nCQkKCgoPDw8fHx8kJCQlJSUtLS0zMzM2NjY3Nzc4ODg5OTk6Ojo7Ozs8PDw9PT0+Pj5AQEBDQ0NE\nRERFRUVGRkZHR0dISEhJSUlKSkpMTExPT09RUVFSUlJUVFRVVVVWVlZXV1dYWFhaWlpcXFxfX19g\nYGBhYWFjY2NkZGRlZWVmZmZoaGhpaWlqampsbGxubm5vb29wcHB0dHR3d3d4eHh6enp7e3t8fHx9\nfX2AgICBgYGDg4OGhoaHh4eIiIiKioqPj4+QkJCRkZGUlJSVlZWXl5eYmJiZmZmampqbm5ucnJye\nnp6goKCioqKjo6OlpaWoqKipqamqqqqurq6vr6+xsbG0tLS2tra4uLi6urq7u7u8vLy9vb2/v7/A\nwMDCwsLExMTFxcXGxsbHx8fJycnLy8vMzMzNzc3Pz8/Q0NDS0tLT09PU1NTV1dXW1tbY2Njb29vc\n3Nzd3d3e3t7f39/g4ODi4uLj4+Pl5eXn5+fp6enq6urs7Ozt7e3u7u7w8PDx8fHy8vLz8/P29vb3\n9/f4+Pj5+fn6+vr8/Pz9/f3+/v7///8d+EfPAAAInklEQVR4nO3d53fbVABA8cdeLVRQ9qaUWUDs\nPQoUU/YuS6yyyx5iFkqZLSVU/zGSORA7TlLb0pPi6/v7oNPYr0+vvtHIOXYTCqGFrheguAwMZ2A4\nA8MZGM7AcAaGMzCcgeEMDGdgOAPDGRjOwHAGhjMwnIHhDAxnYDgDwxkYzsBwBoYzMJyB4QwMZ2A4\nA8MZGM7AcAaGMzCcgeEMDGdgOAPDGRjOwHAGhjMwnIHhDAxnYDgDwxkYzsBwBoYzMJyB4QwMZ2A4\nA8MZGM7AcAaGMzCcgeFqBN772KPq3pMLsQLvuKzrf5tKJ38VLfBD0/9dNeYqA7MZGM7AcAaGMzCc\ngeEMDGdgmn3fDX1ZO3DorfCEgbuwcO3Gy9e9OvBAA4FDtuwTBu7CA/cVxa8n/rz4QP3ARZGGoWHv\n3993wfXTLVF1nPd7ubl34JBrInC1HWi8+7W+iy6caoWq5aKfys1dOxcfaCjwMm6+ZOxVqTHPX32g\n+HLDvsUH4t1FG7gTj6/beH4+8LWB4QwMZ2A4A8MZGM7AcAaGMzCcgeEMDGdgOAPDGRjOwHAGhjMw\n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\n" }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%R plot(X,Y)" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 3", "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.6.0" } }, "nbformat": 4, "nbformat_minor": 0 }