Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mapping legend colorbar #525

Merged
merged 7 commits into from
May 3, 2024
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
33 changes: 32 additions & 1 deletion pyleoclim/core/multiplegeoseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def __init__(self, series_list, time_unit=None, label=None):

def map(self, marker='archiveType', hue='archiveType', size=None, cmap=None,
edgecolor='k', projection='auto',
proj_default=True, crit_dist=5000, colorbar=True,
proj_default=True, crit_dist=5000, colorbar=True,color_scale_type=None,
background=True, borders=False, coastline=True,rivers=False, lakes=False, land=True,ocean=True,
figsize=None, fig=None, scatter_kwargs=None, gridspec_kwargs=None, legend=True, gridspec_slot=None,
lgd_kwargs=None, savefig_settings=None, **kwargs):
Expand Down Expand Up @@ -180,6 +180,10 @@ def map(self, marker='archiveType', hue='archiveType', size=None, cmap=None,
Whether to draw a colorbar on the figure if the data associated with hue are numeric.
Default is True.

color_scale_type : str, optional
Setting to "discrete" will force a discrete color scale with a default bin number of max(11, n) where n=number of unique values$^{\frac{1}{2}}$
Default is None

lgd_kwargs : dict, optional
Dictionary of arguments for `matplotlib.pyplot.legend <https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.pyplot.legend.html>`_.

Expand Down Expand Up @@ -406,6 +410,33 @@ def pca(self, weights=None,missing='fill-em',tol_em=5e-03, max_em_iter=100,**pca
'gridspec_kwargs': {'width_ratios': [.5, 1,14, 4], 'wspace':-.065},
'lgd_kwargs':{'bbox_to_anchor':[-.015,1]}})


One can also configure how hue information gets displayed:

.. jupyter-execute::

# Dashboard with hue as a legend category
res.modeplot(index=1, size='elevation', map_kwargs= dict(colorbar=False))

# Dashboard with discrete colorbar
res.modeplot(index=1, size='elevation', map_kwargs= dict(color_scale_type='discrete'))

# Dashboard with custom scalar mappable
sm = pyleo.utils.mapping.make_scalar_mappable(cmap='vlag', hue_vect=res.eigvecs[:, 1], n=21,norm_kwargs={'vcenter': -.5})
res.modeplot(index=1, size='elevation', map_kwargs= dict(scalar_mappable=sm))


and customize the marker variable:

.. jupyter-execute::

# Dashboard with marker set to archiveType
res.modeplot(index=1, marker='archiveType', size='elevation', map_kwargs= dict(colorbar=True))

# Dashboard with marker set to archiveType
res.modeplot(index=1, marker='observationType', size='elevation', map_kwargs= dict(colorbar=True))


'''
# apply PCA fom parent class
pca_res = super().pca(weights=weights,missing=missing,tol_em=tol_em,
Expand Down
33 changes: 26 additions & 7 deletions pyleoclim/core/multivardecomp.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,9 @@ def screeplot(self, figsize=[6, 4], uq='N82', title=None, ax=None, savefig_setti

def modeplot(self, index=0, figsize=[8, 8], fig=None, savefig_settings=None,gs=None,
title=None, title_kwargs=None, spec_method='mtm', cmap=None,
hue='EOF', marker='archiveType', size=None, scatter_kwargs=None,
hue='EOF', marker=None, size=None, scatter_kwargs=None,
flip = False, map_kwargs=None, gridspec_kwargs=None):

''' Dashboard visualizing the properties of a given mode, including:
1. The temporal coefficient (PC or similar)
2. its spectrum
Expand Down Expand Up @@ -248,8 +249,9 @@ def modeplot(self, index=0, figsize=[8, 8], fig=None, savefig_settings=None,gs=N
- gridspec_kwargs: dict; Optional values for adjusting the arrangement of the colorbar, map and legend in the map subplot
- legend: bool; Whether to draw a legend on the figure. Default is True
- colorbar: bool; Whether to draw a colorbar on the figure if the data associated with hue are numeric. Default is True
The default is None.

- color_scale_type : str; Setting to "discrete" will force a discrete color scale with a default bin number of max(11, n) where n=number of unique values$^{\frac{1}{2}}$. Default is None
- scalar_mappable: matplotlib.cm.ScalarMappable; can be used to pass a matplotlib scalar mappable. See pyleoclim.utils.plotting.make_scalar_mappable for documentation on using the Pyleoclim utility, or the `Matplotlib tutorial on customizing colorbars <https://matplotlib.org/stable/users/explain/colors/colorbar_only.html>`_.

scatter_kwargs : dict, optional
Optional arguments configuring how data are plotted on a map. See description of scatter_kwargs in pyleoclim.utils.mapping.scatter_map

Expand All @@ -263,7 +265,8 @@ def modeplot(self, index=0, figsize=[8, 8], fig=None, savefig_settings=None,gs=N

marker : string, optional
(only applicable if using scatter map) Grouping variable that will produce points with different markers. Can have a numeric dtype but will always be treated as categorical.
The default is 'archiveType'.
The default is None, which will produce circle markers. Alternatively, pass the name of a categorical variable, e.g. 'archiveType'. If 'archiveType' is specified, will attempt to use pyleoclim archiveType markers mapping, defaulting to '?' where values are unavailable.


Returns
-------
Expand All @@ -274,6 +277,7 @@ def modeplot(self, index=0, figsize=[8, 8], fig=None, savefig_settings=None,gs=N
ax : dict
dictionary of matplotlib ax


See also
--------

Expand All @@ -284,7 +288,10 @@ def modeplot(self, index=0, figsize=[8, 8], fig=None, savefig_settings=None,gs=N
pyleoclim.utils.tsutils.eff_sample_size : Effective sample size

pyleoclim.utils.mapping.scatter_map : mapping


pyleoclim.utils.plotting.make_scalar_mappable : Custom scalar mappable


'''
from ..core.multiplegeoseries import MultipleGeoSeries

Expand Down Expand Up @@ -351,12 +358,24 @@ def modeplot(self, index=0, figsize=[8, 8], fig=None, savefig_settings=None,gs=N
map_gridspec_kwargs = map_kwargs.pop('gridspec_kwargs', {})
lgd_kwargs = map_kwargs.pop('lgd_kwargs', {})

if scatter_kwargs is None:
scatter_kwargs = {}
else:
scatter_kwargs = scatter_kwargs.copy()

if 'edgecolor' in map_kwargs.keys():
scatter_kwargs.update({'edgecolor': map_kwargs['edgecolor']})

legend = map_kwargs.pop('legend', True)
colorbar = map_kwargs.pop('colorbar', True)
color_scale_type = map_kwargs.pop('color_scale_type', None)

if marker is None:
marker = scatter_kwargs.pop('marker', None)
if hue is None:
hue = scatter_kwargs.pop('hue', None)
if size is None:
size = scatter_kwargs.pop('size', None)

if isinstance(self.orig, MultipleGeoSeries):
# This makes a bare bones dataframe from a MultipleGeoSeries object
Expand All @@ -373,9 +392,9 @@ def modeplot(self, index=0, figsize=[8, 8], fig=None, savefig_settings=None,gs=N
rivers=rivers, lakes=lakes,
ocean=ocean, land=land, extent=extent,
figsize=None, scatter_kwargs=scatter_kwargs, lgd_kwargs=lgd_kwargs,
gridspec_kwargs=map_gridspec_kwargs, colorbar=colorbar,
gridspec_kwargs=map_gridspec_kwargs, colorbar=colorbar, color_scale_type=color_scale_type,
legend=legend, cmap=cmap,
fig=fig, gs_slot=gs[-1, :]) #label rf'$EOF_{index + 1}$'
fig=fig, gs_slot=gs[-1, :], **map_kwargs) #label rf'$EOF_{index + 1}$'

else: # it must be a plain old MultipleSeries. No map for you! Just a spaghetti plot with the standardizes series
ax['map'] = fig.add_subplot(gs[1:, :])
Expand Down
Loading
Loading