Skip to content

Commit 8188deb

Browse files
authored
Merge pull request #691 from LinkedEarth/MulGeoSeries_map_ext
only a few docstring edits to show customization
2 parents 9b8aa3c + 6a4f341 commit 8188deb

3 files changed

Lines changed: 92 additions & 12 deletions

File tree

pyleoclim/core/multiplegeoseries.py

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,18 @@ def map(self, marker='archiveType', hue='archiveType', size=None, cmap=None,
187187
DESCRIPTION.
188188
The default is 'global'.
189189
190-
cmap : string or list, optional
191-
Matplotlib supported colormap id or list of colors for creating a colormap. See `choosing a matplotlib colormap <https://matplotlib.org/3.5.0/tutorials/colors/colormaps.html>`_.
192-
The default is None.
190+
cmap : str, list, or None, optional
191+
Colormap to use when `hue` is a **numeric** variable. Has no effect when `hue` is
192+
categorical (e.g. ``'archiveType'``), in which case colors come from pyleoclim's
193+
default archive-type palette or the ``hue_mapping`` kwarg. Accepts:
194+
195+
- a named Matplotlib colormap string (e.g. ``'viridis'``, ``'RdBu_r'``, ``'terrain'``)
196+
- a list of colors that will be interpolated into a continuous colormap
197+
(e.g. ``['blue', 'white', 'red']``)
198+
199+
When ``None`` (default), pyleoclim selects ``'vlag'`` for data that span zero
200+
and ``'viridis'`` otherwise.
201+
See `choosing a matplotlib colormap <https://matplotlib.org/stable/gallery/color/colormap_reference.html>`_.
193202
194203
fig : matplotlib.pyplot.figure, optional
195204
See matplotlib.pyplot.figure <https://matplotlib.org/3.5.0/api/_as_gen/matplotlib.pyplot.figure.html#matplotlib-pyplot-figure>_.
@@ -204,8 +213,21 @@ def map(self, marker='archiveType', hue='archiveType', size=None, cmap=None,
204213
For information about Gridspec configuration, refer to `Matplotlib documentation <https://matplotlib.org/3.5.0/api/_as_gen/matplotlib.gridspec.GridSpec.html#matplotlib.gridspec.GridSpec>_. The default is None.
205214
206215
kwargs: dict, optional
207-
- 'missing_val_hue', 'missing_val_marker', 'missing_val_label' can all be used to change the way missing values are represented ('k', '?', are default hue and marker values will be associated with the label: 'missing').
208-
- 'hue_mapping' and 'marker_mapping' can be used to submit dictionaries mapping hue values to colors and marker values to markers. Does not replace passing a string value for hue or marker.
216+
- ``'missing_val_hue'``, ``'missing_val_marker'``, ``'missing_val_label'`` — change
217+
how missing values are represented (defaults: ``'k'``, ``'?'``, ``'missing'``).
218+
- ``'hue_mapping'`` and ``'marker_mapping'`` — dicts mapping hue/marker values to
219+
colors/markers explicitly. Does not replace passing a string for ``hue`` or
220+
``marker``.
221+
- ``'norm_kwargs'`` — dict forwarded to `~pyleoclim.utils.plotting.make_scalar_mappable`
222+
when ``hue`` is numeric. Supports ``'vcenter'`` (float, default ``0``) and
223+
``'clip'`` (bool, default ``False``) for `~matplotlib.colors.CenteredNorm`. Use
224+
this to shift the divergence center of the colormap (e.g.
225+
``norm_kwargs={'vcenter': 500}``).
226+
- ``'scalar_mappable'`` — a `~matplotlib.cm.ScalarMappable` that gives **full control**
227+
over both the colormap and the normalisation (including ``vmin`` / ``vmax``).
228+
Overrides ``cmap`` and ``norm_kwargs``. Build one with
229+
``matplotlib.cm.ScalarMappable(norm=matplotlib.colors.Normalize(vmin=…, vmax=…), cmap=…)``
230+
or with `pyleoclim.utils.plotting.make_scalar_mappable`.
209231
210232
211233
Returns
@@ -249,6 +271,16 @@ def map(self, marker='archiveType', hue='archiveType', size=None, cmap=None,
249271
eur_coord = {'central_latitude':45, 'central_longitude':20}
250272
Euro2k.map(projection='Orthographic',proj_default=eur_coord)
251273
274+
Symbol size is controlled via the ``'s'`` key of ``scatter_kwargs``. Note that ``s``
275+
is inherited from `matplotlib.pyplot.scatter` and represents the marker **area** in
276+
points², not the diameter or radius — so doubling ``s`` does *not* double the perceived
277+
size. A 4× increase in ``s`` is needed to double the apparent diameter:
278+
279+
.. jupyter-execute::
280+
281+
Euro2k.map(projection='Orthographic', proj_default=eur_coord,
282+
scatter_kwargs={'s': 400})
283+
252284
By default, the shape and colors of symbols denote proxy archives; however, one can use either graphical device to convey other information. For instance, if elevation is available, it may be displayed by size, like so:
253285
254286
.. jupyter-execute::
@@ -262,11 +294,41 @@ def map(self, marker='archiveType', hue='archiveType', size=None, cmap=None,
262294
Euro2k.map(projection='Orthographic', hue = 'observationType', proj_default=eur_coord)
263295
264296
All three sources of information may be combined, but the figure height will need to be enlarged manually to fit the legend:
265-
297+
266298
.. jupyter-execute::
267-
299+
268300
Euro2k.map(projection='Orthographic',hue='observationType',
269-
size='elevation', proj_default=eur_coord, figsize=[18, 8])
301+
size='elevation', proj_default=eur_coord, figsize=[18, 8])
302+
303+
When ``hue`` is a numeric variable, ``cmap`` selects the colormap. Here elevation
304+
is mapped to color using the ``'terrain'`` colormap:
305+
306+
.. jupyter-execute::
307+
308+
Euro2k.map(projection='Orthographic', hue='elevation', cmap='terrain',
309+
proj_default=eur_coord)
310+
311+
To control the color range (``vmin`` / ``vmax``), pass a
312+
`~matplotlib.cm.ScalarMappable` via the ``scalar_mappable`` keyword argument.
313+
For example, to cap the elevation color scale at 2 000 m:
314+
315+
.. jupyter-execute::
316+
317+
import matplotlib as mpl
318+
sm = mpl.cm.ScalarMappable(
319+
norm=mpl.colors.Normalize(vmin=0, vmax=2000),
320+
cmap=mpl.colormaps['terrain']
321+
)
322+
Euro2k.map(projection='Orthographic', hue='elevation',
323+
proj_default=eur_coord, scalar_mappable=sm)
324+
325+
For diverging colormaps, shift the neutral centre with ``norm_kwargs``
326+
(e.g. centred at 500 m):
327+
328+
.. jupyter-execute::
329+
330+
Euro2k.map(projection='Orthographic', hue='elevation', cmap='RdBu_r',
331+
proj_default=eur_coord, norm_kwargs={'vcenter': 500})
270332
271333
'''
272334

pyleoclim/core/resolutions.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def plot(self, figsize=[10, 4],
256256
return res
257257

258258
def histplot(self, figsize=[10, 4], title=None, savefig_settings=None,
259-
ax=None, ylabel='KDE', vertical=False, edgecolor='w', **plot_kwargs):
259+
ax=None, ylabel='KDE', vertical=False, edgecolor='w', plot_kwargs=None):
260260
''' Plot the distribution of the resolution values
261261
262262
Parameters
@@ -293,9 +293,12 @@ def histplot(self, figsize=[10, 4], title=None, savefig_settings=None,
293293
294294
The color of the edges of the bar
295295
296-
plot_kwargs : dict
296+
plot_kwargs : dict, optional
297297
298-
Plotting arguments for seaborn histplot: https://seaborn.pydata.org/generated/seaborn.histplot.html
298+
Keyword arguments passed to `seaborn.histplot <https://seaborn.pydata.org/generated/seaborn.histplot.html>`_.
299+
Useful keys include ``'bins'`` (int or sequence), ``'binwidth'`` (float),
300+
``'stat'`` (``'count'``, ``'frequency'``, ``'probability'``, ``'density'``),
301+
and ``'color'``. The default is None.
299302
300303
See also
301304
--------
@@ -311,14 +314,21 @@ def histplot(self, figsize=[10, 4], title=None, savefig_settings=None,
311314
res = ts.resolution()
312315
res.histplot()
313316
317+
To set the number of bins explicitly, pass ``bins`` via ``plot_kwargs``:
318+
319+
.. jupyter-execute::
320+
321+
res.histplot(plot_kwargs={'bins': 20})
322+
314323
'''
315324
savefig_settings = {} if savefig_settings is None else savefig_settings.copy()
325+
plot_kwargs = {} if plot_kwargs is None else plot_kwargs.copy()
316326
if ax is None:
317327
fig, ax = plt.subplots(figsize=figsize)
318328

319329
#make the data into a dataframe so we can flip the figure
320330
_,value_label = self.make_labels()
321-
331+
322332
if vertical == True:
323333
data=pd.DataFrame({'value':self.resolution})
324334
ax = sns.histplot(data=data, y="value", ax=ax, kde=True, edgecolor=edgecolor, **plot_kwargs)

pyleoclim/tests/test_core_Resolution.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ def test_histplot_t0(self,series,request):
4242
fig, ax = resolution.histplot()
4343
pyleo.closefig(fig)
4444

45+
@pytest.mark.parametrize('series', ['unevenly_spaced_series','unevenly_spaced_series_nans'])
46+
def test_histplot_plot_kwargs(self,series,request):
47+
"""plot_kwargs dict must be unpacked and forwarded to seaborn.histplot"""
48+
series = request.getfixturevalue(series)
49+
resolution = series.resolution()
50+
fig, ax = resolution.histplot(plot_kwargs={'bins': 10})
51+
pyleo.closefig(fig)
52+
4553
class TestUIDashboard:
4654
"""Tests for Resolution.dashboard()"""
4755
@pytest.mark.parametrize('series', ['unevenly_spaced_series','unevenly_spaced_series_nans'])

0 commit comments

Comments
 (0)