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
11 changes: 7 additions & 4 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ v1.2.2
======
Added
-----
* You can now save and load presets for the formatoptions of a project which
applies the formatoptions that you stored in a file to a specific plot method,
see `#24 <https://github.com/psyplot/psyplot/pull/24>`__
* the ``rcParams`` do now have a ``catch`` method that allows a temporary change
of formatoptions.

Usage::

rcParams['some_key'] = 0
Expand All @@ -21,11 +24,11 @@ Added
`check_data` method of the various plotmethods now also accept a `decoder`
parameter, see `#22 <https://github.com/psyplot/psyplot/pull/22>`__
* ``psyplot.data.open_dataset`` now decodes grid_mappings attributes,
see `#17 <https://github.com/psyplot/psyplot/pull/17>`__
see `#17 <https://github.com/psyplot/psyplot/pull/17>`__
* psyplot projects now support the with syntax, e.g. something like::

with psy.plot.mapplot('file.nc') as sp:
sp.export('output.png')
with psy.plot.mapplot('file.nc') as sp:
sp.export('output.png')

sp will be closed automatically (see `#18 <https://github.com/psyplot/psyplot/pull/18>`__)
* the update to variables with other dimensions works now as well
Expand Down
10 changes: 5 additions & 5 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,14 @@

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
'pandas': ('http://pandas.pydata.org/pandas-docs/stable/', None),
'numpy': ('https://docs.scipy.org/doc/numpy/', None),
'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', None),
'numpy': ('https://numpy.org/doc/stable/', None),
'matplotlib': ('https://matplotlib.org/', None),
'seaborn': ('http://seaborn.pydata.org/', None),
'sphinx': ('http://www.sphinx-doc.org/en/stable/', None),
'sphinx': ('https://www.sphinx-doc.org/en/master/', None),
'xarray': ('http://xarray.pydata.org/en/stable/', None),
'cartopy': ('https://scitools.org.uk/cartopy/docs/latest/', None),
'mpl_toolkits': ('http://matplotlib.org/basemap/', None),
'mpl_toolkits': ('https://matplotlib.org/basemap/', None),
'sphinx_nbexamples': ('https://sphinx-nbexamples.readthedocs.io/en/latest/',
None),
'psy_maps': (
Expand All @@ -254,7 +254,7 @@
'https://psyplot.readthedocs.io/projects/psyplot-gui/en/latest/', None),
}
if six.PY3:
intersphinx_mapping['python'] = ('https://docs.python.org/3.6/', None)
intersphinx_mapping['python'] = ('https://docs.python.org/3.8/', None)
else:
intersphinx_mapping['python'] = ('https://docs.python.org/2.7/', None)

Expand Down
48 changes: 48 additions & 0 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,54 @@ To restore your project, simply use the
:ref:`own-scripts`)


.. _presets:

Using presets
-------------
You can save and load presets to reuse the formatoption settings. For instance,
let's say temperature should always use a ``'Reds'`` cmap, the colorbar label
should show the long name and the title should be ``'time'``. This is of course
possible via

.. ipython::

@savefig docs_presets_1.png width=4in
In [34]: sp = psy.plot.mapplot(
....: 'demo.nc', name='t2m', cmap="Reds", clabel="%(long_name)s",
....: title='%(time)s')

But instead of writing this all the time, you can also save it as a preset

.. ipython::

In [35]: sp.save_preset("t2m-preset")

@suppress
In [35]: psy.close('all')

and reload this preset either via the `preset` keyword

.. ipython::

@savefig docs_presets_2.png width=4in
In [36]: sp = psy.plot.mapplot('demo.nc', name='t2m', preset='t2m-preset')

or the :meth:`~psyplot.project.Project.load_preset` method

.. ipython::

In [37]: sp.load_preset('t2m-preset')

You can list the available presets from the command line

.. ipython::

In [38]: !psyplot --list-presets

@suppress
In [37]: !rm {sp._resolve_preset_path('t2m-preset')}
....: psy.close('all')

.. _own-scripts:

Adding your own script: The :attr:`~psyplot.plotter.Plotter.post` formatoption
Expand Down
39 changes: 37 additions & 2 deletions psyplot/__main__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
import os
import os.path as osp
import sys
import argparse
import pickle
import six
import glob
from itertools import chain
from collections import defaultdict
import yaml
Expand Down Expand Up @@ -53,7 +55,7 @@ def make_plot(fnames=[], name=[], dims=None, plot_method=None,
tight=False, rc_file=None, encoding=None, enable_post=False,
seaborn_style=None, output_project=None,
concat_dim=get_default_value(xr.open_mfdataset, 'concat_dim'),
chname={}):
chname={}, preset=None):
"""
Eventually start the QApplication or only make a plot

Expand Down Expand Up @@ -107,6 +109,11 @@ def make_plot(fnames=[], name=[], dims=None, plot_method=None,
chname: dict
A mapping from variable names in the project to variable names in the
datasets that should be used instead
preset: str
The filename or identifier of a preset. If the given `preset` is
the path to an existing yaml file, it will be loaded. Otherwise we
look up the `preset` in the psyplot configuration directory (see
:func:`~psyplot.config.rcsetup.get_configdir`).
"""
if project is not None and (name != [] or dims is not None):
warn('The `name` and `dims` parameter are ignored if the `project`'
Expand Down Expand Up @@ -141,6 +148,8 @@ def make_plot(fnames=[], name=[], dims=None, plot_method=None,
project, alternative_paths=alternative_paths,
engine=engine, encoding=encoding, enable_post=enable_post,
chname=chname)
if preset:
p.load_preset(preset)
if formatoptions is not None:
p.update(fmt=formatoptions)
p.export(output, tight=tight)
Expand All @@ -150,7 +159,7 @@ def make_plot(fnames=[], name=[], dims=None, plot_method=None,
raise ValueError("Unknown plot method %s!" % plot_method)
kwargs = {'name': name} if name else {}
p = pm(
fnames, dims=dims or {}, engine=engine,
fnames, dims=dims or {}, engine=engine, preset=preset,
fmt=formatoptions or {}, mf_mode=True, concat_dim=concat_dim,
**kwargs)
p.export(output, tight=tight)
Expand Down Expand Up @@ -237,6 +246,10 @@ def get_parser(create=True):
action=ListDsNamesAction, if_existent=False, group=info_grp,
help="""List the used dataset names in the given `project`.""")

parser.update_arg(
'list_presets', short='lps', long='list-presets',
action=ListPresetsAction, if_existent=False, group=info_grp)

parser.setup_args(make_plot)

output_grp = parser.add_argument_group(
Expand Down Expand Up @@ -334,6 +347,28 @@ def __call__(self, parser, namespace, values, option_string=None):
sys.exit(0)


class ListPresetsAction(argparse.Action):

def __init__(self, option_strings, dest=argparse.SUPPRESS, nargs=None,
default=argparse.SUPPRESS, **kwargs):
if nargs is not None:
raise ValueError("nargs not allowed")
kwargs['help'] = ("Print available presets and exit")
if not _on_rtd:
kwargs['default'] = default
super().__init__(option_strings, nargs=0, dest=dest, **kwargs)

def __call__(self, parser, namespace, values, option_string=None):
from psyplot.config.rcsetup import get_configdir
presets_dir = osp.join(get_configdir(), 'presets')
if not osp.exists(presets_dir):
sys.exit(0)
else:
presets = {osp.splitext(osp.basename(fname))[0]: fname
for fname in glob.glob(osp.join(presets_dir, '*.yml'))}
print('\n'.join(map(': '.join, presets.items())))
sys.exit(0)

class ListPluginsAction(argparse.Action):

def __init__(self, option_strings, dest=argparse.SUPPRESS, nargs=None,
Expand Down
4 changes: 2 additions & 2 deletions psyplot/plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1781,7 +1781,7 @@ def _get_formatoptions(cls, include_bases=True):
Iterator over formatoptions

This class method returns an iterator that contains all the
formatoptions descriptors that are in this class and that are defined
formatoption keys that are in this class and that are defined
in the base classes

Notes
Expand All @@ -1790,7 +1790,7 @@ def _get_formatoptions(cls, include_bases=True):
initialization, since all formatoptions are in the plotter itself.
Just type::

>>> list(plotter)
>>> list(plotter)

to get the formatoptions.

Expand Down
Loading