Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
78 changes: 70 additions & 8 deletions pyleoclim/core/multiplegeoseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,18 @@ def map(self, marker='archiveType', hue='archiveType', size=None, cmap=None,
DESCRIPTION.
The default is 'global'.

cmap : string or list, optional
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>`_.
The default is None.
cmap : str, list, or None, optional
Colormap to use when `hue` is a **numeric** variable. Has no effect when `hue` is
categorical (e.g. ``'archiveType'``), in which case colors come from pyleoclim's
default archive-type palette or the ``hue_mapping`` kwarg. Accepts:

- a named Matplotlib colormap string (e.g. ``'viridis'``, ``'RdBu_r'``, ``'terrain'``)
- a list of colors that will be interpolated into a continuous colormap
(e.g. ``['blue', 'white', 'red']``)

When ``None`` (default), pyleoclim selects ``'vlag'`` for data that span zero
and ``'viridis'`` otherwise.
See `choosing a matplotlib colormap <https://matplotlib.org/stable/gallery/color/colormap_reference.html>`_.

fig : matplotlib.pyplot.figure, optional
See matplotlib.pyplot.figure <https://matplotlib.org/3.5.0/api/_as_gen/matplotlib.pyplot.figure.html#matplotlib-pyplot-figure>_.
Expand All @@ -204,8 +213,21 @@ def map(self, marker='archiveType', hue='archiveType', size=None, cmap=None,
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.

kwargs: dict, optional
- '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').
- '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.
- ``'missing_val_hue'``, ``'missing_val_marker'``, ``'missing_val_label'`` — change
how missing values are represented (defaults: ``'k'``, ``'?'``, ``'missing'``).
- ``'hue_mapping'`` and ``'marker_mapping'`` — dicts mapping hue/marker values to
colors/markers explicitly. Does not replace passing a string for ``hue`` or
``marker``.
- ``'norm_kwargs'`` — dict forwarded to `~pyleoclim.utils.plotting.make_scalar_mappable`
when ``hue`` is numeric. Supports ``'vcenter'`` (float, default ``0``) and
``'clip'`` (bool, default ``False``) for `~matplotlib.colors.CenteredNorm`. Use
this to shift the divergence center of the colormap (e.g.
``norm_kwargs={'vcenter': 500}``).
- ``'scalar_mappable'`` — a `~matplotlib.cm.ScalarMappable` that gives **full control**
over both the colormap and the normalisation (including ``vmin`` / ``vmax``).
Overrides ``cmap`` and ``norm_kwargs``. Build one with
``matplotlib.cm.ScalarMappable(norm=matplotlib.colors.Normalize(vmin=…, vmax=…), cmap=…)``
or with `pyleoclim.utils.plotting.make_scalar_mappable`.


Returns
Expand Down Expand Up @@ -249,6 +271,16 @@ def map(self, marker='archiveType', hue='archiveType', size=None, cmap=None,
eur_coord = {'central_latitude':45, 'central_longitude':20}
Euro2k.map(projection='Orthographic',proj_default=eur_coord)

Symbol size is controlled via the ``'s'`` key of ``scatter_kwargs``. Note that ``s``
is inherited from `matplotlib.pyplot.scatter` and represents the marker **area** in
points², not the diameter or radius — so doubling ``s`` does *not* double the perceived
size. A 4× increase in ``s`` is needed to double the apparent diameter:

.. jupyter-execute::

Euro2k.map(projection='Orthographic', proj_default=eur_coord,
scatter_kwargs={'s': 400})

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:

.. jupyter-execute::
Expand All @@ -262,11 +294,41 @@ def map(self, marker='archiveType', hue='archiveType', size=None, cmap=None,
Euro2k.map(projection='Orthographic', hue = 'observationType', proj_default=eur_coord)

All three sources of information may be combined, but the figure height will need to be enlarged manually to fit the legend:

.. jupyter-execute::

Euro2k.map(projection='Orthographic',hue='observationType',
size='elevation', proj_default=eur_coord, figsize=[18, 8])
size='elevation', proj_default=eur_coord, figsize=[18, 8])

When ``hue`` is a numeric variable, ``cmap`` selects the colormap. Here elevation
is mapped to color using the ``'terrain'`` colormap:

.. jupyter-execute::

Euro2k.map(projection='Orthographic', hue='elevation', cmap='terrain',
proj_default=eur_coord)

To control the color range (``vmin`` / ``vmax``), pass a
`~matplotlib.cm.ScalarMappable` via the ``scalar_mappable`` keyword argument.
For example, to cap the elevation color scale at 2 000 m:

.. jupyter-execute::

import matplotlib as mpl
sm = mpl.cm.ScalarMappable(
norm=mpl.colors.Normalize(vmin=0, vmax=2000),
cmap=mpl.colormaps['terrain']
)
Euro2k.map(projection='Orthographic', hue='elevation',
proj_default=eur_coord, scalar_mappable=sm)

For diverging colormaps, shift the neutral centre with ``norm_kwargs``
(e.g. centred at 500 m):

.. jupyter-execute::

Euro2k.map(projection='Orthographic', hue='elevation', cmap='RdBu_r',
proj_default=eur_coord, norm_kwargs={'vcenter': 500})

'''

Expand Down
18 changes: 14 additions & 4 deletions pyleoclim/core/resolutions.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def plot(self, figsize=[10, 4],
return res

def histplot(self, figsize=[10, 4], title=None, savefig_settings=None,
ax=None, ylabel='KDE', vertical=False, edgecolor='w', **plot_kwargs):
ax=None, ylabel='KDE', vertical=False, edgecolor='w', plot_kwargs=None):
''' Plot the distribution of the resolution values

Parameters
Expand Down Expand Up @@ -293,9 +293,12 @@ def histplot(self, figsize=[10, 4], title=None, savefig_settings=None,

The color of the edges of the bar

plot_kwargs : dict
plot_kwargs : dict, optional

Plotting arguments for seaborn histplot: https://seaborn.pydata.org/generated/seaborn.histplot.html
Keyword arguments passed to `seaborn.histplot <https://seaborn.pydata.org/generated/seaborn.histplot.html>`_.
Useful keys include ``'bins'`` (int or sequence), ``'binwidth'`` (float),
``'stat'`` (``'count'``, ``'frequency'``, ``'probability'``, ``'density'``),
and ``'color'``. The default is None.

See also
--------
Expand All @@ -311,14 +314,21 @@ def histplot(self, figsize=[10, 4], title=None, savefig_settings=None,
res = ts.resolution()
res.histplot()

To set the number of bins explicitly, pass ``bins`` via ``plot_kwargs``:

.. jupyter-execute::

res.histplot(plot_kwargs={'bins': 20})

'''
savefig_settings = {} if savefig_settings is None else savefig_settings.copy()
plot_kwargs = {} if plot_kwargs is None else plot_kwargs.copy()
if ax is None:
fig, ax = plt.subplots(figsize=figsize)

#make the data into a dataframe so we can flip the figure
_,value_label = self.make_labels()

if vertical == True:
data=pd.DataFrame({'value':self.resolution})
ax = sns.histplot(data=data, y="value", ax=ax, kde=True, edgecolor=edgecolor, **plot_kwargs)
Expand Down
8 changes: 8 additions & 0 deletions pyleoclim/tests/test_core_Resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ def test_histplot_t0(self,series,request):
fig, ax = resolution.histplot()
pyleo.closefig(fig)

@pytest.mark.parametrize('series', ['unevenly_spaced_series','unevenly_spaced_series_nans'])
def test_histplot_plot_kwargs(self,series,request):
"""plot_kwargs dict must be unpacked and forwarded to seaborn.histplot"""
series = request.getfixturevalue(series)
resolution = series.resolution()
fig, ax = resolution.histplot(plot_kwargs={'bins': 10})
pyleo.closefig(fig)

class TestUIDashboard:
"""Tests for Resolution.dashboard()"""
@pytest.mark.parametrize('series', ['unevenly_spaced_series','unevenly_spaced_series_nans'])
Expand Down
Loading