{ "cells": [ { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "# PyPlot Examples\n", "by [Gizmaa](https://github.com/gizmaa/Julia_Examples)
\n", "Last Edited: May 13, 2019
\n", "Latest [PyPlot_Examples.zip](https://github.com/gizmaa/Julia_Examples/blob/master/PyPlot_Examples.zip)\n", "\n", "##### Contents\n", "\n", "\n", "\n", "### PyPlot\n", "#### Translating\n", " \n", "Translating PyPlot code from Python to Julia can be difficult so here are a few examples comparing Python code with its Julia equivalent." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Python\n", "ax.set_ylim([-30, 10])\n", "ax.spines['right'].set_color('none')\n", "ax.spines['top'].set_color('none')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Source: [Axis Boundary Color](http://matplotlib.org/examples/showcase/xkcd.html)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Julia\n", "ax.set_ylim([-30,10])\n", "ax.spines[\"top\"].set_color(\"none\") # Remove the top axis boundary\n", "ax.spines[\"right\"].set_color(\"none\") # Remove the right axis boundary" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above example looked at settings of plot components. The next example will call matplotlib itself." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Python\n", "from matplotlib.dates import MonthLocator, WeekdayLocator, DateFormatter\n", "majorformatter = DateFormatter(\"%d.%m.%Y\")\n", "minorformatter = DateFormatter(\"%H:%M\")\n", "majorlocator = DayLocator(interval=1)\n", "minorlocator = HourLocator(byhour=(8,16)) # Not sure about this one" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Source: Modified from [this forum post by Nat Wilson](https://groups.google.com/d/msg/julia-users/jIyyRJc6Hho/mSwSCItH3PoJ) and [this matplotlib example](http://matplotlib.org/examples/pylab_examples/date_demo2.html)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Julia\n", "majorformatter = matplotlib.dates.DateFormatter(\"%d.%m.%Y\")\n", "minorformatter = matplotlib.dates.DateFormatter(\"%H:%M\")\n", "majorlocator = matplotlib.dates.DayLocator(interval=1)\n", "minorlocator = matplotlib.dates.HourLocator(byhour=(8, 16))\n", "\n", "# After an axis exists\n", "ax1.xaxis.set_major_formatter(majorformatter)\n", "ax1.xaxis.set_minor_formatter(minorformatter)\n", "ax1.xaxis.set_major_locator(majorlocator)\n", "ax1.xaxis.set_minor_locator(minorlocator)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "#### Important Note\n", "The easiest way of doing a quick plot is to simply type it into the REPL (command line) but by default interactive mode might be \"off\". This means that when you create a figure, `figure()`, nothing will appear except for the object type in the REPL, `PyPlot.Figure(PyObject ....` The command `plt[:show]()` will make the figure visible but also make the REPL temporarily unusable until all figures are closed.\n", "\n", "Changing interactive mode to \"on\" is as simple as running `ion()`. Plots will be visible and the REPL will still be usable. It will only last for the current session though. Add it to the .juliarc.jl file to make it \"on\" by default. It can also be turned \"off\" by running `ioff()`. If IJulia fails to plot inline try adding `gcf()` after the plot.\n", "\n", "Depending on the editor you are using this may be undesirable. In one mode IJulia may plot inline whereas the other may plot to a window.\n", "\n", "
\n", "\n", "#### Basic Plot\n", "Most of the basic commands in PyPlot are very similar to Matlab. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "image/png": "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h/DWW29h0qRJoqO5herqapw6darp++LiYhQUFCAwMBBRUVHIyMjA3Llz0alTJxiNRsyePRvh4eFNVxi5lEStDoBmv1avXi06Gt0wYMAAKT09XXQMt/bZZ59JPXr0kHQ6ndSlSxdpxYoVoiO5LYvFIqWnp0tRUVGSl5eX1L59e2nWrFlSXV2d6GhuYdeuXc3+nzFhwgRJkiTJ4XBIs2fPlkJCQiSdTielpKRIx48fF5KV67QQERGRInBOCxERESkCSwsREREpAksLERERKQJLCxERESkCSwsREREpAksLERERKQJLCxERESkCSwsREREpAksLEcmG3W5H37598fjjj990u9lsRmRkJGbNmiUoGRHJAVfEJSJZOXHiBHr27ImVK1ciNTUVADB+/HgUFhbCZDLB09NTcEIiEoWlhYhkZ8mSJcjMzMSRI0dw4MABjBkzBiaTCXFxcaKjEZFALC1EJDuSJGHw4MHQaDQoKirCtGnT8Nprr4mORUSCsbQQkSx9//336Nq1K2JiYnDw4EF4eHiIjkREgnEiLhHJ0vvvvw8fHx8UFxfj3LlzouMQkQzwSAsRyc53332HAQMG4Msvv8TcuXMBAF999RVUKpXgZEQkEo+0EJGs1NTUYOLEiZgyZQoGDRqErKwsHDhwAMuWLRMdjYgE45EWIpKV9PR0fP755ygsLISPjw8AYPny5ZgxYwaKiooQHR0tNiARCcPSQkSykZubi5SUFOTk5OChhx666b5hw4ahoaGBp4mI3BhLCxERESkC57QQERGRIrC0EBERkSKwtBAREZEisLQQERGRIrC0EBERkSKwtBAREZEisLQQERGRIrC0EBERkSKwtBAREZEisLQQERGRIrC0EBERkSKwtBAREZEi/D86Ru4kLN0e6QAAAABJRU5ErkJggg==", "text/plain": [ "Figure(PyObject )" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using PyPlot\n", "ioff() # Interactive plotting OFF, necessary for inline plotting in IJulia\n", "x = collect(1:10)\n", "y = 10rand(10,1)\n", "\n", "p = plot(x,y)\n", "xlabel(\"X\")\n", "ylabel(\"Y\")\n", "PyPlot.title(\"Your Title Goes Here\")\n", "grid(\"on\")\n", "gcf() # Needed by IJulia to display plot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first noticable change is in the plotting command when non-default values are used. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "p = plot_date(x,y,linestyle=\"-\",marker=\"None\",label=\"Base Plot\") # Basic line plot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Instead of `\"linestyle\",\"-\"` it uses `linestyle=\"-\"` for parameters. \n", "\n", "
\n", "\n", "## Plot Annotation\n", "([IJulia](pyplot_annotation.ipynb), [Code](pyplot_annotation.jl))\n", "\n", "![Annotation Examples](pyplot_annotation.png)\n", "\n", "The following command will point an arrow at a point and label the arrow." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "annotate(\"Look, data!\",\n", " xy=[x;y,# Arrow tip\n", " xytext=[x+dx;y+dy], # Text offset from tip\n", " xycoords=\"data\", # Coordinates in in \"data\" units\n", " arrowprops=[\"facecolor\"=>\"black\"]) # Julia dictionary objects are automatically converted to Python object when they pass into a PyPlot function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's important to note that in Python the arrowprops would look like this: `arrowprops=dict(arrowstyle=\"->\")`. Dictionary definitions look like `arrowprops=[\"facecolor\"=>\"black\"]` in Julia.\n", "\n", "LaTeX can be used by putting an L in front of LaTeX code, `L\"$\\int x = \\frac{x^2}{2} + C$\"`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "annotate(L\"$\\int x = \\frac{x^2}{2} + C$\",\n", " xy=[1;0],\n", " xycoords=\"axes fraction\",\n", " xytext=[-10,10],\n", " textcoords=\"offset points\",\n", " fontsize=30.0,\n", " ha=\"right\",\n", " va=\"bottom\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "## Time Customization\n", "([IJulia](pyplot_customtime.ipynb),[Code](pyplot_customtime.jl))\n", "\n", "The formatting preparation is accomplished by calling the formatters within Matplotlib." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "majorformatter = matplotlib.dates.DateFormatter(\"%d.%m.%Y\")\n", "minorformatter = matplotlib.dates.DateFormatter(\"%H:%M\")\n", "majorlocator = matplotlib.dates.DayLocator(interval=1)\n", "minorlocator = matplotlib.dates.HourLocator(byhour=(8, 16))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "They are then applied to the specific axis, the handle of which is called ax1 in this case." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ax1.xaxis.set_major_formatter(majorformatter)\n", "ax1.xaxis.set_minor_formatter(minorformatter)\n", "ax1.xaxis.set_major_locator(majorlocator)\n", "ax1.xaxis.set_minor_locator(minorlocator)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Custom Time](pyplot_customtime.png)\n", "\n", "
\n", "\n", "## Subplots\n", "([IJulia](pyplot_subplot.ipynb), [Code](pyplot_subplot.jl))\n", "\n", "`subplot(YXN)`, Y = number of columns, X = number of rows, N = number of axis being created\n", "\n", "The number, N, of a grid of axes starts in the upper left (1), and goes right then down. The second axis of a 2x2 grid is the upper right axis." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "subplot(313) # Create the third plot of a 3x1 group of subplots\n", "\n", "suptitle(\"3x1 Subplot\") # Supe title, title for all subplots combined" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![2x2 Subplot](pyplot_subplot_mixed.png)\n", "\n", "![3x1 Subplot](pyplot_subplot_column.png)\n", "\n", "![3x1 Touching Subplots](pyplot_subplot_touching.png)\n", "\n", "
\n", "\n", "## Polar and Windrose Plot\n", "([IJulia](pyplot_windrose.ipynb), [Code](pyplot_windrose.jl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ax = axes(polar=\"true\") # Create a polar axis\n", "# Do your plotting\n", "\n", "# Optional changes\n", "ax.set_thetagrids(collect(0:dtheta:360-dtheta)) # Show grid lines from 0 to 360 in increments of dtheta\n", "ax.set_theta_zero_location(\"N\") # Set 0 degrees to the top of the plot\n", "ax.set_theta_direction(-1) # Switch to clockwise\n", "fig.canvas.draw() # Update the figure, required when doing additional modifications" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Wind Rose](pyplot_windrose_barplot.png)\n", "\n", "![Wind Rose - Line](pyplot_windrose_lineplot.png)\n", "\n", "
\n", "\n", "## Histogram\n", "([IJulia](pyplot_histogram.ipynb), [Code](pyplot_histogram.jl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "h = plt.hist(x,nbins) # Histogram, PyPlot.plt required to differentiate with conflicting hist command" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The PyPlot.plt prefix is required to disambiguate it from the hist command.\n", "\n", "![Histogram](pyplot_histogram.png)\n", "\n", "
\n", "\n", "## Bar Plot\n", "([IJulia](pyplot_barplot.ipynb), [Code](pyplot_barplot.jl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "b = bar(x,y,color=\"#0f87bf\",align=\"center\",alpha=0.4)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "b = barh(x,y,color=\"#0f87bf\",align=\"center\",alpha=0.4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Bar Plots](pyplot_barplot.png)\n", "\n", "
\n", "\n", "## Errorbar Plot\n", "([IJulia](pyplot_errorbar.ipynb), [Code](pyplot_errorbar.jl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "errorbar(x, # Original x data points, N values\n", " y, # Original y data points, N values\n", " yerr=errs, # Plus/minus error ranges, Nx2 values\n", " fmt=\"o\") # Format" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Error Bars](pyplot_errorbar.png)\n", "\n", "
\n", "\n", "## Inexact Plot\n", "([IJulia](pyplot_inexact.ipynb), [Code](pyplot_inexact.jl))\n", "\n", "The IJulia example does not properly apply all the formatting as the terminal version does." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "xkcd() # Set to XKCD mode, based on the comic (hand drawn)\n", "# Plot everything" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Inexact Plot](pyplot_inexact.png)\n", "\n", "
\n", "\n", "## Pie Chart\n", "([IJulia](pyplot_piechart.ipynb), [Code](pyplot_piechart.jl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "p = pie(sizes,\n", " labels=labels,\n", " shadow=true,\n", " startangle=90,\n", " explode=explode,\n", " colors=colors,\n", " autopct=\"%1.1f%%\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Pie Chart](pyplot_piechart.png)\n", "\n", "
\n", "\n", "## Scatter Plot\n", "([IJulia](pyplot_scatterplot.ipynb), [Code](pyplot_scatterplot.jl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "scatter(x,y,s=areas,alpha=0.5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Scatter Plot](pyplot_scatterplot.png)\n", "\n", "
\n", "\n", "## Box Plot\n", "([IJulia](pyplot_boxplot.ipynb), [Code](pyplot_boxplot.jl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "boxplot(data, # Each column/cell is one box\n", " notch=true, # Notched center\n", " whis=0.75, # Whisker length as a percent of inner quartile range\n", " widths=0.25, # Width of boxes\n", " vert=false, # Horizontal boxes\n", " sym=\"rs\") # Symbol color and shape (rs = red square)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Box Plot](pyplot_boxplot.png)\n", "\n", "
\n", "\n", "## Major and Minor Ticks\n", "([IJulia](pyplot_majorminor.ipynb), [Code](pyplot_majorminor.jl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "###########################\n", "# Set the tick interval #\n", "###########################\n", "Mx = matplotlib.ticker.MultipleLocator(20) # Define interval of major ticks\n", "f = matplotlib.ticker.FormatStrFormatter(\"%1.2f\") # Define format of tick labels\n", "ax.xaxis.set_major_locator(Mx) # Set interval of major ticks\n", "ax.xaxis.set_major_formatter(f) # Set format of tick labels\n", "\n", "mx = matplotlib.ticker.MultipleLocator(5) # Define interval of minor ticks\n", "ax.xaxis.set_minor_locator(mx) # Set interval of minor ticks\n", "\n", "My = matplotlib.ticker.MultipleLocator(0.5) # Define interval of major ticks\n", "ax.yaxis.set_major_locator(My) # Set interval of major ticks\n", "\n", "my = matplotlib.ticker.MultipleLocator(0.1) # Define interval of minor ticks\n", "ax.yaxis.set_minor_locator(my) # Set interval of minor ticks\n", "\n", "#########################\n", "# Set tick dimensions #\n", "#########################\n", "ax.xaxis.set_tick_params(which=\"major\",length=10,width=2)\n", "ax.xaxis.set_tick_params(which=\"minor\",length=5,width=2)\n", "\n", "fig.canvas.draw() # Update the figure" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Major and Minor Ticks](pyplot_majorminor.png)\n", "\n", "
\n", "\n", "## Multi-axis Plot\n", "([IJulia](pyplot_multiaxis.ipynb), [Code](pyplot_multiaxis.jl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "################\n", "# Other Axes #\n", "################\n", "new_position = [0.06;0.06;0.77;0.91] # Position Method 2\n", "ax.set_position(new_position) # Position Method 2: Change the size and position of the axis\n", "#fig.subplots_adjust(right=0.85) # Position Method 1\n", "\n", "ax2 = ax.twinx() # Create another axis on top of the current axis\n", "font2 = Dict(\"color\"=>\"purple\")\n", "ylabel(\"Right Axis\",fontdict=font2)\n", "p = plot(x,y2,color=\"purple\",linestyle=\"-\",marker=\"o\",label=\"Second\") # Plot a basic line\n", "ax2.set_position(new_position) # Position Method 2\n", "setp(ax2.get_yticklabels(),color=\"purple\") # Y Axis font formatting\n", "\n", "ax3 = ax.twinx() # Create another axis on top of the current axis\n", "ax3.spines[\"right\"].set_position((\"axes\",1.12)) # Offset the y-axis label from the axis itself so it doesn't overlap the second axis\n", "font3 = Dict(\"color\"=>\"green\")\n", "ylabel(\"Far Right Axis\",fontdict=font3)\n", "p = plot(x,y3,color=\"green\",linestyle=\"-\",marker=\"o\",label=\"Third\") # Plot a basic line\n", "ax3.set_position(new_position) # Position Method 2\n", "setp(ax.get_yticklabels(),color=\"green\") # Y Axis font formatting\n", "\n", "axis(\"tight\")\n", "\n", "# Enable just the right part of the frame\n", "ax3.set_frame_on(true) # Make the entire frame visible\n", "ax3.patch.set_visible(false) # Make the patch (background) invisible so it doesn't cover up the other axes' plots\n", "ax3.spines[\"top\"].set_visible(false) # Hide the top edge of the axis\n", "ax3.spines[\"bottom\"].set_visible(false) # Hide the bottom edge of the axis\n", "\n", "fig.canvas.draw() # Update the figure" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Multi-axis Plot](pyplot_multiaxis.png)\n", "\n", "
\n", "\n", "## Axis Placement\n", "([IJulia](pyplot_axis_placement.ipynb), [Code](pyplot_axis_placement.jl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ax.spines[\"top\"].set_visible(false) # Hide the top edge of the axis\n", "ax.spines[\"right\"].set_visible(false) # Hide the right edge of the axis\n", "ax.spines[\"left\"].set_position(\"center\") # Move the right axis to the center\n", "ax.spines[\"bottom\"].set_position(\"center\") # Most the bottom axis to the center\n", "ax.xaxis.set_ticks_position(\"bottom\") # Set the x-ticks to only the bottom\n", "ax.yaxis.set_ticks_position(\"left\") # Set the y-ticks to only the left" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ax2.spines[\"top\"].set_visible(false) # Hide the top edge of the axis\n", "ax2.spines[\"right\"].set_visible(false) # Hide the right edge of the axis\n", "ax2.xaxis.set_ticks_position(\"bottom\")\n", "ax2.yaxis.set_ticks_position(\"left\")\n", "ax2.spines[\"left\"].set_position((\"axes\",-0.03)) # Offset the left scale from the axis\n", "ax2.spines[\"bottom\"].set_position((\"axes\",-0.05)) # Offset the bottom scale from the axis" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Axis Placement](pyplot_axis_placement.png)\n", "\n", "
\n", "\n", "## Surface and Contour Plots\n", "([IJulia](pyplot_surfaceplot.ipynb), [Code](pyplot_surfaceplot.jl))\n", "\n", "Thanks to [Daniel Høegh](https://gist.github.com/dhoegh) for providing this example." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "plot_surface(xgrid, ygrid, z, rstride=2,edgecolors=\"k\", cstride=2, cmap=ColorMap(\"gray\"), alpha=0.8, linewidth=0.25)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "contour(xgrid, ygrid, z, colors=\"black\", linewidth=2.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Surface and Contour Plots](pyplot_surfaceplot.png)\n", "\n", "
\n", "\n", "## Broken Axis Subplot\n", "([IJulia](pyplot_brokenAxisSubplot.ipynb), [Code](pyplot_brokenAxisSubplot.jl))\n", "\n", "Thanks to [Ian Butterworth](https://gist.github.com/ianshmean) for providing this example." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "axes_grid1 = pyimport(\"mpl_toolkits.axes_grid1\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "divider = axes_grid1.make_axes_locatable(ax)\n", "ax2 = divider.new_vertical(size=\"100%\", pad=0.1)\n", "fig.add_axes(ax2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ax.spines[\"top\"].set_visible(false)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ax2.spines[\"bottom\"].set_visible(false)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Upper Line Break Markings\n", "d = 0.015 # how big to make the diagonal lines in axes coordinates\n", "ax2.plot((-d, +d), (-d, +d), transform=ax2.transAxes, color=\"k\", clip_on=false,linewidth=0.8) # Left diagonal\n", "ax2.plot((1 - d, 1 + d), (-d, +d), transform=ax2.transAxes, color=\"k\", clip_on=false,linewidth=0.8) # Right diagonal\n", "\n", "# Lower Line Break Markings\n", "ax.plot((-d, +d), (1 - d, 1 + d), transform=ax.transAxes, color=\"k\", clip_on=false,linewidth=0.8) # Left diagonal\n", "ax.plot((1 - d, 1 + d), (1 - d, 1 + d), transform=ax.transAxes, color=\"k\", clip_on=false,linewidth=0.8) # Right diagonal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Broken Axis Subplot](pyplot_brokenAxisSubplot.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "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": 1 }