Skip to content

Commit

Permalink
Fix basics documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
lukelbd committed Dec 5, 2019
1 parent 1553f7b commit 35cb21f
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 74 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ Features

Bug fixes
---------
- Fix minor `~proplot.utils.arange` and `~proplot.utils.edges` bugs (:commit:`aaa479fc`).
- Fix shared *x* and *y* axis bugs (:commit:`ac14e9dd`).
- Disable automatic resizing for the ``nbAgg`` interactive inline backend. Found no
suitable workaround (:commit:`3a622887`).
- Fix issue where customized super title settings are overridden when
new axes are created.

Deprecated
----------
Expand Down
115 changes: 60 additions & 55 deletions docs/basics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## The subplots command"
"## Figures and subplots"
]
},
{
Expand All @@ -30,7 +30,7 @@
"* Just like `matplotlib.pyplot.subplots`, you can use `~proplot.subplots.subplots` without arguments to generate a single-axes subplot or with `ncols` or `nrows` to set up simple grids of subplots.\n",
"* Unlike `matplotlib.pyplot.subplots`, you can *also* use `~proplot.subplots.subplots` to draw arbitrarily complex grids using a 2D array of integers. Just think of this array as a \"picture\" of your figure, where each unique integer corresponds to a unique axes and ``0`` corresponds to an empty space.\n",
"\n",
"In the below examples, we create subplot grids with `~proplot.subplots.subplots`, draw some lines, and modify the axes using :ref:`The format method` and :ref:`The subplot grid class`."
"In the below examples, we create subplot grids with `~proplot.subplots.subplots` and modify the axes using `~proplot.axes.Axes.format` and `~proplot.subplots.subplot_grid`. See :ref:`Formatting subplots` and :ref:`Subplot grids` for details."
]
},
{
Expand Down Expand Up @@ -67,45 +67,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## The subplot grid class"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Instead of an `~numpy.ndarray` of axes, `~proplot.subplots.subplots` returns a special `~proplot.subplots.subplot_grid` container. This container behaves like a python list, but lets you call any command on multiple axes at once. It supports both 2D indexing (e.g. ``axs[0,1]``) and 1D indexing (e.g. ``axs[2]``), and is row-major by default. Further, slicing a subplot grid (e.g. ``axs[:,0]``) returns another subplot grid.\n",
"\n",
"You can make your own `~proplot.subplots.subplot_grid` by passing a list of axes to the class. In the below example, the `~proplot.subplots.subplot_grid` returned by `~proplot.subplots.subplots` is used to call :ref:`The format method` on several axes at once."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import proplot as plot\n",
"import numpy as np\n",
"state = np.random.RandomState(51423)\n",
"f, axs = plot.subplots(ncols=4, nrows=4, axpad=0.05, axwidth=1)\n",
"axs[:, 0].format(color='red5', linewidth=1.2)\n",
"axs[0, :].format(color='blue5', linewidth=1.2)\n",
"axs[0].format(color='black', linewidth=2)\n",
"axs[1:,1:].format(facecolor='gray2')\n",
"for ax in axs[1:, 1:]:\n",
" ax.plot(state.rand(6, 4), color='gray7', cycle_kw={\n",
" 'linestyle': ('-', ':', '--', '-.')})\n",
"axs.format(xlabel='xlabel', ylabel='ylabel', suptitle='Axes grid demo')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The format method"
"## Formatting subplots"
]
},
{
Expand All @@ -120,7 +82,7 @@
"2. Remaining keyword args are passed to the class-specific `~proplot.axes.XYAxes` `~proplot.axes.XYAxes.format`, `~proplot.axes.ProjAxes` `~proplot.axes.ProjAxes.format`, or `~proplot.axes.PolarAxes` `~proplot.axes.PolarAxes.format` methods.\n",
"3. Still remaining keyword args are passed to the `~proplot.axes.Axes` `~proplot.axes.Axes.format` method. `~proplot.axes.Axes` is the base class for all other axes classes. This changes axes titles, a-b-c subplot labeling, and figure titles.\n",
"\n",
"``format`` lets you use simple shorthands for changing all kinds of axes settings at once, instead of the verbose, one-liner setter methods like ``ax.set_title()``, ``ax.set_xlabel()``, and ``ax.xaxis.tick_params()``. It is also integrated with the `~proplot.axistools.Locator`, `~proplot.axistools.Formatter`, and `~proplot.axistools.Scale` constructors, so you don't have to directly invoke verbose abstract classes. The goal here is to reduce the amount of boilerplate code needed for drawing highly customized plots."
"``format`` lets you use simple shorthands for changing all kinds of axes settings at once, instead of the verbose, one-liner setter methods like ``ax.set_title()``, ``ax.set_xlabel()``, and ``ax.xaxis.tick_params()``. It is also integrated with the `~proplot.axistools.Locator`, `~proplot.axistools.Formatter`, and `~proplot.axistools.Scale` constructors, so you don't have to directly invoke verbose abstract classes. The goal here is to *reduce the amount of typing needed for drawing highly customized plots*."
]
},
{
Expand All @@ -130,7 +92,10 @@
"outputs": [],
"source": [
"import proplot as plot\n",
"import numpy as np\n",
"f, axs = plot.subplots(ncols=2, nrows=2, share=0, tight=True, axwidth=1.7)\n",
"state = np.random.RandomState(51423)\n",
"axs[0].plot(np.linspace(1, 10, 80), (state.rand(80, 5) - 0.5).cumsum(axis=0))\n",
"axs.format(\n",
" suptitle='Format command demo',\n",
" abc=True, abcloc='ul', abcstyle='a.',\n",
Expand All @@ -139,18 +104,18 @@
" collabels=['Column label 1', 'Column label 2'], rowlabels=['Row label 1', 'Row label 2'],\n",
" xlabel='x-axis', ylabel='y-axis',\n",
" xlim=(1, 10), xticks=1, xscale='log',\n",
" ylim=(0, 4), yticks=plot.arange(0, 4), yticklabels=('a', 'bb', 'c', 'dd', 'e'),\n",
" ylim=(-2, 2), yticks=plot.arange(-2, 2), yticklabels=('a', 'bb', 'c', 'dd', 'e'),\n",
" xtickdir='inout', xtickminor=False,\n",
" ytickloc='both', yticklabelloc='both', ygridminor=True,\n",
" linewidth=1, gridlinewidth=1, gridminorlinewidth=0.5,\n",
" linewidth=0.8, gridlinewidth=0.8, gridminorlinewidth=0.5,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The rc configurator"
"## Changing rc settings"
]
},
{
Expand All @@ -174,29 +139,69 @@
"import numpy as np\n",
"# Update global settings in several different ways\n",
"plot.rc.cycle = 'colorblind'\n",
"plot.rc.color = 'gray6'\n",
"plot.rc.update({'fontname': 'DejaVu Sans'})\n",
"plot.rc['figure.facecolor'] = 'gray3'\n",
"plot.rc.axesfacecolor = 'gray4'\n",
"# Context settings applied to figure only\n",
"with plot.rc.context(linewidth=1.5):\n",
"with plot.rc.context({'suptitle.size': 11}, toplabelcolor='gray6', linewidth=1.5):\n",
" f, axs = plot.subplots(ncols=2, aspect=1, width=6, span=False, sharey=2)\n",
"# Plot stuff\n",
"N, M = 100, 6\n",
"state = np.random.RandomState(51423)\n",
"values = np.arange(1, M+1)\n",
"# Cycle from two concatenated monochromatic colormaps\n",
"cycle = plot.Cycle('C0', 'C1', M, fade=80)\n",
"for i, ax in enumerate(axs):\n",
" data = np.cumsum(state.rand(N, M)-0.5, axis=0)\n",
" lines = ax.plot(data, linewidth=3, cycle=cycle)\n",
"axs.format(grid=False, ycolor='blue7',\n",
" xlabel='x label', ylabel='y label',\n",
" suptitle='Applying new rc settings')\n",
" data = np.cumsum(state.rand(N, M) - 0.5, axis=0)\n",
" lines = ax.plot(data, linewidth=3, cycle='Grays')\n",
"axs.format(grid=False, xlabel='x label', ylabel='y label',\n",
" collabels=['Column label 1', 'Column label 2'],\n",
" suptitle='Rc settings demo',\n",
" suptitlecolor='gray7',\n",
" abc=True, abcloc='l', abcstyle='A)',\n",
" title='Title', titleloc='r', titlecolor='gray7')\n",
"ay = axs[-1].twinx()\n",
"ay.format(ycolor='r', linewidth=1.5, ylabel='secondary axis')\n",
"ay.plot((state.rand(100)-0.2).cumsum(), color='r', lw=3)\n",
"ay.format(ycolor='red', linewidth=1.5, ylabel='secondary axis')\n",
"ay.plot((state.rand(100) - 0.2).cumsum(), color='r', lw=3)\n",
"plot.rc.reset() # reset persistent mods made at head of cell"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Subplot grids"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Instead of an `~numpy.ndarray` of axes, `~proplot.subplots.subplots` returns a special `~proplot.subplots.subplot_grid` container. This container behaves like a python list, but lets you call any command on multiple axes at once. It supports both 2D indexing (e.g. ``axs[0,1]``) and 1D indexing (e.g. ``axs[2]``), and is row-major by default. Further, slicing a subplot grid (e.g. ``axs[:,0]``) returns another subplot grid.\n",
"\n",
"You can make your own `~proplot.subplots.subplot_grid` by passing a list of axes to the class. In the below example, the `~proplot.subplots.subplot_grid` returned by `~proplot.subplots.subplots` is used to call :ref:`The format method` on several axes at once."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import proplot as plot\n",
"import numpy as np\n",
"state = np.random.RandomState(51423)\n",
"f, axs = plot.subplots(ncols=4, nrows=4, axwidth=1.2)\n",
"axs[:, 0].format(color='red', facecolor='gray3', linewidth=1)\n",
"axs[0, :].format(color='gray7', facecolor='gray3', linewidth=1)\n",
"axs[0].format(color='black', facecolor='gray5', linewidth=1.4)\n",
"axs[1:, 1:].format(facecolor='gray1')\n",
"for ax in axs[1:, 1:]:\n",
" ax.plot((state.rand(50, 5) - 0.5).cumsum(axis=0), cycle='Grays', lw=2)\n",
"axs.format(xlabel='xlabel', ylabel='ylabel', suptitle='Subplot grid demo',\n",
" grid=False, xlim=(0, 50), ylim=(-4, 4))"
]
}
],
"metadata": {
Expand Down
19 changes: 11 additions & 8 deletions docs/subplots.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@
"source": [
"By default, ProPlot *automatically* determines the suitable figure width and height for your subplot grid. The figure dimensions are constrained by the dimensions of the *reference* subplot. In practice, this usually sets the properties for *all* subplots, unless your subplots have different aspect ratios or your subplot grid is very complex.\n",
"\n",
"* To fix the figure dimension(s), pass `width`, `height`, and/or `figsize` to `~proplot.subplots.subplots`.\n",
"* To fix the reference subplot dimension(s), use `axwidth`, `axheight`, and/or `aspect` (default is ``axwidth=2`` with ``aspect=1``).\n",
"* To set the reference subplot, use `ref` (default is ``1``, i.e. the subplot in the upper left corner).\n",
"* If the `aspect ratio mode <https://matplotlib.org/2.0.2/examples/pylab_examples/equal_aspect_ratio.html>`__ for the `ref` subplot is set to ``'equal'``, as with :ref:`Geographic and polar plots` and `~matplotlib.axes.Axes.imshow` plots, the existing aspect will be used instead of the input `aspect`.\n",
"This feature is controlled by a variety of `~proplot.subplots.subplots` keyword arguments.\n",
"\n",
"* To set the reference subplot, use `ref` (default is ``1``, i.e. the subplot in the upper left corner). To set the refernce subplot aspect ratio, use `aspect` (default is ``1``).\n",
"* If you use *either* `axwidth` or `axheight`, both figure dimensions are determined automatically and the reference subplot aspect ratio is preserved (default is ``axwidth=2``).\n",
"* If you use *either* `width` or `height`, the other figure dimension is determined automatically and the reference subplot aspect ratio is preserved.\n",
"* If you use *both* `width` and `height` (or `figsize`, which is a ``(width, height)`` tuple), the figure dimensions are fixed and the reference subplot aspect ratio is *not* preserved.\n",
"* When the `ref` subplot `aspect ratio mode <https://matplotlib.org/2.0.2/examples/pylab_examples/equal_aspect_ratio.html>`__ is set to ``'equal'``, as with :ref:`Geographic and polar plots` and `~matplotlib.axes.Axes.imshow` plots, the existing aspect will be used instead of the input `aspect`.\n",
"\n",
"By default, ProPlot also applies a *tight layout* algorithm to every figure. This algorithm automatically adjusts the space between subplot rows and columns and the figure edge to accomadate labels.\n",
"Matplotlib has `its own tight layout algorithm <https://matplotlib.org/3.1.1/tutorials/intermediate/tight_layout_guide.html>`__,\n",
"but ProPlot's algorithm may change the figure dimensions and permits *variable spacing* between subsequent subplot rows and columns, thanks to the new `~proplot.subplots.GridSpec` class.\n",
"but ProPlot's algorithm may change the figure dimensions (depending on the keyword arguments you passed to `~proplot.subplots.subplots`) and permits *variable spacing* between subsequent subplot rows and columns, thanks to the new `~proplot.subplots.GridSpec` class.\n",
"\n",
"ProPlot's tight layout algorithm can also be easily overridden. When you pass a spacing argument like `left`, `right`, `top`, `bottom`, `wspace`, or `hspace` to `~proplot.subplots.subplots`, that value is *always respected*.\n",
"\n",
Expand Down Expand Up @@ -120,9 +123,9 @@
" f, axs = plot.subplots(\n",
" ncols=3, width='13cm', height='2in',\n",
" wspace=('10pt', '20pt'), right='10mm')\n",
" panel = axs[2].panel_axes('r', width='2em')\n",
" axs.format(suptitle='Arguments with arbitrary units',\n",
" xlabel='x axis', ylabel='y axis')\n",
"panel = axs[2].panel_axes('r', width='2em')\n",
"axs.format(suptitle='Arguments with arbitrary units',\n",
" xlabel='x axis', ylabel='y axis')\n",
"plot.rc.reset()"
]
},
Expand Down
2 changes: 1 addition & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Figure and axes methods
The `~proplot.subplots.Figure` and `~proplot.axes.Axes` subclasses
include several *brand new* methods and add to the functionality of several *existing* methods.

* The new `~proplot.axes.Axes.format` method is used to fine-tune various axes settings. Its behavior depends on whether the axes is an `~proplot.axes.XYAxes`, `~proplot.axes.PolarAxes`, or `~proplot.axes.ProjAxes`. Think of this as a dedicated `~matplotlib.artist.Artist.update` method for axes artists. See :ref:`The format command` for details.
* The new `~proplot.axes.Axes.format` method is used to fine-tune various axes settings. Its behavior depends on whether the axes is an `~proplot.axes.XYAxes`, `~proplot.axes.PolarAxes`, or `~proplot.axes.ProjAxes`. Think of this as a dedicated `~matplotlib.artist.Artist.update` method for axes artists. See :ref:`Formatting subplots` and :ref:`Changing rc settings` for details.
* The `~proplot.subplots.Figure` `~proplot.subplots.Figure.colorbar` and `~proplot.subplots.Figure.legend` and `~proplot.axes.Axes` `~proplot.axes.Axes.colorbar` and `~proplot.axes.Axes.legend` commands are used to add colorbars and legends *inside* of subplots, along the *outside edge* of subplots, and along the *edge of the figure*. They considerably simplify the process of drawing colorbars and legends. See :ref:`Colorbars and legends` for details.
* ProPlot adds a huge variety of features for working with `~matplotlib.axes.Axes.contour` plots, `~matplotlib.axes.Axes.pcolor` plots, `~matplotlib.axes.Axes.plot` lines, `~proplot.axes.Axes.heatmap` plots, `~matplotlib.axes.Axes.errorbar` bars, `~matplotlib.axes.Axes.bar` plots, `~proplot.axes.Axes.area` plots, and `~proplot.axes.Axes.parametric` plots. See :ref:`1d plotting` and :ref:`2d plotting` for details.

Expand Down
21 changes: 13 additions & 8 deletions proplot/axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -740,19 +740,24 @@ def format(
self._title_pad = pad

# Super title
# NOTE: These are actually *figure-wide* settings, but that line seems
# to get blurred -- where we have shared axes, spanning labels, and
# NOTE: These are actually *figure-wide* settings, but that line
# gets blurred where we have shared axes, spanning labels, and
# whatnot. May result in redundant assignments if formatting more than
# one axes, but operations are fast so some redundancy is nbd.
# NOTE: Below workaround prevents changed *figure-wide* settings
# from getting overwritten when user makes a new axes.
fig = self.figure
suptitle = _notNone(figtitle, suptitle, None,
names=('figtitle', 'suptitle'))
kw = rc.fill({
'fontsize': 'suptitle.size',
'weight': 'suptitle.weight',
'color': 'suptitle.color',
'fontfamily': 'font.family'
})
if len(fig._axes_main) > 1 and rc._getitem_mode == 1:
kw = {}
else:
kw = rc.fill({
'fontsize': 'suptitle.size',
'weight': 'suptitle.weight',
'color': 'suptitle.color',
'fontfamily': 'font.family'
})
if suptitle or kw:
fig._update_figtitle(suptitle, **kw)
# Labels
Expand Down
2 changes: 1 addition & 1 deletion proplot/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def edges2d(z):
Like `edges` but for 2d arrays.
The size of both axes are increased by one. This is used
internally to calculate graitule edges when you supply centers to
`~matplotlib.axes.Axes.pcolor` or `~matplotlib.axes.Axes.pcolormesh`,
`~matplotlib.axes.Axes.pcolor` or `~matplotlib.axes.Axes.pcolormesh`.
Parameters
----------
Expand Down

0 comments on commit 35cb21f

Please sign in to comment.