Skip to content

Commit b002ea2

Browse files
authored
Merge pull request #162 from lukelbd/scatter-discrete-norm
Support DiscreteNorm in scatter plot colorbars
2 parents 1e0205f + ee57494 commit b002ea2

26 files changed

+440
-446
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ repos:
1010
- id: end-of-file-fixer
1111
- id: trailing-whitespace
1212
- id: flake8
13-
args: ['--max-line-length=88', '--ignore=W503,E402']
13+
args: ['--max-line-length=88', '--ignore=W503,E402,E741']

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ install:
3838
- which python
3939

4040
script:
41-
- flake8 proplot docs --max-line-length=88 --ignore=W503,E402
41+
- flake8 proplot docs --max-line-length=88 --ignore=W503,E402,E741
4242
- pushd docs
4343
- make html
4444
- popd

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ There are quite a lot of deprecations for this release.
115115

116116
.. rubric:: Features
117117

118+
- Support building a colormap and `DiscreteNorm` inside `~matplotlib.axes.Axes.scatter`,
119+
just like `contourf` and `pcolormesh` (:pr:`162`).
118120
- Support `cartopy 0.18 <https://scitools.org.uk/cartopy/docs/latest/whats_new.html>`__
119121
locators, formatters, deprecations, and new labelling features (:pr:`158`).
120122
- Add :rcraw:`geogrid.labelpad` and :rcraw:`geogrid.rotatelabels` settings

docs/1dplots.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
# It is often desirable to use different `property cycles
4141
# <https://matplotlib.org/tutorials/intermediate/color_cycle.html#sphx-glr-tutorials-intermediate-color-cycle-py>`__
4242
# for different axes or different plot elements. To enable this, the
43-
# `~proplot.wrappers.cycle_changer` adds the `cycle` and `cycle_kw` to the 1D
43+
# `~proplot.axes.cycle_changer` adds the `cycle` and `cycle_kw` to the 1D
4444
# plotting methods. These arguments are passed to the
4545
# `~proplot.constructor.Cycle` constructor function, and the resulting property
4646
# cycle is used to style the input data. ProPlot iterates through property
@@ -76,9 +76,9 @@
7676
# Standardized arguments
7777
# ----------------------
7878
#
79-
# The `~proplot.wrappers.standardize_1d` wrapper is used to standardize
79+
# The `~proplot.axes.standardize_1d` wrapper is used to standardize
8080
# positional arguments across all 1D plotting methods.
81-
# `~proplot.wrappers.standardize_1d` allows you to optionally omit *x*
81+
# `~proplot.axes.standardize_1d` allows you to optionally omit *x*
8282
# coordinates, in which case they are inferred from the data. It also permits
8383
# passing 2D *y* coordinate arrays to any plotting method, in which case the
8484
# plotting method is called for each column of the array.
@@ -100,7 +100,7 @@
100100
# Plot by passing both x and y coordinates
101101
ax = axs[0]
102102
ax.area(x, -1 * y / N, stacked=True)
103-
ax.bar(x, y, linewidth=0, alpha=1, width=0.8 * (x[1] - x[0]))
103+
ax.bar(x, y, linewidth=0, alpha=1, width=0.8)
104104
ax.plot(x, y + 1, linewidth=2)
105105
ax.scatter(x, y + 2, marker='s', markersize=5**2)
106106
ax.format(title='Manual x coordinates')
@@ -122,7 +122,7 @@
122122
# Pandas and xarray integration
123123
# -----------------------------
124124
#
125-
# The `~proplot.wrappers.standardize_1d` wrapper integrates 1D plotting
125+
# The `~proplot.axes.standardize_1d` wrapper integrates 1D plotting
126126
# methods with pandas `~pandas.DataFrame`\ s and xarray `~xarray.DataArray`\ s.
127127
# When you pass a DataFrame or DataArray to any plotting command, the x-axis
128128
# label, y-axis label, legend label, colorbar label, and/or title are
@@ -185,20 +185,20 @@
185185
# Adding error bars
186186
# -----------------
187187
#
188-
# The `~proplot.wrappers.add_errorbars` wrapper lets you draw error bars
188+
# The `~proplot.axes.add_errorbars` wrapper lets you draw error bars
189189
# on-the-fly by passing certain keyword arguments to
190190
# `~matplotlib.axes.Axes.plot`, `~matplotlib.axes.Axes.scatter`,
191191
# `~matplotlib.axes.Axes.bar`, or `~matplotlib.axes.Axes.barh`.
192192
#
193193
# If you pass 2D arrays to these methods with ``means=True`` or
194194
# ``medians=True``, the means or medians of each column are drawn as points,
195195
# lines, or bars, and error bars are drawn to represent the spread in each
196-
# column. `~proplot.wrappers.add_errorbars` lets you draw both thin error
196+
# column. `~proplot.axes.add_errorbars` lets you draw both thin error
197197
# "bars" with optional whiskers, and thick error "boxes" overlayed on top of
198198
# these bars (this can be used to represent different percentil ranges).
199199
# Instead of using 2D arrays, you can also pass error bar coordinates
200200
# *manually* with the `bardata` and `boxdata` keyword arguments. See
201-
# `~proplot.wrappers.add_errorbars` for details.
201+
# `~proplot.axes.add_errorbars` for details.
202202

203203
# %%
204204
import proplot as plot
@@ -254,8 +254,8 @@
254254
# ------------------------
255255
#
256256
# The `~matplotlib.axes.Axes.bar` and `~matplotlib.axes.Axes.barh` methods
257-
# are wrapped by `~proplot.wrappers.bar_wrapper`,
258-
# `~proplot.wrappers.cycle_changer`, and `~proplot.wrappers.standardize_1d`.
257+
# are wrapped by `~proplot.axes.bar_wrapper`,
258+
# `~proplot.axes.cycle_changer`, and `~proplot.axes.standardize_1d`.
259259
# You can now *group* or *stack* columns of data by passing 2D arrays to
260260
# `~matplotlib.axes.Axes.bar` or `~matplotlib.axes.Axes.barh`, just like in
261261
# `pandas`. Also, `~matplotlib.axes.Axes.bar` and `~matplotlib.axes.Axes.barh`
@@ -266,8 +266,8 @@
266266
# `~proplot.axes.Axes.areax` methods. These are alises for
267267
# `~matplotlib.axes.Axes.fill_between` and
268268
# `~matplotlib.axes.Axes.fill_betweenx`, which are now wrapped by
269-
# `~proplot.wrappers.fill_between_wrapper` and
270-
# `~proplot.wrappers.fill_betweenx_wrapper`. You can now *stack* or *overlay*
269+
# `~proplot.axes.fill_between_wrapper` and
270+
# `~proplot.axes.fill_betweenx_wrapper`. You can now *stack* or *overlay*
271271
# columns of data by passing 2D arrays to `~proplot.axes.Axes.area` and
272272
# `~proplot.axes.Axes.areax`, just like in `pandas`. You can also now draw
273273
# area plots that *change color* when the fill boundaries cross each other by
@@ -350,9 +350,9 @@
350350
# --------------------------
351351
#
352352
# The `~matplotlib.axes.Axes.boxplot` and `~matplotlib.axes.Axes.violinplot`
353-
# methods are now wrapped with `~proplot.wrappers.boxplot_wrapper`,
354-
# `~proplot.wrappers.violinplot_wrapper`, `~proplot.wrappers.cycle_changer`,
355-
# and `~proplot.wrappers.standardize_1d`. These wrappers add some useful
353+
# methods are now wrapped with `~proplot.axes.boxplot_wrapper`,
354+
# `~proplot.axes.violinplot_wrapper`, `~proplot.axes.cycle_changer`,
355+
# and `~proplot.axes.standardize_1d`. These wrappers add some useful
356356
# options and apply aesthetically pleasing default settings. They also
357357
# automatically apply axis labels based on the `~pandas.DataFrame` column
358358
# labels or the input *x* coordinate labels.
@@ -446,7 +446,7 @@
446446
xlim=(-1, 1), ylim=(-1, 1), title='Step gradations',
447447
xlabel='cosine angle', ylabel='sine angle'
448448
)
449-
ax.colorbar(m, loc='b', maxn=10, label=f'parametric coordinate')
449+
ax.colorbar(m, loc='b', maxn=10, label='parametric coordinate')
450450

451451

452452
# %% [raw] raw_mimetype="text/restructuredtext"
@@ -456,8 +456,8 @@
456456
# -------------
457457
#
458458
# The `~matplotlib.axes.Axes.scatter` method is now wrapped by
459-
# `~proplot.wrappers.scatter_wrapper`, `~proplot.wrappers.cycle_changer`, and
460-
# `~proplot.wrappers.standardize_1d`. This means that
459+
# `~proplot.axes.scatter_wrapper`, `~proplot.axes.cycle_changer`, and
460+
# `~proplot.axes.standardize_1d`. This means that
461461
# `~matplotlib.axes.Axes.scatter` now accepts 2D arrays, just like
462462
# `~matplotlib.axes.Axes.plot`. Also, successive calls to
463463
# `~matplotlib.axes.Axes.scatter` now use the property cycler properties

docs/2dplots.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@
3939
#
4040
# It is often desirable to create ProPlot colormaps on-the-fly, without
4141
# explicitly using the `~proplot.constructor.Colormap` constructor function.
42-
# To enable this, the `~proplot.wrappers.cmap_changer` wrapper adds the
42+
# To enable this, the `~proplot.axes.cmap_changer` wrapper adds the
4343
# `cmap` and `cmap_kw` arguments to every 2D plotting method. These
4444
# arguments are passed to the `~proplot.constructor.Colormap` constructor
4545
# function, and the resulting colormap is used for the input data. For
4646
# example, to create and apply a monochromatic colormap, you can simply use
4747
# ``cmap='color name'``.
4848

49-
# The `~proplot.wrappers.cmap_changer` wrapper also
49+
# The `~proplot.axes.cmap_changer` wrapper also
5050
# adds the `norm` and `norm_kw` arguments. They are passed to the
5151
# `~proplot.constructor.Norm` constructor function, and the resulting
5252
# normalizer is used for the input data. For more information on colormaps
@@ -80,7 +80,7 @@
8080
# Discrete colormap levels
8181
# ------------------------
8282
#
83-
# The `~proplot.wrappers.cmap_changer` wrapper also applies the
83+
# The `~proplot.axes.cmap_changer` wrapper also applies the
8484
# `~proplot.colors.DiscreteNorm` normalizer to every colormap plot.
8585
# `~proplot.colors.DiscreteNorm` converts data values to colormap colors by (1)
8686
# transforming data using an arbitrary *continuous* normalizer (e.g.
@@ -212,7 +212,7 @@
212212
# Standardized arguments
213213
# ----------------------
214214
#
215-
# The `~proplot.wrappers.standardize_2d` wrapper is used to standardize
215+
# The `~proplot.axes.standardize_2d` wrapper is used to standardize
216216
# positional arguments across all 2D plotting methods. Among other things,
217217
# it guesses coordinate *edges* for `~matplotlib.axes.Axes.pcolor` and
218218
# `~matplotlib.axes.Axes.pcolormesh` plots when you supply coordinate
@@ -255,7 +255,7 @@
255255
# Pandas and xarray integration
256256
# -----------------------------
257257
#
258-
# The `~proplot.wrappers.standardize_2d` wrapper also integrates 2D
258+
# The `~proplot.axes.standardize_2d` wrapper also integrates 2D
259259
# plotting methods with pandas `~pandas.DataFrame`\ s and xarray
260260
# `~xarray.DataArray`\ s. When you pass a DataFrame or DataArray to any
261261
# plotting command, the x-axis label, y-axis label, legend label, colorbar
@@ -272,19 +272,20 @@
272272

273273
# DataArray
274274
state = np.random.RandomState(51423)
275-
data = 50 * (
276-
np.sin(np.linspace(0, 2 * np.pi, 20) + 0) ** 2
277-
* np.cos(np.linspace(0, np.pi, 20) + np.pi / 2)[:, None] ** 2
275+
linspace = np.linspace(0, np.pi, 20)
276+
data = 50 * state.normal(1, 0.2, size=(20, 20)) * (
277+
np.sin(linspace * 2) ** 2
278+
* np.cos(linspace + np.pi / 2)[:, None] ** 2
278279
)
279280
lat = xr.DataArray(
280281
np.linspace(-90, 90, 20),
281282
dims=('lat',),
282-
attrs={'units': 'degN'}
283+
attrs={'units': 'deg_north'}
283284
)
284285
plev = xr.DataArray(
285286
np.linspace(1000, 0, 20),
286287
dims=('plev',),
287-
attrs={'long_name': 'pressure', 'units': 'hPa'}
288+
attrs={'long_name': 'pressure', 'units': 'mb'}
288289
)
289290
da = xr.DataArray(
290291
data,
@@ -295,14 +296,14 @@
295296
)
296297

297298
# DataFrame
298-
data = state.rand(20, 20)
299+
data = state.rand(12, 20)
299300
df = pd.DataFrame(
300-
data.cumsum(axis=0).cumsum(axis=1),
301-
index=[*'JFMAMJJASONDJFMAMJJA']
301+
(data - 0.4).cumsum(axis=0).cumsum(axis=1),
302+
index=list('JFMAMJJASOND'),
302303
)
303304
df.name = 'temporal data'
304-
df.index.name = 'index'
305-
df.columns.name = 'time (days)'
305+
df.index.name = 'month'
306+
df.columns.name = 'variable (units)'
306307

307308
# %%
308309
import proplot as plot
@@ -311,13 +312,13 @@
311312

312313
# Plot DataArray
313314
axs[0].contourf(
314-
da, cmap='RdPu', cmap_kw={'left': 0.05}, colorbar='l', lw=0.7, color='gray7'
315+
da, cmap='RdPu', cmap_kw={'left': 0.05}, colorbar='l', lw=0.7, color='k'
315316
)
316317
axs[0].format(yreverse=True)
317318

318319
# Plot DataFrame
319320
axs[1].contourf(
320-
df, cmap='YlOrRd', colorbar='r', linewidth=0.7, color='gray7'
321+
df, cmap='YlOrRd', colorbar='r', linewidth=0.7, color='k'
321322
)
322323
axs[1].format(xtickminor=False)
323324

@@ -328,19 +329,19 @@
328329
# Contour and gridbox labels
329330
# --------------------------
330331
#
331-
# The `~proplot.wrappers.cmap_changer` wrapper also allows you to quickly add
332+
# The `~proplot.axes.cmap_changer` wrapper also allows you to quickly add
332333
# *labels* to `~proplot.axes.Axes.heatmap`, `~matplotlib.axes.Axes.pcolor`,
333334
# `~matplotlib.axes.Axes.pcolormesh`, `~matplotlib.axes.Axes.contour`, and
334335
# `~matplotlib.axes.Axes.contourf` plots by simply using ``labels=True``.
335336
# Critically, the label text is colored black or white depending on the
336337
# luminance of the underlying grid box or filled contour.
337338
#
338-
# `~proplot.wrappers.cmap_changer` draws contour labels with
339+
# `~proplot.axes.cmap_changer` draws contour labels with
339340
# `~matplotlib.axes.Axes.clabel` and grid box labels with
340341
# `~matplotlib.axes.Axes.text`. You can pass keyword arguments to these
341342
# functions using the `labels_kw` dictionary keyword argument, and change the
342343
# label precision with the `precision` keyword argument. See
343-
# `~proplot.wrappers.cmap_changer` for details.
344+
# `~proplot.axes.cmap_changer` for details.
344345

345346
# %%
346347
import proplot as plot

docs/api.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Axes classes
2828

2929
.. automodsumm:: proplot.axes
3030
:toctree: api
31-
:skip: ProjAxes, XYAxes
31+
:classes-only:
3232

3333

3434
Constructor functions
@@ -52,13 +52,15 @@ Configuration tools
5252
Plotting wrappers
5353
=================
5454

55-
.. automodule:: proplot.wrappers
55+
.. automodule:: proplot.axes.plot
5656

57-
.. automodsumm:: proplot.wrappers
57+
.. automodsumm:: proplot.axes
5858
:toctree: api
59+
:functions-only:
60+
:skip: ProjAxes, XYAxes
5961

6062

61-
Show functions
63+
Demo functions
6264
==============
6365

6466
.. automodule:: proplot.demos

docs/axis.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,8 @@
269269
# %% [raw] raw_mimetype="text/restructuredtext"
270270
# .. _ug_scales:
271271
#
272-
# Axis scales
273-
# -----------
272+
# Changing the axis scale
273+
# -----------------------
274274
#
275275
# "Axis scales" like ``'linear'`` and ``'log'`` control the *x* and *y* axis
276276
# coordinate system. To change the axis scale, simply pass e.g.
@@ -448,8 +448,7 @@
448448
# In the latter case, the scale's transforms are used for the forward and
449449
# inverse functions, and the scale's default locators and formatters are used
450450
# for the default `~proplot.scale.FuncScale` locators and formatters.
451-
#
452-
# Notably, the "parent" axis scale is now *arbitrary* -- in the first example
451+
# Note that the "parent" axis scale is now arbitrary -- in the first example
453452
# shown below, we create a `~proplot.axes.CartesianAxes.dualx` axis for an
454453
# axis scaled by the ``'symlog'`` scale.
455454

docs/colorbars_legends.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343
# `~matplotlib.axes.Axes.contourf`). To draw a legend or colorbar-legend in
4444
# one go, pass a location (e.g. ``legend='r'`` or ``colorbar='r'``) to
4545
# methods that accept a `cycle` argument (e.g. `~matplotlib.axes.Axes.plot`).
46-
# This feature is powered by the `~proplot.wrappers.cmap_changer` and
47-
# `~proplot.wrappers.cycle_changer` wrappers.
46+
# This feature is powered by the `~proplot.axes.cmap_changer` and
47+
# `~proplot.axes.cycle_changer` wrappers.
4848
#
4949
# Finally, just like matplotlib "inset" legends, ProPlot also supports
5050
# "inset" *colorbars*. To draw an inset colorbar, pass an inset location to
@@ -185,7 +185,7 @@
185185
#
186186
# The `~proplot.figure.Figure` `~proplot.figure.Figure.colorbar` and
187187
# `~proplot.axes.Axes` `~proplot.axes.Axes.colorbar` methods are wrapped by
188-
# `~proplot.wrappers.colorbar_wrapper`, which adds several new features.
188+
# `~proplot.axes.colorbar_wrapper`, which adds several new features.
189189
#
190190
# You can now draw colorbars from *lists of colors* or *lists of artists* by
191191
# passing a list instead of a mappable object. Colorbar minor ticks are now
@@ -243,7 +243,7 @@
243243
#
244244
# The `~proplot.figure.Figure` `~proplot.figure.Figure.legend` and
245245
# `~proplot.axes.Axes` `~proplot.axes.Axes.legend` methods are wrapped by
246-
# `~proplot.wrappers.legend_wrapper`, which adds several new features.
246+
# `~proplot.axes.legend_wrapper`, which adds several new features.
247247
#
248248
# You can draw legends with *centered legend rows*, either by passing
249249
# ``center=True`` or by passing *list of lists* of plot handles. This is

docs/colormaps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
# your convenience, most of these features can be accessed via the
140140
# `~proplot.constructor.Colormap` constructor function. Note that every
141141
# plotting command that accepts a `cmap` keyword passes it through this
142-
# function (see `~proplot.wrappers.cmap_changer`).
142+
# function (see `~proplot.axes.cmap_changer`).
143143
#
144144
# To make `~proplot.colors.PerceptuallyUniformColormap`\ s from scratch, you
145145
# have the following three options:

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
'sphinx_copybutton',
7575
'sphinx_automodapi.automodapi', # see: https://github.com/lukelbd/sphinx-automodapi/tree/proplot-mods # noqa
7676
'nbsphinx',
77-
]
77+
]
7878

7979
extlinks = {
8080
'issue': ('https://github.com/lukelbd/proplot/issues/%s', 'GH#'),

0 commit comments

Comments
 (0)