Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6653b7f
Remove half-baked 'rgbcycle' option
lukelbd May 13, 2020
f801852
Make default style closer to matplotlib
lukelbd May 13, 2020
979e5c2
Rename 'defaults.py' to 'rcsetup.py'
lukelbd May 13, 2020
dff1579
Cleanup basemap wrappers
lukelbd May 13, 2020
50a262d
Support pcolorfast with wrappers
lukelbd May 13, 2020
2480ca3
Better warning message for show_cmaps
lukelbd May 13, 2020
9ac149e
Remove smart_bounds support
lukelbd May 13, 2020
02e4403
Minor bugfix
lukelbd May 13, 2020
d016fda
Add 'negcolor' and 'poscolor' kwargs
lukelbd May 13, 2020
72e11a5
Clean up area plot wrapper, add support for new settings
lukelbd May 13, 2020
ab4d674
Add negpos support for bar plots
lukelbd May 13, 2020
8c05fdf
Update docs
lukelbd May 13, 2020
aedd877
Update plot wrapper
lukelbd May 13, 2020
e3217d7
Update docs
lukelbd May 13, 2020
45629b1
Update changelog
lukelbd May 13, 2020
65ec4b5
Fix custom_roles sphinxext
lukelbd May 13, 2020
1c53e94
Support vlines/hlines/stem
lukelbd May 13, 2020
3428295
Rename add_errorbars
lukelbd May 13, 2020
345e9d5
Bugfix
lukelbd May 13, 2020
d89134c
Clean up _rename_kwargs decorator
lukelbd May 14, 2020
c35ca89
Better error message for invalid legend locs
lukelbd May 14, 2020
6861de1
Fix helper func that detects legend labels/titles
lukelbd May 14, 2020
d8c50a8
Add indicate_error shading support, rename keywords
lukelbd May 14, 2020
4d25323
Support adding shading to legend labels
lukelbd May 14, 2020
55448dd
Avoid duplicate keyword arg warnings
lukelbd May 14, 2020
ffc049e
Update error bars example
lukelbd May 14, 2020
9b7c3c0
Update changelog
lukelbd May 14, 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
32 changes: 25 additions & 7 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ ProPlot v0.6.0 (2020-##-##)

There are quite a lot of deprecations for this release.

- Rename `add_errorbars` to `~proplot.axes.plot.indicate_error` and rename
various keyword args (:pr:`166`, :commit:`d8c50a8d`).
- Remove ``'rgbcycle'`` setting (:commit:`6653b7f0`).
- Deprecate support for "parametric" plots inside `~matplotlib.axes.Axes.plot`,
instead use `~proplot.axes.Axes.parametric` (:commit:`64210bce`).
- Change `~proplot.utils.units` ``units`` keyword argument to more natural
Expand Down Expand Up @@ -115,10 +118,25 @@ There are quite a lot of deprecations for this release.

.. rubric:: Features

- Support building a colormap and `DiscreteNorm` inside `~matplotlib.axes.Axes.scatter`,
just like `contourf` and `pcolormesh` (:pr:`162`).
- Add options to `~proplot.axes.plot.indicate_error` for adding *shading*
to arbitrary plots (:pr:`166`, :commit:`d8c50a8d`). Also support automatic legend
entries for shading and ensure `indicate_error` preserves metadata.
- Wrap ``pcolorfast`` just like ``pcolor`` and ``pcolormesh`` are
wrapped (:commit:`50a262dd`).
- Add ``negpos`` feature to `~proplot.axes.plot.bar_wrapper` and new
:rcraw:`negcolor` and :rcraw:`poscolor` rc keyword arguments (:commit:`ab4d6746`).
- Increase default line width from ``0.6`` to ``0.8`` to match matplotlib defaults
(:commit:`f801852b`; try to avoid frivolously changing defaults).
- Change default resolution for geographic features from ``'lo'`` to ``'med'``
(:commit:`f801852b`).
- Change default line style for geographic gridlines from ``':'`` to ``'-'``
and match style from primary gridlines (:commit:`f801852b`).
- Support cartopy inline meridian and parallel gridlines and support
changing the gridline padding (:commit:`###`).
- Support `cartopy 0.18 <https://scitools.org.uk/cartopy/docs/latest/whats_new.html>`__
locators, formatters, deprecations, and new labelling features (:pr:`158`).
- Support building a colormap and `DiscreteNorm` inside `~matplotlib.axes.Axes.scatter`,
just like `contourf` and `pcolormesh` (:pr:`162`).
- Add :rcraw:`geogrid.labelpad` and :rcraw:`geogrid.rotatelabels` settings
for cartopy gridline labels (:pr:`158`).
- Support more `~proplot.ticker.AutoFormatter` features on
Expand Down Expand Up @@ -161,6 +179,8 @@ There are quite a lot of deprecations for this release.

.. rubric:: Bug fixes

- Fix various issues with axis label sharing and axis sharing for
twinned axes and panel axes (:pr:`164`).
- Fix issue drawing bar plots with datetime *x* axes (:pr:`156`).
- Fix issue where `~proplot.ticker.AutoFormatter` tools were not locale-aware, i.e. use
comma as decimal point sometimes (:commit:`c7636296`).
Expand Down Expand Up @@ -206,9 +226,8 @@ There are quite a lot of deprecations for this release.
sensible behavior.
- Turn some private `~proplot.config` functions into static
methods (:commit:`6121de03`).
- Remove "smart bounds" feature from `FuncScale` (:commit:`9ac149ea`).
- Clean up axes iterators (:commit:`c8a0768a`).
- Clean up locator and formatter sharing stuff (:commit:`###`).
- Configure label sharing at draw-time rather than label-time (:commit:`###`).

.. rubric:: Documentation

Expand Down Expand Up @@ -245,7 +264,6 @@ ProPlot v0.5.0 (2020-02-10)

.. rubric:: Bug fixes

- Fix issue where colormaps cannot have "dot" in name (:commit:`###`).
- Fix issue where `~proplot.styletools.show_cmaps` and
`~proplot.styletools.show_cycles` colormap names were messed up
(:commit:`13045599`)
Expand All @@ -256,9 +274,9 @@ ProPlot v0.5.0 (2020-02-10)
`~proplot.wrappers.colorbar_wrapper` were sometimes ignored
(:commit:`fd4f8d5f`).
- Permit passing *lists of colors* to manually shade line contours and filled
contours in `~proplot.wrappers.cmap_changer` (:commit:`###`).
contours in `~proplot.wrappers.cmap_changer`.
- Prevent formatting rightmost meridian label as ``1e-10`` on cartopy map
projections (:commit:`37fdd1eb]`).
projections (:commit:`37fdd1eb`).
- Support CF-time axes by fixing bug in `~proplot.wrappers.standardize_1d`
and `~proplot.wrappers.standardize_2d` (:issue:`103`, :pr:`121`).
- Redirect to the "default" location when using ``legend=True`` and
Expand Down
122 changes: 63 additions & 59 deletions docs/1dplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
fig, axs = plot.subplots(ncols=2, share=False)
x = np.linspace(-5, 5, N)
y = state.rand(N, 5)
axs.format(xlabel='xlabel', ylabel='ylabel', ymargin=0.05)
axs.format(xlabel='xlabel', ylabel='ylabel')
axs.format(suptitle='Standardized arguments demonstration')

# Plot by passing both x and y coordinates
Expand Down Expand Up @@ -182,66 +182,70 @@
# %% [raw] raw_mimetype="text/restructuredtext"
# .. _ug_errorbars:
#
# Adding error bars
# -----------------
# Error bars and shading
# ----------------------
#
# The `~proplot.axes.add_errorbars` wrapper lets you draw error bars
# on-the-fly by passing certain keyword arguments to
# The `~proplot.axes.indicate_error` wrapper lets you draw error bars
# and error shading on-the-fly by passing certain keyword arguments to
# `~matplotlib.axes.Axes.plot`, `~matplotlib.axes.Axes.scatter`,
# `~matplotlib.axes.Axes.bar`, or `~matplotlib.axes.Axes.barh`.
#
# If you pass 2D arrays to these methods with ``means=True`` or
# ``medians=True``, the means or medians of each column are drawn as points,
# lines, or bars, and error bars are drawn to represent the spread in each
# column. `~proplot.axes.add_errorbars` lets you draw both thin error
# "bars" with optional whiskers, and thick error "boxes" overlayed on top of
# these bars (this can be used to represent different percentil ranges).
# Instead of using 2D arrays, you can also pass error bar coordinates
# *manually* with the `bardata` and `boxdata` keyword arguments. See
# `~proplot.axes.add_errorbars` for details.
# lines, or bars, and error bars or shading is drawn to represent the spread in
# each column. `~proplot.axes.indicate_error` lets you draw thin error
# bars with optional whiskers, thick "boxes" overlayed on top of these bars
# (think of this as a miniature boxplot), or up to 2 intervals of shading.
# Instead of using 2D arrays, you can also pass the error bounds
# *manually* with the `bardata`, `boxdata`, `shadedata`, and `fadedata` keyword
# arguments. See `~proplot.axes.indicate_error` for details.

# %%
import proplot as plot
import numpy as np
import pandas as pd
plot.rc['title.loc'] = 'uc'
plot.rc['axes.ymargin'] = plot.rc['axes.xmargin'] = 0.05

# Generate sample data
state = np.random.RandomState(51423)
data = (
state.rand(20, 8).cumsum(axis=0).cumsum(axis=1)[:, ::-1]
+ 20 * state.normal(size=(20, 8)) + 30
)
data = state.rand(20, 8).cumsum(axis=0).cumsum(axis=1)[:, ::-1]
data = data + 20 * state.normal(size=(20, 8)) + 30
data = pd.DataFrame(data, columns=np.arange(0, 16, 2))
data.name = 'variable'

# Generate figure
fig, axs = plot.subplots(
nrows=3, aspect=1.5, axwidth=4,
share=0, hratios=(2, 1, 1)
)
axs.format(suptitle='Error bars with various plotting commands')
axs.format(suptitle='Indicating error bounds with various plotting commands')
axs[1:].format(xlabel='column number', xticks=1, xgrid=False)

# Asking add_errorbars to calculate bars
# Automatically calculate medians and display default percentile range
ax = axs[0]
obj = ax.barh(data, color='red orange', means=True)
obj = ax.barh(
data, color='light red', legend=True,
medians=True, barpctiles=True, boxpctiles=True
)
ax.format(title='Column statistics')
ax.format(ylabel='column number', title='Bar plot', ygrid=False)

# Showing a standard deviation range instead of percentile range
# Automatically calculate means and display requested standard deviation range
ax = axs[1]
ax.scatter(
data, color='k', marker='_', markersize=50,
medians=True, barstd=True, boxes=False, capsize=2,
barcolor='gray6', barrange=(-1, 1), barzorder=0, barlw=1,
data, color='denim', marker='x', markersize=8**2, linewidth=0.8,
means=True, shadestds=(-1, 1), legend='ll',
)
ax.format(title='Scatter plot')

# Supplying error bar data manually
# Manually supply error bar data and legend labels
ax = axs[2]
boxdata = np.percentile(data, (25, 75), axis=0)
bardata = np.percentile(data, (5, 95), axis=0)
means = data.mean(axis=0)
means.name = data.name
shadedata = np.percentile(data, (25, 75), axis=0) # dark shading
fadedata = np.percentile(data, (5, 95), axis=0) # light shading
ax.plot(
data.mean(axis=0), boxes=True,
edgecolor='k', color='gray9',
boxdata=boxdata, bardata=bardata, barzorder=0,
boxcolor='gray7', barcolor='gray7', boxmarker=False,
means, shadedata=shadedata, fadedata=fadedata,
color='ocean blue', barzorder=0, boxmarker=False, legend='ll',
)
ax.format(title='Line plot')
plot.rc.reset()
Expand All @@ -258,9 +262,10 @@
# `~proplot.axes.cycle_changer`, and `~proplot.axes.standardize_1d`.
# You can now *group* or *stack* columns of data by passing 2D arrays to
# `~matplotlib.axes.Axes.bar` or `~matplotlib.axes.Axes.barh`, just like in
# `pandas`. Also, `~matplotlib.axes.Axes.bar` and `~matplotlib.axes.Axes.barh`
# now employ "default" *x* coordinates if you failed to provide them
# explicitly, just like `~matplotlib.axes.Axes.plot`.
# `pandas`, or use different colors for negative and positive bars by
# passing ``negpos=True``. Also, `~matplotlib.axes.Axes.bar` and
# `~matplotlib.axes.Axes.barh` now employ "default" *x* coordinates if you
# failed to provide them explicitly.
#
# To make filled "area" plots, use the new `~proplot.axes.Axes.area` and
# `~proplot.axes.Axes.areax` methods. These are alises for
Expand All @@ -270,7 +275,7 @@
# `~proplot.axes.fill_betweenx_wrapper`. You can now *stack* or *overlay*
# columns of data by passing 2D arrays to `~proplot.axes.Axes.area` and
# `~proplot.axes.Axes.areax`, just like in `pandas`. You can also now draw
# area plots that *change color* when the fill boundaries cross each other by
# area plots that change color when the fill boundaries cross each other by
# passing ``negpos=True`` to `~matplotlib.axes.Axes.fill_between`. The most
# common use case for this is highlighting negative and positive areas with
# different colors, as shown below.
Expand All @@ -280,7 +285,6 @@
import numpy as np
import pandas as pd
plot.rc.titleloc = 'uc'
plot.rc.margin = 0.05
fig, axs = plot.subplots(nrows=2, aspect=2, axwidth=5, share=0, hratios=(3, 2))
state = np.random.RandomState(51423)
data = state.rand(5, 5).cumsum(axis=0).cumsum(axis=1)[:, ::-1]
Expand Down Expand Up @@ -313,33 +317,39 @@
# %%
import proplot as plot
import numpy as np
plot.rc.margin = 0
fig, axs = plot.subplots(array=[[1, 2], [3, 3]], hratios=(1, 0.8), share=0)
axs.format(xlabel='xlabel', ylabel='ylabel', suptitle='Area plot demo')
fig, axs = plot.subplots(array=[[1, 2], [3, 3]], hratios=(1, 1.5), share=0)
axs.format(grid=False, xlabel='xlabel', ylabel='ylabel', suptitle='Area plot demo')
state = np.random.RandomState(51423)
data = state.rand(5, 3).cumsum(axis=0)
cycle = ('gray3', 'gray5', 'gray7')

# Overlaid and stacked area patches
# Overlaid area patches
ax = axs[0]
ax.area(
np.arange(5), data, data + state.rand(5)[:, None], cycle=cycle, alpha=0.5,
np.arange(5), data, data + state.rand(5)[:, None], cycle=cycle, alpha=0.7,
legend='uc', legend_kw={'center': True, 'ncols': 2, 'labels': ['z', 'y', 'qqqq']},
)
ax.format(title='Fill between columns')

# Stacked area patches
ax = axs[1]
ax.area(
np.arange(5), data, stacked=True, cycle=cycle, alpha=0.8,
legend='ul', legend_kw={'center': True, 'ncols': 2, 'labels': ['z', 'y', 'qqqq']},
)
ax.format(title='Stack between columns')

# Positive and negative color area patches
# Positive and negative color bars and area patches
ax = axs[2]
data = 5 * (state.rand(20) - 0.5)
ax.area(data, negpos=True, negcolor='blue7', poscolor='red7')
ax.format(title='Positive and negative colors', xlabel='xlabel', ylabel='ylabel')
axs.format(grid=False)
data = 4 * (state.rand(20) - 0.5)
ax.bar(data, bottom=-2, width=1, edgecolor='none', negpos=True)
ax.area(data + 2, y2=2, negpos=True)
for offset in (-2, 2):
ax.axhline(offset, color='k', linewidth=1, linestyle='--')
ax.format(
xmargin=0, xlabel='xlabel', ylabel='ylabel',
title='Positive and negative colors demo', titleweight='bold',
)
plot.rc.reset()


Expand All @@ -361,18 +371,19 @@
import proplot as plot
import numpy as np
import pandas as pd

# Generate sample data
N = 500
state = np.random.RandomState(51423)
fig, axs = plot.subplots(ncols=2, axwidth=2.5)
data = state.normal(size=(N, 5)) + 2 * (state.rand(N, 5) - 0.5) * np.arange(5)
data = pd.DataFrame(
data,
columns=pd.Index(['a', 'b', 'c', 'd', 'e'], name='xlabel')
)
axs.format(
ymargin=0.1, xmargin=0.1, grid=False,
suptitle='Boxes and violins demo'
)

# Generate figure
fig, axs = plot.subplots(ncols=2, axwidth=2.5)
axs.format(grid=False, suptitle='Boxes and violins demo')

# Box plots
ax = axs[0]
Expand Down Expand Up @@ -428,7 +439,6 @@
x, y, c, cmap=cmap, lw=7, interp=5, capstyle='round', joinstyle='round'
)
ax.format(xlabel='xlabel', ylabel='ylabel', title='Line with smooth gradations')
ax.format(xmargin=0.05, ymargin=0.05)
ax.colorbar(m, loc='b', label='parametric coordinate', locator=5)

# Parametric line with stepped gradations
Expand Down Expand Up @@ -463,12 +473,6 @@
# `~matplotlib.axes.Axes.scatter` now optionally accepts keywords that look
# like `~matplotlib.axes.Axes.plot` keywords (e.g. `color` instead of `c` and
# `markersize` instead of `s`).
#
# We are also considering supporting 2D array input and property cycle
# iteration for more obscure matplotlib plotting commands like
# `~matplotlib.axes.Axes.stem`, `~matplotlib.axes.Axes.step`,
# `~matplotlib.axes.Axes.vlines`, and `~matplotlib.axes.Axes.hlines`. Stay
# tuned.

# %%
import proplot as plot
Expand Down
2 changes: 1 addition & 1 deletion docs/basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@
xlabel='x-axis', ylabel='y-axis',
xscale='log',
xlim=(1, 10), xticks=1,
ylim=(-2, 2), yticks=plot.arange(-2, 2),
ymargin=0.05, yticks=plot.arange(-2, 2),
yticklabels=('a', 'bb', 'c', 'dd', 'e'),
ytickloc='both', yticklabelloc='both',
xtickdir='inout', xtickminor=False, ygridminor=True,
Expand Down
3 changes: 2 additions & 1 deletion docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,10 @@ Key Description
``linewidth`` Thickness of axes spines and major tick lines.
``lut`` The number of colors to put in the colormap lookup table.
``margin`` The margin of space between axes edges and objects plotted inside the axes, if ``xlim`` and ``ylim`` are unset.
``negcolor`` The color for negative bars and shaded areas when using ``negpos=True``.
``ocean`` Boolean, toggles ocean patches on and off.
``poscolor`` The color for positive bars and shaded areas when using ``negpos=True``.
``reso`` Resolution of geographic features, one of ``'lo'``, ``'med'``, or ``'hi'``
``rgbcycle`` If ``True``, and ``colorblind`` is the current cycle, this registers the ``colorblind`` colors as ``'r'``, ``'b'``, ``'g'``, etc., like in `seaborn <https://seaborn.pydata.org/tutorial/color_palettes.html>`__.
``rivers`` Boolean, toggles river lines on and off.
``share`` The axis sharing level, one of ``0``, ``1``, ``2``, or ``3``. See `~proplot.ui.subplots` for details.
``small`` Font size for legend text, tick labels, axis labels, and text generated with `~matplotlib.axes.Axes.text`.
Expand Down
6 changes: 0 additions & 6 deletions docs/projections.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,6 @@
fig.colorbar(m, loc='b', span=i + 1, label='values', extendsize='1.7em')
else:
ax.pcolor(lon, lat, data, cmap=cmap, globe=globe, extend='both')
if globe:
continue
xi = offset + np.linspace(0, 360, 20)
for cmd in (np.sin, np.cos):
yi = cmd(xi * np.pi / 180) * 60
ax.plot(xi, yi, color='k', lw=0, marker='o')
axs.format(
suptitle=titles[globe],
collabels=['Cartopy example', 'Basemap example'],
Expand Down
4 changes: 2 additions & 2 deletions docs/sphinxext/custom_roles.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from docutils import nodes
from os.path import sep
from proplot.internals import defaults
from proplot.internals import rcsetup


def get_nodes(rawtext, text, inliner):
Expand All @@ -20,7 +20,7 @@ def get_nodes(rawtext, text, inliner):
def rc_role(name, rawtext, text, lineno, inliner, options={}, content=[]): # noqa: U100
node_list = get_nodes(rawtext, text, inliner)
try:
default = defaults._get_default_param(text)
default = rcsetup._get_default_param(text)
except KeyError:
pass
else:
Expand Down
4 changes: 2 additions & 2 deletions docs/why.rst
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,8 @@ designed to make your life easier.
`~matplotlib.axes.Axes.fill_betweenx`, you will be able to use different
colors for positive/negative bars.
* All :ref:`1D plotting methods <ug_1dplots>` can be used to :ref:`add error
bars <ug_errorbars>` using various specialized keyword arguments. You no
longer have to work with the `~matplotlib.axes.Axes.errorbar` method
bars or error shading <ug_errorbars>` using various specialized keyword arguments.
You no longer have to work with the `~matplotlib.axes.Axes.errorbar` method
directly. They also accept a
:ref:`"cycle" keyword argument <ug_cycle_changer>`
interpreted by `~proplot.constructor.Cycle` and optional
Expand Down
Loading