Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
464d41e
Import docstring
lukelbd Sep 17, 2019
c962d63
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Sep 17, 2019
e2f0777
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Sep 17, 2019
a89016c
Add _concatenate_axes_docstrings, make behavior dependent on whether …
lukelbd Sep 17, 2019
93c6405
Prepend matplotlib summary to proplot method docstrings
lukelbd Sep 17, 2019
7a5692b
Implement 1d wrappers and begin adding interp docstring segments
lukelbd Sep 17, 2019
cd43068
Standardize docstring fragment names, add new fragments
lukelbd Sep 29, 2019
1ff63cc
Fix ginormous merge conflict
lukelbd Nov 28, 2019
b9c9e6c
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Nov 30, 2019
a41df85
Pep8 compliance
lukelbd Nov 30, 2019
da9e82a
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Nov 30, 2019
fb37b47
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Dec 2, 2019
9ac7946
Merge from master
lukelbd Dec 2, 2019
ae389be
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Dec 2, 2019
27bae6f
Fix RST links
lukelbd Dec 2, 2019
ec6c359
Merge from master
lukelbd Dec 7, 2019
65d3142
Merge from master
lukelbd Dec 14, 2019
902f101
Fix example size
lukelbd Dec 14, 2019
63474ad
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Dec 14, 2019
499d7f2
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Jan 7, 2020
7ff34f0
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Jan 7, 2020
e1131f5
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Jan 7, 2020
d9c2260
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Jan 7, 2020
6c86d3c
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Jan 7, 2020
fb9ba07
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Jan 7, 2020
ca72203
Merge branch 'master' into wrapper-docs-on-methods
lukelbd Jan 20, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix ginormous merge conflict
  • Loading branch information
lukelbd committed Nov 28, 2019
commit 1ff63ccdd694dedf63eb9a4bafde8b0ac7195f00
4 changes: 3 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@

import os
import sys
import matplotlib # loads local matplotlibrc which sets up docstring settings
import matplotlib # load local matplotlibrc and set up docstring settings
from pygments.formatters import HtmlFormatter
from pygments.styles import get_all_styles

# Sphinx-automodapi requires proplot on path
sys.path.insert(0, os.path.abspath('..'))
Expand Down
187 changes: 95 additions & 92 deletions proplot/axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1076,98 +1076,6 @@ def boxplot(self, *args,
artist.set_markersize(markersize)
return obj

@docstring.dedent_interpd
@_standardize_1d
@_cmap_changer
def cmapline(self, *args, values=None,
cmap=None, norm=None,
interp=0, **kwargs):
"""
Invoked when you pass the `cmap` keyword argument to
`~matplotlib.axes.Axes.plot`. Draws a "colormap line",
i.e. a line whose color changes as a function of the parametric
coordinate ``values``. using the input colormap ``cmap``.

This is actually a collection of lines, added as a
`~matplotlib.collections.LineCollection` instance. See `this matplotlib example
<https://matplotlib.org/gallery/lines_bars_and_markers/multicolored_line.html>`__.

Parameters
----------
*args : (y,) or (x,y)
The coordinates. If `x` is not provided, it is inferred from `y`.
cmap : colormap spec, optional
The colormap specifier, passed to `~proplot.styletools.Colormap`.
values : list of float
The parametric values used to map points on the line to colors
in the colormap.
norm : normalizer spec, optional
The normalizer, passed to `~proplot.styletools.Norm`.
interp : int, optional
Number of values between each line joint and each *halfway* point
between line joints to which you want to interpolate.
"""
# First error check
# WARNING: So far this only works for 1D *x* and *y* coordinates. Cannot
# draw multiple colormap lines at once, unlike `~matplotlib.axes.Axes.plot`.
if values is None:
raise ValueError('Requires a "values" keyword arg.')
if len(args) not in (1,2):
raise ValueError(f'Requires 1-2 arguments, got {len(args)}.')
y = np.array(args[-1]).squeeze()
x = np.arange(y.shape[-1]) if len(args) == 1 else np.array(args[0]).squeeze()
values = np.array(values).squeeze()
if x.ndim != 1 or y.ndim != 1 or values.ndim != 1:
raise ValueError(f'x ({x.ndim}-d), y ({y.ndim}-d), and values ({values.ndim}-d) must be 1-dimensional.')
if len(x) != len(y) or len(x) != len(values) or len(y) != len(values):
raise ValueError(f'{len(x)} xs, {len(y)} ys, but {len(values)} colormap values.')

# Interpolate values to allow for smooth gradations between values
# (bins=False) or color switchover halfway between points (bins=True)
# Then optionally interpolate the corresponding colormap values
if interp > 0:
xorig, yorig, vorig = x, y, values
x, y, values = [], [], []
for j in range(xorig.shape[0]-1):
idx = (slice(None, -1) if j+1 < xorig.shape[0]-1 else slice(None))
x.extend(np.linspace(xorig[j], xorig[j+1], interp + 2)[idx].flat)
y.extend(np.linspace(yorig[j], yorig[j+1], interp + 2)[idx].flat)
values.extend(np.linspace(vorig[j], vorig[j+1], interp + 2)[idx].flat)
x, y, values = np.array(x), np.array(y), np.array(values)
coords = []
levels = utils.edges(values)
for j in range(y.shape[0]):
# Get x/y coordinates and values for points to the 'left' and
# 'right' of each joint
if j == 0:
xleft, yleft = [], []
else:
xleft = [(x[j-1] + x[j])/2, x[j]]
yleft = [(y[j-1] + y[j])/2, y[j]]
if j+1 == y.shape[0]:
xright, yright = [], []
else:
xleft = xleft[:-1] # prevent repetition when joined with right
yleft = yleft[:-1]
xright = [x[j], (x[j+1] + x[j])/2]
yright = [y[j], (y[j+1] + y[j])/2]
pleft = np.stack((xleft, yleft), axis=1)
pright = np.stack((xright, yright), axis=1)
coords.append(np.concatenate((pleft, pright), axis=0))

# Create LineCollection and update with values
hs = mcollections.LineCollection(np.array(coords), cmap=cmap, norm=norm,
linestyles='-', capstyle='butt', joinstyle='miter')
hs.set_array(np.array(values))
hs.update({key:value for key,value in kwargs.items() if key not in ('color',)})

# Add collection, with some custom attributes
self.add_collection(hs)
self.autoscale_view() # data limits not updated otherwise
hs.values = values
hs.levels = levels # needed for other functions some
return hs

@docstring.dedent_interpd
def colorbar(self, *args, loc=None, pad=None,
length=None, width=None, space=None, frame=None, frameon=None,
Expand Down Expand Up @@ -2013,6 +1921,101 @@ def violinplot(self, *args,
artist.set_facecolor(fillcolor)
return obj

@docstring.dedent_interpd
@_standardize_1d
@_cmap_changer
def parametric(self, *args, values=None,
cmap=None, norm=None,
interp=0, **kwargs):
"""
Invoked when you pass the `cmap` keyword argument to
`~matplotlib.axes.Axes.plot`. Draws a "colormap line",
i.e. a line whose color changes as a function of the parametric
coordinate ``values``. using the input colormap ``cmap``.

This is actually a collection of lines, added as a
`~matplotlib.collections.LineCollection` instance. See `this matplotlib example
<https://matplotlib.org/gallery/lines_bars_and_markers/multicolored_line.html>`__.

Parameters
----------
*args : (y,) or (x,y)
The coordinates. If `x` is not provided, it is inferred from `y`.
cmap : colormap spec, optional
The colormap specifier, passed to `~proplot.styletools.Colormap`.
values : list of float
The parametric values used to map points on the line to colors
in the colormap.
norm : normalizer spec, optional
The normalizer, passed to `~proplot.styletools.Norm`.
interp : int, optional
If greater than ``0``, we interpolate to additional points
between the `values` coordinates. The number corresponds to the
number of additional color levels between the line joints
and the halfway points between line joints.
"""
# First error check
# WARNING: So far this only works for 1D *x* and *y* coordinates. Cannot
# draw multiple colormap lines at once, unlike `~matplotlib.axes.Axes.plot`.
if values is None:
raise ValueError('Requires a "values" keyword arg.')
if len(args) not in (1,2):
raise ValueError(f'Requires 1-2 arguments, got {len(args)}.')
y = np.array(args[-1]).squeeze()
x = np.arange(y.shape[-1]) if len(args) == 1 else np.array(args[0]).squeeze()
values = np.array(values).squeeze()
if x.ndim != 1 or y.ndim != 1 or values.ndim != 1:
raise ValueError(f'x ({x.ndim}-d), y ({y.ndim}-d), and values ({values.ndim}-d) must be 1-dimensional.')
if len(x) != len(y) or len(x) != len(values) or len(y) != len(values):
raise ValueError(f'{len(x)} xs, {len(y)} ys, but {len(values)} colormap values.')

# Interpolate values to allow for smooth gradations between values
# (bins=False) or color switchover halfway between points (bins=True)
# Then optionally interpolate the corresponding colormap values
if interp > 0:
xorig, yorig, vorig = x, y, values
x, y, values = [], [], []
for j in range(xorig.shape[0]-1):
idx = (slice(None, -1) if j+1 < xorig.shape[0]-1 else slice(None))
x.extend(np.linspace(xorig[j], xorig[j+1], interp + 2)[idx].flat)
y.extend(np.linspace(yorig[j], yorig[j+1], interp + 2)[idx].flat)
values.extend(np.linspace(vorig[j], vorig[j+1], interp + 2)[idx].flat)
x, y, values = np.array(x), np.array(y), np.array(values)
coords = []
levels = utils.edges(values)
for j in range(y.shape[0]):
# Get x/y coordinates and values for points to the 'left' and
# 'right' of each joint
if j == 0:
xleft, yleft = [], []
else:
xleft = [(x[j-1] + x[j])/2, x[j]]
yleft = [(y[j-1] + y[j])/2, y[j]]
if j+1 == y.shape[0]:
xright, yright = [], []
else:
xleft = xleft[:-1] # prevent repetition when joined with right
yleft = yleft[:-1]
xright = [x[j], (x[j+1] + x[j])/2]
yright = [y[j], (y[j+1] + y[j])/2]
pleft = np.stack((xleft, yleft), axis=1)
pright = np.stack((xright, yright), axis=1)
coords.append(np.concatenate((pleft, pright), axis=0))

# Create LineCollection and update with values
hs = mcollections.LineCollection(np.array(coords), cmap=cmap, norm=norm,
linestyles='-', capstyle='butt', joinstyle='miter')
hs.set_array(np.array(values))
hs.update({key:value for key,value in kwargs.items() if key not in ('color',)})

# Add collection, with some custom attributes
self.add_collection(hs)
if self.get_autoscale_on() and self.ignore_existing_data_limits:
self.autoscale_view() # data limits not updated otherwise
hs.values = values
hs.levels = levels # needed for other functions some
return hs

def violins(self, *args, **kwargs):
"""Alias for `~matplotlib.axes.Axes.violinplot`."""
return self.violinplot(*args, **kwargs)
Expand Down
41 changes: 25 additions & 16 deletions proplot/subplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
try:
from matplotlib.backends.backend_macosx import FigureCanvasMac
except ImportError:
mbackend = None
FigureCanvasMac = type(None) # standin null type
from matplotlib import docstring
from .rctools import rc
from .utils import _notNone, _counter, units
Expand Down Expand Up @@ -123,7 +123,7 @@ def __repr__(self):
return 'axes_grid([' + ', '.join(str(ax) for ax in self) + '])'

def __setitem__(self, key, value):
"""Pseudo immutability. Raises LookupError."""
"""Pseudo immutability. Raises error."""
raise LookupError('axes_grid is immutable.')

def __getitem__(self, key):
Expand Down Expand Up @@ -1656,22 +1656,13 @@ def subplots(array=None, ncols=1, nrows=1,
autoformat=True, includepanels=False,
):
"""
Analogous to `matplotlib.pyplot.subplots`. Creates a figure with an
arbitrary layout of axes belong to arbitrary projections, and accepts
various `Figure` and `FlexibleGridSpec` parameters.
Analogous to `matplotlib.pyplot.subplots`, creates a figure with a single
axes or arbitrary grids of axes, any of which can be map projections.

Parameters
----------
ncols, nrows : int, optional
Number of columns, rows in the subplot layout. Ignored if `array` is
passed. Default is ``1``.
order : {'C', 'F'}, optional
Whether subplots are numbered in column-major (``'C'``) or row-major
(``'F'``) order. Analogous to `numpy.array` ordering. This controls
the order axes appear in the `axs` list, and the order of subplot
a-b-c labeling (see `~proplot.axes.Axes.format`).
array : array-like of int, optional
2-dimensional array specifying complex grid of subplots. Think of
array : 2D array-like of int, optional
Array specifying complex grid of subplots. Think of
this array as a "picture" of your figure. For example, the array
``[[1, 1], [2, 3]]`` creates one long subplot in the top row, two
smaller subplots in the bottom row. Integers must range from 1 to the
Expand All @@ -1697,7 +1688,25 @@ def subplots(array=None, ncols=1, nrows=1,
String name corresponding to an academic journal standard that is used
to control the figure width (and height, if specified). Valid names
are as follows.
%(journal_doc)s

=========== ==================== ==========================================================================================================================================================
Key Size description Organization
=========== ==================== ==========================================================================================================================================================
``'pnas1'`` 1-column `Proceedings of the National Academy of Sciences <http://www.pnas.org/page/authors/submission>`__
``'pnas2'`` 2-column ”
``'pnas3'`` landscape page ”
``'ams1'`` 1-column `American Meteorological Society <https://www.ametsoc.org/ams/index.cfm/publications/authors/journal-and-bams-authors/figure-information-for-authors/>`__
``'ams2'`` small 2-column ”
``'ams3'`` medium 2-column ”
``'ams4'`` full 2-column ”
``'agu1'`` 1-column `American Geophysical Union <https://publications.agu.org/author-resource-center/figures-faq/>`__
``'agu2'`` 2-column ”
``'agu3'`` full height 1-column ”
``'agu4'`` full height 2-column ”
``'aaas1'`` 1-column `American Association for the Advancement of Science <https://www.sciencemag.org/authors/instructions-preparing-initial-manuscript>`__
``'aaas2'`` 2-column ”
=========== ==================== ==========================================================================================================================================================

ref : int, optional
The reference axes number. The `axwidth`, `axheight`, and `aspect`
keyword args are applied to this axes, and aspect ratio is conserved
Expand Down
25 changes: 14 additions & 11 deletions proplot/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2284,20 +2284,23 @@ def _wrapper(self, *args, **kwargs):
# List wrapped methods in the driver function docstring
# Prevents us from having to both explicitly apply decorators in
# axes.py and explicitly list functions *again* in this file
doc = driver._docstring_orig
if '%(methods)s' in doc:
name = func.__name__
if name in ('cmapline', 'heatmap', 'area', 'areax'):
name = f'`~proplot.axes.Axes.{name}`'
docstring = driver._docstring_orig
if '%(methods)s' in docstring:
if name in proplot_methods:
link = f'`~proplot.axes.Axes.{name}`'
elif name in cartopy_methods:
link = f'`~cartopy.mpl.geoaxes.GeoAxes.{name}`'
else:
link = f'`~matplotlib.axes.Axes.{name}`'
methods = driver._methods_wrapped
if name not in methods:
methods.append(name)
string = (', '.join(methods[:-1])
+ ','*min(1, len(methods)-2) # Oxford comma bitches
+ ' and ' + methods[-1])
driver.__doc__ = doc % {'methods': string}
if link not in methods:
methods.append(link)
string = (
', '.join(methods[:-1])
+ ',' * int(len(methods)>2) # Oxford comma bitches
+ ' and ' * int(len(methods)>1)
+ methods[-1])
driver.__doc__ = docstring % {'methods': string}
return _wrapper
return decorator

Expand Down
40 changes: 23 additions & 17 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,31 @@
long_description = ''

setup(
name = 'proplot',
url = 'https://lukelbd.github.io/proplot',
author = 'Luke Davis',
version = '1.0',
author_email = 'lukelbd@gmail.com',
python_requires = '>=3.6.0',
project_urls = {
url = 'https://lukelbd.github.io/proplot',
name = 'proplot',
author = 'Luke Davis',
author_email = 'lukelbd@gmail.com',
maintainer = 'Luke Davis',
maintainer_email = 'lukelbd@gmail.com',
python_requires = '>=3.6.0',
project_urls={
'Bug Tracker': 'https://github.com/lukelbd/proplot/issues',
'Documentation': 'https://lukelbd.github.io/proplot',
'Source Code': 'https://github.com/lukelbd/proplot'
},
packages = ['proplot'], # reserve name
package_data = {'': [
'cmaps/*', 'fonts/*', 'colors/*', '.proplotrc'
]},
install_requires = [
'matplotlib>=2.2', 'numpy>=1.11', 'lxml>=4.0.0',
packages = ['proplot'],
classifiers = classifiers,
include_package_data = True, # normally uses MANIFEST.in but setuptools_scm auto-detects tracked files
install_requires = install_req,
license = 'MIT',
description = 'A comprehensive wrapper for making beautiful, publication-quality graphics.',
long_description = long_description,
long_description_content_type = 'text/x-rst',
use_scm_version={'version_scheme': 'post-release', 'local_scheme': 'dirty-tag'},
setup_requires=[
'setuptools_scm',
'setuptools>=30.3.0',
'setuptools_scm_git_archive',
],
license = open('LICENSE.txt').read(),
description = 'A comprehensive matplotlib wrapper for making beautiful, publication-quality graphics.',
long_description = open('README.rst').read(),
)
)

You are viewing a condensed version of this merge commit. You can view the full changes here.