Skip to content

Commit fb64eb0

Browse files
committed
Overview, faq, why proplot
1 parent d6a7c5a commit fb64eb0

File tree

6 files changed

+119
-43
lines changed

6 files changed

+119
-43
lines changed

docs/faq.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
Frequently asked questions
33
==========================
44

5-
What makes this matplotlib wrapper special?
6-
===========================================
5+
What makes this matplotlib wrapper different?
6+
=============================================
77

88
There is already a great matplotlib wrapper called `seaborn <https://seaborn.pydata.org/>`__. Also, `pandas <https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.html>`__ and `xarray <http://xarray.pydata.org/en/stable/plotting.html>`__ both offer convenient matplotlib plotting commands. How does ProPlot compare against these tools?
99

@@ -18,8 +18,8 @@ In a nutshell, ProPlot is intended to *unify the convenience of seaborn, pandas,
1818
.. So while ProPlot includes similar tools, the scope and goals are largely different.
1919
.. Indeed, parts of ProPlot were inspired by these projects -- in particular, ``rctools.py`` and ``colortools.py`` are modeled after seaborn. However the goals and scope of ProPlot are largely different:
2020
21-
Why didn't you contribute to matplotlib directly?
22-
=================================================
21+
Why didn't you add to matplotlib directly?
22+
==========================================
2323

2424
Since ProPlot is built right into the matplotlib API, you might be wondering why we didn't contribute to the matplotlib project directly. The main answer is *speed* and *autonomy*, but there are a few practical limitations:
2525

docs/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ A comprehensive, easy-to-use `matplotlib <https://matplotlib.org/>`__ wrapper fo
1616
:maxdepth: 1
1717
:caption: Getting Started
1818

19-
quick-overview
20-
why-proplot
19+
why
20+
overview
2121
faq
2222

2323
.. toctree::
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ If you tend to use the `~matplotlib.pyplot` API and are not familiar with the "a
88

99
This page is meant as the starting point for new users. It is
1010
populated with links to the :ref:`API reference` and User Guide.
11-
For a more in-depth perspective, see :ref:`Why proplot?`
11+
For more in-depth descriptions, see :ref:`Why ProPlot?`.
1212

1313
Importing proplot
1414
=================
@@ -30,7 +30,8 @@ Top-level commands
3030

3131
ProPlot's features derive from the `~proplot.subplots.subplots` command, inspired
3232
by the pyplot `~matplotlib.pyplot.subplots` command.
33-
`~proplot.subplots.subplots` creates a `~proplot.subplots.Figure` subclass
33+
34+
The `~proplot.subplots.subplots` command creates a `~proplot.subplots.Figure` subclass
3435
populated with special `~proplot.axes.Axes` subclasses,
3536
and is packed with new features -- one highlight is the new :ref:`Figure tight layout`
3637
algorithm applied to all `~proplot.subplots.Figure`\ s by default.

docs/projection.ipynb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,7 @@
7979
"\n",
8080
"So, with ProPlot, you no longer have to invoke verbose cartopy `~cartopy.crs.CRS` classes like `~cartopy.crs.LambertAzimuthalEqualArea`, or mess about with a separate `~mpl_toolkits.basemap.Basemap` instance.\n",
8181
"\n",
82-
"To pass keyword args to `~mpl_toolkits.basemap.Basemap` and `cartopy.crs.Projection` classes, use the `proj_kw` dictionary. ProPlot lets you supply native PROJ.4 keyword names to the `cartopy.crs.Projection` classes, e.g. `lon_0` instead of `central_longitude`. This makes things a bit less verbose. ProPlot also lets you draw `~mpl_toolkits.basemap.Basemap` projections without having to always specify the projection settings by applying sensible defaults.\n",
83-
"\n",
84-
"Note that the basemap developers plan to `halt active development after 2020 <https://matplotlib.org/basemap/users/intro.html#cartopy-new-management-and-eol-announcement>`__, since cartopy is integrated more closely with the matplotlib API and has more room for growth. For now, cartopy is `missing several features <https://matplotlib.org/basemap/api/basemap_api.html#module-mpl_toolkits.basemap>`__ offered by basemap -- namely, flexible meridian and parallel gridline labels, drawing physical map scales, and convenience features for adding background images like the \"blue marble\". But once these are added to cartopy, ProPlot support for basemap may be removed."
82+
"To pass keyword args to `~mpl_toolkits.basemap.Basemap` and `cartopy.crs.Projection` classes, use the `proj_kw` dictionary. ProPlot lets you supply native PROJ.4 keyword names to the `cartopy.crs.Projection` classes, e.g. `lon_0` instead of `central_longitude`. This makes things a bit less verbose. ProPlot also lets you draw `~mpl_toolkits.basemap.Basemap` projections without having to always specify the projection settings by applying sensible defaults."
8583
]
8684
},
8785
{
Lines changed: 107 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@ Why ProPlot?
44

55
ProPlot's core mission
66
is to improve upon the parts of matplotlib that
7-
tend to be cumbersome and repetitive.
7+
tend to be cumbersome or repetitive
8+
for power users.
89
This page
910
enumerates these limitations and
1011
describes how ProPlot addresses them.
11-
For a more comprehensive overview of ProPlot's features,
12+
To start using these new features, see
1213
see :ref:`Quick overview` and the User Guide.
1314

14-
Efficient modifications
15-
=======================
15+
No more boilerplate
16+
===================
17+
1618
.. raw:: html
1719

1820
<h3>Problem</h3>
@@ -71,17 +73,17 @@ This may seem "unpythonic" but it is absolutely invaluable when making plots. Pl
7173

7274
The below table lists the constructor functions and the keyword arguments that use them.
7375

74-
============================== ============================= ========================================================
76+
============================== ============================= ================================================================================================================================================================================================
7577
Function Returns Interpreted by
76-
============================== ============================= ========================================================
77-
`~proplot.axistools.Locator` Axis locator ``locator=``, ``xlocator=``, ``ylocator=``
78-
`~proplot.axistools.Formatter` Axis formatter ``formatter=``, ``xformatter=``, ``yformatter=``
78+
============================== ============================= ================================================================================================================================================================================================
79+
`~proplot.axistools.Locator` Axis locator ``locator=``, ``xlocator=``, ``ylocator=``, ``minorlocator=``, ``xminorlocator=``, ``yminorlocator=``, ``ticks=``, ``xticks=``, ``yticks=``, ``minorticks=``, ``xminorticks=``, ``yminorticks=``
80+
`~proplot.axistools.Formatter` Axis formatter ``formatter=``, ``xformatter=``, ``yformatter=``, ``ticklabels=``, ``xticklabels=``, ``yticklabels=``
7981
`~proplot.axistools.Scale` Axis scale ``xscale=``, ``yscale=``
8082
`~proplot.styletools.Colormap` Colormap ``cmap=``
8183
`~proplot.styletools.Cycle` Property cycler ``cycle=``
8284
`~proplot.styletools.Norm` Colormap normalizer ``norm=``
8385
`~proplot.projs.Proj` Cartopy or basemap projection ``proj=``
84-
============================== ============================= ========================================================
86+
============================== ============================= ================================================================================================================================================================================================
8587

8688
Fluid figure dimensions
8789
=======================
@@ -104,6 +106,7 @@ Several matplotlib backends require figure dimensions to be fixed. When `~proplo
104106

105107
The right layout every time
106108
===========================
109+
107110
.. raw:: html
108111

109112
<h3>Problem</h3>
@@ -129,8 +132,9 @@ In ProPlot, the tight layout algorithm is simpler and more accurate because:
129132
..
130133
ProPlot introduces a marginal limitation (see discussion in :pr:`50`) but *considerably* simplifies the tight layout algorithm.
131134
132-
Easier colorbars and legends
133-
============================
135+
Simpler colorbars and legends
136+
=============================
137+
134138
.. raw:: html
135139

136140
<h3>Problem</h3>
@@ -182,32 +186,95 @@ In ProPlot, `~proplot.subplots.subplots` returns an `~proplot.subplots.axes_grid
182186

183187
Further, thanks to the `~proplot.subplots.axes_grid.__getattr__` override, `~proplot.subplots.axes_grid` allows you to call arbitrary methods on arbitrary axes all at once, e.g. ``axs.format(tickminor=False)``.
184188

185-
Arbitrary physical units
186-
========================
189+
Xarray and pandas integration
190+
=============================
187191

188-
..
189-
* Configuring spaces and dimensions in matplotlib often requires physical units.
192+
.. raw:: html
193+
194+
<h3>Problem</h3>
195+
196+
Matplotlib strips metadata from the array-like `xarray` `~xarray.DataArray` container and the `pandas` `~pandas.DataFrame` and `~pandas.Series` containers. To create plots that
197+
are automatically labeled with metadata from these containers, you need to use
198+
the dedicated `xarray plotting <http://xarray.pydata.org/en/stable/plotting.html>`__ and `pandas plotting <https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html>`__ tools.
199+
200+
This approach is somewhat cumbersome -- plotting methods should be invoked on the axes, not on the data container! It also requires learning a slightly different syntax, and tends to encourage using the `~matplotlib.pyplot` API rather than the object-oriented API.
201+
202+
.. raw:: html
203+
204+
<h3>Solution</h3>
205+
206+
ProPlot *reproduces* most of the `xarray.DataArray.plot` and `pandas.DataFrame.plot` features on the `~proplot.axes.Axes`
207+
plotting methods themselves! Axis tick labels, axis labels, subplot titles, and colorbar and legend labels are automatically applied
208+
when a `~xarray.DataArray`, `~pandas.DataFrame`, or `~pandas.Series` is passed through
209+
a plotting method instead of a `~numpy.ndarray`.
210+
This is accomplished by passing positional arguments through the
211+
`~proplot.wrappers.standardize_1d` and `~proplot.wrappers.standardize_2d`
212+
wrappers.
213+
214+
Various plotting improvements
215+
=============================
190216

191217
.. raw:: html
192218

193219
<h3>Problem</h3>
194220

195-
Matplotlib uses "inches" for figure dimensions and figure-relative or axes-relative units almost everywhere else. The problem is:
221+
Certain plotting tasks are quite difficult to accomplish
222+
with the default matplotlib API. The `seaborn`, `xarray`, and `pandas`
223+
packages offer improvements, but it would be nice
224+
to have this functionality build right into matplotlib.
196225

197-
* Inches are foreign to the world outside of the U.S.
198-
* Figure-relative and axes-relative units encourage "tinkering" with meaningless numbers that change the subjective appearance when the physical dimensions change, since *text* and *lines* are specified in the physical units "points".
226+
.. raw:: html
227+
228+
<h3>Solutions</h3>
229+
230+
The ProPlot `~proplot.axes.Axes` class
231+
wraps various plotting methods to reproduce
232+
certain features from `seaborn`, `xarray`, and `pandas`:
233+
234+
* The new `~proplot.axes.Axes.heatmap` command draws `~matplotlib.axes.Axes.pcolormesh` plots and puts ticks at the center of each box.
235+
* The `~matplotlib.axes.Axes.bar` and `~matplotlib.axes.Axes.barh` commands now accept 2D arrays, and can *stack* or *group* successive columns of data, thanks to `~proplot.wrappers.bar_wrapper`.
236+
* The new `~proplot.axes.Axes.area` and `~proplot.axes.Axes.areax` commands mimic the `~proplot.axes.Axes.fill_between` and `~proplot.axes.Axes.fill_betweenx` commands, but also support drawing *stacked* area plots for 2D arrays.
237+
238+
`~proplot.axes.Axes` also includes the following
239+
new plotting features:
240+
241+
* `~matplotlib.axes.Axes.pcolor` and `~matplotlib.axes.Axes.pcolormesh` plots use auto-generated coordinate *edges* if you pass coordinate *centers*.
242+
* `~proplot.axes.Axes.area` plots can be assigned different colors for negative and positive values. This will also be added to `~matplotlib.axes.Axes.bar` soon.
243+
* `~matplotlib.axes.Axes.pcolor`, `~matplotlib.axes.Axes.pcolormesh`, `~proplot.axes.Axes.heatmap`, `~matplotlib.axes.Axes.contour` and `~matplotlib.axes.Axes.contourf` plots can be assigned contour and box labels by simply passing ``labels=True`` to the plotting command.
244+
* `~matplotlib.axes.Axes.plot`, `~matplotlib.axes.Axes.scatter`, and `~matplotlib.axes.Axes.bar` plots can be assigned error bars using a variety of `~proplot.wrappers.errorbar_wrapper` keyword args.
245+
* `~proplot.axes.Axes.parametric` plots can be made with colormap colors marking the parametric coordinates rather than text annotations.
246+
* `~matplotlib.axes.Axes.pcolor`, `~matplotlib.axes.Axes.pcolormesh`, `~proplot.axes.Axes.heatmap`, `~matplotlib.axes.Axes.contour` and `~matplotlib.axes.Axes.contourf` plots on geographic axes can be inteprolated to global coverage by passing ``globe=True`` tot he plotting command.
247+
248+
See :ref:`1d plotting commands` and :ref:`2d plotting commands`
249+
for details.
250+
251+
Cartopy and basemap integration
252+
===============================
253+
254+
.. raw:: html
255+
256+
<h3>Problem</h3>
257+
258+
There are two widely-used engines
259+
for plotting geophysical data with matplotlib: `cartopy` and `~mpl_toolkits.basemap`.
260+
Using cartopy tends to be quite verbose and involve lots of boilerplate code,
261+
while basemap is outdated and requires you to use plotting commands on a separate `~mpl_toolkits.basemap.Basemap` object.
262+
263+
Also, `cartopy` and `~mpl_toolkits.basemap` plotting commands assume *map projection coordinates* unless specified otherwise. For most of us, this choice is very frustrating, since geophysical data are usually stored in longitude-latitude or "Plate Carrée" coordinates.
199264

200265
.. raw:: html
201266

202267
<h3>Solution</h3>
203268

204-
ProPlot permits arbitrary physical units for almost all sizing arguments, e.g. ``left='0.5cm'``. This is done by passing various keyword arguments through the `~proplot.utils.units` engine.
269+
ProPlot includes various `cartopy` and `~mpl_toolkits.basemap` features
270+
using the `~proplot.axes.ProjAxes` class. The corresponding `~proplot.axes.ProjAxes.format` command lets you apply all kinds of geographic plot settings, like coastlines, continents, political boundaries, and meridian and parallel gridlines.
271+
It also makes longitude-latitude coordinates the *default*:
205272

206-
* This prevents "tinkering" and encourages users to be aware of the physical dimensions describing their figure.
207-
* You can also use font-relative units, e.g. ``left='1em'``. This is nice when you don't care about physical dimensions, but need something more intuitive than figure-relative units.
273+
* ``latlon=True`` is the default for `~proplot.axes.BasemapAxes` plotting methods.
274+
* ``transform=ccrs.PlateCarree()`` is the default for `~proplot.axes.GeoAxes` plotting methods.
275+
276+
Note that the basemap developers plan to `halt active development after 2020 <https://matplotlib.org/basemap/users/intro.html#cartopy-new-management-and-eol-announcement>`__, since cartopy is integrated more closely with the matplotlib API and has more room for growth. For now, cartopy is `missing several features <https://matplotlib.org/basemap/api/basemap_api.html#module-mpl_toolkits.basemap>`__ offered by basemap -- namely, flexible meridian and parallel gridline labels, drawing physical map scales, and convenience features for adding background images like the "blue marble". But once these are added to cartopy, ProPlot support for basemap may be removed.
208277

209-
..
210-
* You can still use axes-relative and figure-relative units for most arguments with e.g. ``left='0.1fig'`` or ``left='0.1ax'``.
211278

212279
Working with colormaps
213280
======================
@@ -283,27 +350,36 @@ It is clear that the task discretizing colormap colors should be left to the **n
283350

284351
<h3>Solution</h3>
285352

286-
In ProPlot, all colormap visualizations are automatically discretized with the `~proplot.styletools.BinNorm` class. This reads the ``extend`` property passed to your plotting command and chooses colormap indices so that your colorbar levels *always* traverse the full range of colormap colors.
353+
In ProPlot, all colormap visualizations are automatically discretized with the `~proplot.styletools.BinNorm` class. This reads the `extend` property passed to your plotting command and chooses colormap indices so that your colorbar levels *always* traverse the full range of colormap colors.
287354

288355
`~proplot.styletools.BinNorm` can also apply an arbitrary continuous normalizer, e.g. `~matplotlib.colors.LogNorm`, before discretization. Think of it as a "meta-normalizer" -- other normalizers perform the continuous transformation step, while this performs the discretization step.
289356

290-
Cartopy and basemap defaults
291-
============================
357+
Arbitrary physical units
358+
========================
359+
360+
..
361+
* Configuring spaces and dimensions in matplotlib often requires physical units.
362+
292363
.. raw:: html
293364

294365
<h3>Problem</h3>
295366

296-
In cartopy and basemap, the default coordinate system is always map projection coordinates. For most of us, this choice is very frustrating. Geophysical data is almost always stored in longitude-latitude or "Plate Carrée" coordinates.
367+
Matplotlib uses "inches" for figure dimensions and figure-relative or axes-relative units almost everywhere else. The problem is:
368+
369+
* Inches are foreign to the world outside of the U.S.
370+
* Figure-relative and axes-relative units encourage "tinkering" with meaningless numbers that change the subjective appearance when the physical dimensions change, since *text* and *lines* are specified in the physical units "points".
297371

298372
.. raw:: html
299373

300374
<h3>Solution</h3>
301375

302-
ProPlot makes longitude-latitude coordinates
303-
the *default*:
376+
ProPlot permits arbitrary physical units for almost all sizing arguments, e.g. ``left='0.5cm'``. This is done by passing various keyword arguments through the `~proplot.utils.units` engine.
304377

305-
* ``latlon=True`` is the new default for `~proplot.axes.BasemapAxes` plotting methods.
306-
* ``transform=ccrs.PlateCarree()`` is the new default for `~proplot.axes.GeoAxes` plotting methods.
378+
* This prevents "tinkering" and encourages users to be aware of the physical dimensions describing their figure.
379+
* You can also use font-relative units, e.g. ``left='1em'``. This is nice when you don't care about physical dimensions, but need something more intuitive than figure-relative units.
380+
381+
..
382+
* You can still use axes-relative and figure-relative units for most arguments with e.g. ``left='0.1fig'`` or ``left='0.1ax'``.
307383
308384
...and much more!
309385
=================
@@ -312,5 +388,4 @@ This page is not comprehensive -- it just
312388
illustrates how ProPlot addresses
313389
some of the stickiest matplotlib limitations
314390
that bug your average power user.
315-
316391
See :ref:`Quick overview` and the User Guide for a more comprehensive overview.

proplot/axistools.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,8 @@ def __init__(self, *args,
372372

373373
def __call__(self, x, pos=None):
374374
"""
375+
Convert number to a string.
376+
375377
Parameters
376378
----------
377379
x : float

0 commit comments

Comments
 (0)