Source code for mplpub.mplpub

import os
from ast import literal_eval
from collections import OrderedDict

import matplotlib
from matplotlib import rcParams


def read_template(template_file):
    """ Returns a matploblib rc configurations dict created from
    template_file which should consist lines having the format::

        key1 = value1
        key2 = value2
        ...

    where whitespaces are ignored and everything following
    a ``#`` is a comment. The values can be numbers, strings,
    lists or dictionaries.
    """
    template = {}
    with open(template_file, 'r') as f:
        lines = f.readlines()
        for line in lines:
            line = line.strip()
            if line.startswith('#'):
                continue
            elif line == '':
                continue
            else:
                line_split = line.split('=')
                key = line_split[0].strip()
                value = line_split[1]
                if '#' in value:
                    value = value[: value.index('#')]
                value = value.strip()
                value = literal_eval(value)
                template[key] = value
    return template


# ---------------------------------------------------
# Color sets
# ---------------------------------------------------
# Standard tableau 20 set
tableau = OrderedDict(
    [
        ('blue', '#1F77B4'),
        ('orange', '#FF7F0E'),
        ('green', '#2CA02C'),
        ('red', '#D62728'),
        ('purple', '#9467BD'),
        ('brown', '#8C564B'),
        ('pink', '#E377C2'),
        ('grey', '#7F7F7F'),
        ('yellow', '#BCBD22'),
        ('turquoise', '#17BECF'),
        ('lightblue', '#AEC7E8'),
        ('lightorange', '#FFBB78'),
        ('lightgreen', '#98DF8A'),
        ('lightred', '#FF9896'),
        ('lightpurple', '#C5B0D5'),
        ('lightbrown', '#C49C94'),
        ('lightpink', '#F7B6D2'),
        ('lightgrey', '#C7C7C7'),
        ('lightyellow', '#DBDB8D'),
        ('lightturquoise', '#9EDAE5'),
    ]
)


# ---------------------------------------------------
[docs] def setup( tex: bool = True, template: str = None, width: float = None, height: float = None, font_family: str = 'sans-serif', color_cycle=tableau.values(), extra_settings: dict = None, ): """Set up publication quality plotting by changing the ``rcparams`` dictionary and various other options. Parameters ---------- tex use external (system) TeX-engine template name of template width width of the figure in inches height height of the figure in inches font_family font family (e.g., ``'sans-serif'``) extra_settings extra parameters that are used to update the ``rcParams`` dictionary """ # ------------------------------------ # load settings from templates, start with base dir_module = os.path.dirname(os.path.realpath(__file__)) dir_templates = os.path.join(dir_module, 'templates') template_base = read_template(os.path.join(dir_templates, 'base')) if int(matplotlib.__version__[0]) >= 2: # settings for version >= 2.0 template_base.update( read_template(os.path.join(dir_templates, 'base_2.0_update')) ) rcParams.update(template_base) # overload with journal specific template if template: new_template = read_template(os.path.join(dir_templates, template)) rcParams.update(new_template) # ------------------------------------ # set font properties rcParams['font.family'] = font_family if tex: rcParams['text.usetex'] = True preamble_list = [r'\usepackage{amsmath}'] if font_family == 'sans-serif': preamble_list += [ r'\usepackage{helvet}', # use helvetica sans font r'\usepackage{sansmath}', # also use for math r'\sansmath', # Dirty hack to get uppercase greek letters: r"""\newcommand{ \UG}[1]{\text{\unsansmath\ensuremath{#1}\sansmath}}""" r"""\newcommand{ \angs}{\text{\normalfont\AA}}""", ] # in older versions of matplotlib the preamble must be a list of strings def versiontuple(v): return tuple(map(int, (v.split('.')))) if versiontuple(matplotlib.__version__) < versiontuple('3.1'): rcParams['text.latex.preamble'] = preamble_list else: rcParams['text.latex.preamble'] = '\n'.join(preamble_list) else: # choose fonts if we are not using tex rcParams['font.sans-serif'] = 'Liberation Sans' rcParams['font.serif'] = 'Palatino' # ------------------------------------ # other properties # set custom size if width or height: if not width: size = (rcParams['figure.figsize'][0], height) elif not height: size = (width, rcParams['figure.figsize'][1]) else: size = (width, height) rcParams['figure.figsize'] = size # set color cycle to tableau, note that the cycler is not available # in older versions of matplotlib so we have to try it try: from matplotlib import cycler rcParams['axes.prop_cycle'] = cycler(color=color_cycle) except Exception: print('Note: color cycler is not supported by this version of matplotlib.') # update dict with extra parameters if extra_settings: rcParams.update(extra_settings)