{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "**NOTE**: This is a Julia demo for Binder, it's been adapted from the Julia demo on the nbconvert website.\n", "\n", "Binder is an open-source project and Julia support is early in development. If you'd like to improve Julia support in Binder, see our issue on adding Julia support here: https://github.com/jupyter/repo2docker/issues/23. We'd love to hear from you!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# An IJulia Demo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook uses **IJulia**: a [Julia-language](http://julialang.org/) backend combined with the [IPython](http://ipython.org/) interactive environment. This combination allows you to interact with the Julia language using IPython's powerful [graphical notebook](http://ipython.org/notebook.html), which combines code, formatted text, math, and multimedia in a single document." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic Julia interaction" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Basic mathematical expressions work like you expect:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "1 + sin(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can define variables, write loops, and execute arbitrary multiline code blocks. Here is an example of an alternating harmonic series $\\sum_{n=1}^\\infty \\frac{(-1)^n}{n}$ from a [Julia tutorial by Homer Reid](http://homerreid.ath.cx/teaching/18.330/JuliaProgramming.shtml#SimplePrograms):" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s = 0.0\n", "for n = 1:2:10000\n", " s += 1/n - 1/(n+1)\n", "end\n", "s # an expression on the last line (if it doesn't end with \";\") is printed as \"Out\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Previous outputs can be referred to via `Out[`*n*`]`, following the IPython, for example `Out[2]` for the result above. You can also use the shorthand `_2`, or `_` for the previous result, as in IPython. Like in Matlab, `ans` can also be used to refer to the previous result, *even if it was not printed* (when the command ended with `;`).\n", "\n", "For example, the harmonic series above should be converging (slowly) to $\\ln 2$, and we can check this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "Out[2] - log(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like Matlab or Scipy + Numpy, Julia has lots of mathematical functions and linear algebra built in. For example, we can define a $500\\times500$ random matrix $R$ and form the positive-definite matrix $R^* R$:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "R = rand(500,500)\n", "R' * R" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(Notice that, by default, only a portion of a large matrix is shown. You didn't really want to read $500^2 = 250,000$ numbers, did you?)\n", "\n", "Standard output from Julia is also captured and sent to the IJulia notebook as you'd expect:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "println(\"Hello world!\\n\")\n", "println(stderr, \"Börk börk börk, some unicode output on stderr...\\n\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "IJulia even captures output from external C libraries (and notice how easy it is using Julia's `ccall` intrinsic):" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ccall(:printf, Cint, (Ptr{UInt8},), \"Hello from C!!\\n\");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can define functions, of course, and use them in later input cells:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "f(x) = x .+ 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "println(f(3))\n", "f([1,1,2,3,5,8])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that the input above both printed an scalar to `STDOUT` and also returned a vector, the latter using Julia's ability to write polymorphic functions and built-in array operations.\n", "\n", "On the other hand adding a string to a number is not defined (there is no `+` method defined for those types, although we could easily add one), and attempting to do so will throw an exception:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "f(\"Hello?\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Interactive Plotting in IJulia\n", "\n", "Below we'll show off some plotting using the excellent Gadfly package. The plots are heavily inspired by [this blog post](http://int8.io/basic-visualization-in-julia-gadfly/)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "using RDatasets\n", "sleep = dataset(\"lme4\",\"sleepstudy\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "using Gadfly\n", "plot(sleep, x = \"Days\", y = \"Reaction\", Geom.point)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "plot(sleep, x = \"Reaction\", Geom.density, color = \"Subject\", Scale.x_continuous(minvalue= 0, maxvalue= 500))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "plot(x = sleep[!, :Reaction], Geom.histogram(bincount = 30), Scale.x_continuous(minvalue = 200), color = sleep[!, :Days])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Multimedia display in IJulia" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like most programming languages, Julia has a built-in `print(x)` function for outputting an object `x` as text, and you can override the resulting text representation of a user-defined type by overloading Julia's `show` function. The next version of Julia, however, will extend this to a more general mechanism to display **arbitrary multimedia representations** of objects, as defined by standard [MIME types](https://en.wikipedia.org/wiki/Internet_media_type). More specifically, the Julia [multimedia I/O API](http://docs.julialang.org/en/latest/stdlib/base/#multimedia-i-o) provides:\n", "\n", "* A `display(x)` function requests the richest available multimedia display of a Julia object x (with a `text/plain` fallback).\n", "* Overloading `writemime` allows one to indicate arbitrary multimedia representations (keyed by standard MIME types) of user-defined types.\n", "* Multimedia-capable display backends may be registered by subclassing a generic `Display` type. IJulia provides one such backend which, thanks to the IPython notebook, is capable of displaying HTML, LaTeX, SVG, PNG, and JPEG media formats.\n", "\n", "The last two points are critical, because they separate **multimedia export** (which is defined by functions associated with the originating Julia data) from **multimedia display** (defined by backends which know nothing about the source of the data).\n", "\n", "Precisely these mechanism were used to create the inline PyPlot plots above. To start with, the simplest thing is to provide the MIME type of the data when you call `display`, which allows you to pass \"raw\" data in the corresponding format:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "display(\"text/html\", \"\"\"Hello world in HTML!\"\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However, it will be more common to attach this information to types, so that they display correctly automatically. For example, let's define a simple `HTML` type in Julia that contains a string and automatically displays as HTML (given an HTML-capable backend such as IJulia):" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "mutable struct HTML\n", " s::String\n", "end\n", "\n", "Base.show(io::IO, ::MIME\"text/html\", x::HTML) = print(io, x.s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, `Base.show` is just a function that writes `x` in the corresponding format (`text/html`) to the I/O stream `io`.\n", "\n", "This `show` definition is all that we need to make any object of type `HTML` display automatically as HTML text in IJulia:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = HTML(\"\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "display(x)\n", "println(x)" ] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.1.0", "language": "julia", "name": "julia-1.1" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.1.0" } }, "nbformat": 4, "nbformat_minor": 2 }