Skip to content

Commit efb4475

Browse files
committed
Why proplot
1 parent 8bbe050 commit efb4475

File tree

1 file changed

+27
-53
lines changed

1 file changed

+27
-53
lines changed

docs/why.rst

Lines changed: 27 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -85,44 +85,39 @@ Function Returns Interpreted by
8585
`~proplot.projs.Proj` Cartopy or basemap projection ``proj=``
8686
============================== ============================= ================================================================================================================================================================================================
8787

88-
Fluid figure dimensions
89-
=======================
88+
89+
90+
Nice-looking figures out of the box
91+
===================================
92+
9093
.. raw:: html
9194

9295
<h3>Problem</h3>
9396

94-
In matplotlib, you have to specify the physical dimensions of the figure. However, the dimensions of the *individual subplots* are often more important:
97+
Matplotlib plots tend to require lots of "tweaking" when you have more than one subplot in the figure. This is partly because you must specify the physical dimensions of the figure, while the dimensions of the *individual subplots* are more important:
9598

9699
#. The subplot aspect ratio is usually more relevant than the figure aspect ratio, e.g. for map projections.
97100
#. The subplot width and height control the evident thickness of text and other content plotted inside the axes.
98101

102+
Matplotlib has a `tight layout <https://matplotlib.org/tutorials/intermediate/tight_layout_guide.html>`__ algorithm to keep you from having to "tweak" the spacing, but the algorithm cannot apply different amounts of spacing between different subplot row and column boundaries. This sometimes creates figures with unnecessary extra whitespace.
103+
99104
.. raw:: html
100105

101106
<h3>Solution</h3>
102107

103108
In ProPlot, you can specify the physical dimensions of *subplots* instead of the figure by passing `axwidth` or `axheight` to `~proplot.subplots.Figure`. The default behavior is ``axwidth=2`` (inches). Figure dimensions are then automatically calculated to accommodate the subplot geometry and the spacing adjustments.
104109

105-
Several matplotlib backends require figure dimensions to be fixed. When `~proplot.subplots.Figure.draw` changes the figure dimensions, this can "surprise" the backend and cause unexpected behavior. ProPlot fixes this issue for the static inline backend and the Qt popup backend. However, this issue is unfixable the "notebook" inline backend, the "macosx" popup backend, and possibly other untested backends.
106-
107-
The right layout every time
108-
===========================
109-
110-
.. raw:: html
111-
112-
<h3>Problem</h3>
113-
114-
In matplotlib, the tight layout algorithm is very complex, and it cannot apply different amounts of spacing to different subplot rows and columns.
115-
116-
.. raw:: html
117-
118-
<h3>Solution</h3>
110+
..
111+
Several matplotlib backends require figure dimensions to be fixed. When `~proplot.subplots.Figure.draw` changes the figure dimensions, this can "surprise" the backend and cause unexpected behavior. ProPlot fixes this issue for the static inline backend and the Qt popup backend. However, this issue is unfixable the "notebook" inline backend, the "macosx" popup backend, and possibly other untested backends.
119112
120-
In ProPlot, the tight layout algorithm is simpler and more accurate because:
113+
The tight layout algorithm is also simpler and more accurate because:
121114

122115
#. The new `~proplot.subplots.FlexibleGridSpec` class permits variable spacing between rows and columns.
123116
#. The `~proplot.subplots.FlexibleGridSpec` spacing parameters are specified in physical units instead of figure-relative units.
124117
#. Figures are restricted to have only *one* `~proplot.subplots.FlexibleGridSpec` per figure. This is done by requiring users to draw all of their subplots at once with `~proplot.subplots.subplots`. This requirement *considerably* simplifies the algorithm (see :pr:`50` for details).
125118

119+
See :ref:`Figure tight layout` for details.
120+
126121
..
127122
The `~matplotlib.gridspec.FlexibleGridSpec` class is useful for creating figures with complex subplot geometry.
128123
..
@@ -276,43 +271,42 @@ It also makes longitude-latitude coordinates the *default*:
276271
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.
277272

278273

279-
Working with colormaps
280-
======================
274+
Colormaps and property cycles
275+
=============================
276+
281277
.. raw:: html
282278

283279
<h3>Problem</h3>
284280

285-
In matplotlib, colormaps are implemented with the `~matplotlib.colors.ListedColormap` and `~matplotlib.colors.LinearSegmentedColormap` classes. They are very hard to modify and hard to create.
286-
287-
Colormap identification by string name is also suboptimal. The names are case-sensitive, and reversed versions of each colormap (i.e. names that end in ``'_r'``) are not guaranteed to exist.
281+
In matplotlib, colormaps are implemented with the `~matplotlib.colors.ListedColormap` and `~matplotlib.colors.LinearSegmentedColormap` classes. They are very hard to modify and hard to create. Colormap identification by string name is also suboptimal. The names are case-sensitive, and reversed versions of each colormap (i.e. names that end in ``'_r'``) are not guaranteed to exist.
288282

289283
.. raw:: html
290284

291285
<h3>Solution</h3>
292286

293-
In ProPlot, it is easy to generate, combine, and modify colormaps using the `~proplot.styletools.Colormap` constructor function, and thanks to the new `~proplot.styletools.ListedColormap`, `~proplot.styletools.LinearSegmentedColormap`, and `~proplot.styletools.PerceptuallyUniformColormap`. This includes new tools for making colormaps that vary linearly in `perceptually uniform colorspaces <https://en.wikipedia.org/wiki/HCL_color_space>`__, so that they portray your data accurately (see :ref:`Perceptually uniform colormaps` for details).
294-
287+
In ProPlot, it is easy to generate, combine, and modify colormaps using the `~proplot.styletools.Colormap` constructor function, and thanks to the new `~proplot.styletools.ListedColormap`, `~proplot.styletools.LinearSegmentedColormap`, and `~proplot.styletools.PerceptuallyUniformColormap`. This includes new tools for making colormaps that are `perceptually uniform <https://en.wikipedia.org/wiki/HCL_color_space>`__ (see :ref:`Perceptually uniform colormaps` for details).
295288
The `~proplot.styletools.CmapDict` dictionary used to store colormaps also makes colormap identification a bit easier. All colormap names are case-insensitive, and reversed colormaps are automatically created when you request a name ending in ``'_r'``.
296289

297-
..
298-
Also, "colormaps" and "color cycles" are now *fluid*, e.g. you can use a colormap as the color cycler for line plots. This is ProPlot's answer to seaborn's "palettes".
290+
In ProPlot, you can also create arbitrary property cycles with `~proplot.styletools.Cycle` and use them with arbitrary plotting commands with the `cycle` keyword argument. You can also create property cycles from arbitrary colormaps! See `~proplot.styletools.Cycle` for details.
299291

300-
Working with property cycles
301-
============================
292+
Improved colormap normalization
293+
===============================
302294
.. raw:: html
303295

304296
<h3>Problem</h3>
305297

306-
Changing the property cycle is tricky in matplotlib. You have to work with the :rcraw:`axes. prop_cycle` setting and the `~cycler.Cycler` class directly.
298+
In matplotlib, when ``extend='min'``, ``extend='max'``, or ``extend='neither'`` is passed to `~matplotlib.figure.Figure.colorbar` , colormap colors reserved for "out-of-bounds" values are truncated. The problem is that matplotlib discretizes colormaps by generating a low-resolution lookup table (see `~matplotlib.colors.LinearSegmentedColormap` for details).
299+
This approach cannot be fine-tuned, creates an unnecessary copy of the colormap, and prevents you from using the resulting colormap for plots with different numbers of levels.
300+
301+
It is clear that the task discretizing colormap colors should be left to the **normalizer**, not the colormap itself. Matplotlib provides `~matplotlib.colors.BoundaryNorm` for this purpose, but it is seldom used and its features are limited.
307302

308303
.. raw:: html
309304

310305
<h3>Solution</h3>
311306

312-
In ProPlot, you can create arbitrary property cycles with `~proplot.styletools.Cycle` and use them with arbitrary plotting commands with the `cycle` keyword argument. You can also create property cycles from arbitrary colormaps! See `~proplot.styletools.Cycle` for details.
307+
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.
313308

314-
..
315-
Changing the property cycle is easy in ProPlot.
309+
`~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.
316310

317311
Working with fonts
318312
==================
@@ -334,23 +328,3 @@ In ProPlot, the default font is Helvetica. Albeit somewhat overused, this is a t
334328
ProPlot also makes it easier to work with custom fonts by making use of a completely undocumented feature: ``$TTFPATH``. Matplotlib adds ``.ttf`` and ``.otf`` font files in folders listed in the ``$TTFPATH`` environment variable, so ProPlot simply populates that variable. Feel free to drop your own font files into ``~/.proplot/fonts``, and you're good to go.
335329

336330

337-
Improved colormap levels
338-
========================
339-
.. raw:: html
340-
341-
<h3>Problem</h3>
342-
343-
In matplotlib, when ``extend='min'``, ``extend='max'``, or ``extend='neither'`` is passed to `~matplotlib.figure.Figure.colorbar` , colormap colors reserved for "out-of-bounds" values are truncated.
344-
The problem is that matplotlib discretizes colormaps by generating a low-resolution lookup table (see `~matplotlib.colors.LinearSegmentedColormap` for details).
345-
This approach cannot be fine-tuned, creates an unnecessary copy of the colormap, and prevents you from using the resulting colormap for plots with different numbers of levels.
346-
347-
It is clear that the task discretizing colormap colors should be left to the **normalizer**, not the colormap itself. Matplotlib provides `~matplotlib.colors.BoundaryNorm` for this purpose, but it is seldom used and its features are limited.
348-
349-
.. raw:: html
350-
351-
<h3>Solution</h3>
352-
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.
354-
355-
`~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.
356-

0 commit comments

Comments
 (0)