acgc.figstyle API documentation

# acgc.figstyle

Style settings for matplotlib, for publication-ready figures

Activate the style by importing this module:

`from acgc import figstyle`

Figures generated by Matplotlib will then use the new style. Additional colormaps and fonts will be loaded. The style includes grid lines (horizontal and vertical) by default. Turn these off and on with `grid_off` and `grid_on`:

`figstyle.grid_off()`

`figstyle.grid_on()`

The additional colormaps are from Fabio Crameri's Scientific color maps (https://github.com/callumrollo/cmcrameri).

View Source

      1#!/usr/bin/env python3
      2'''Style settings for matplotlib, for publication-ready figures
      3
      4Activate the style by importing this module:
      5
      6`from acgc import figstyle`
      7
      8Figures generated by Matplotlib will then use the new style.
      9Additional colormaps and fonts will be loaded.
     10The style includes grid lines (horizontal and vertical) by default.
     11Turn these off and on with `grid_off` and `grid_on`:
     12
     13`figstyle.grid_off()`
     14
     15`figstyle.grid_on()`
     16
     17The additional colormaps are from Fabio Crameri's Scientific color maps
     18(https://github.com/callumrollo/cmcrameri).
     19'''
     20
     21import os
     22import warnings
     23import matplotlib as mpl
     24import matplotlib.style as mstyle
     25import matplotlib.font_manager as mfonts
     26if 'inline' in mpl.get_backend():
     27    import matplotlib_inline
     28
     29# Path to this module
     30_PATH = os.path.dirname(__file__)
     31
     32def activate_style(grid=True,gridaxis='both',mathfont='regular'):
     33    '''Activate style sheet
     34
     35    Parameters
     36    ----------
     37    grid : bool, default=True
     38        turn grid lines on (True) or off (False)
     39    gridaxis : str, default='both'
     40        specifies which axes should have grid lines
     41    mathfont : str, default='regular'
     42        sets font used in mathtext, 'regular' uses same font as regular text.
     43        see `set_mathfont` for all options
     44    '''
     45    # Load settings from style file
     46    mstyle.use(os.path.join(_PATH,'acgc.mplstyle'))
     47
     48    # Set mathtext font
     49    set_mathfont(mathfont)
     50
     51    # Turn grid on or off
     52    if grid:
     53        grid_on(axis=gridaxis)
     54
     55    # Use high quality for inline images; Only use this if the inline backend is active
     56    # 'png' is default, 'svg' is also good
     57    if 'inline' in mpl.get_backend():
     58        matplotlib_inline.backend_inline.set_matplotlib_formats('retina')
     59
     60def deactivate_style():
     61    '''Restore rcParams prior to importing figstyle'''
     62    mpl.rcParams = _rcParams_old
     63
     64def set_mathfont(fontname=None):
     65    '''Set the font used for typsetting math in Matplotlib
     66
     67    Parameters
     68    ----------
     69    fontname : str, default=None
     70        Should be one of
     71        - None         : Restore mathtext font to settings before importing figstyle
     72        - 'regular'    : Use same font as regular text in math expressions (default).
     73                       Same as using \\mathregular or \\mathdefault in math expressions.
     74                       Best for mixing regular and math text for superscripts and subscripts.
     75                       May lack or have poor positioning of some math symbols (e.g. integrals).
     76                       This will overwrite mathtext.bf, mathtext.bfit, mathtext.it,
     77                       mathtext.rm in rcParams.
     78        - 'custom'     : Uses custom settings from rcParams (mathtext.bf, .bfit, .it, .rm)
     79        - 'cm'         : Computer Modern (i.e. LaTeX default)
     80        - 'stix'       : STIX serif
     81        - 'stixsans'   : STIX sans-serif; best for sans-serif math
     82        - 'dejavuserif': DejaVu Serif (not recommended)
     83        - 'dejavusans' : DejaVu Sans (not recommended)
     84    '''
     85
     86    # Check that input has an allowed value
     87    allowedvalues = ['None','regular','custom','cm','stix','stixsans','dejavusans','dejavuserif']
     88    if (fontname not in allowedvalues) and (fontname is not None):
     89        raise ValueError('Font name should be one of the allowed values: '+','.join(allowedvalues))
     90
     91    if fontname is None:
     92        # Restore old mathtext settings
     93        mpl.rcParams.update( {key:_rcParams_old[key] for key in
     94                              ['mathtext.fontset','mathtext.bf','mathtext.bfit',
     95                               'mathtext.it','mathtext.rm']})
     96
     97    elif fontname == 'regular':
     98        # Set the math font to the font used for regular text
     99
    100        # Name of the text font
    101        textfont = mpl.rcParams[f'font.{mpl.rcParams["font.family"][0]:s}'][0]
    102        # Use the same font for math
    103        mpl.rcParams.update({'mathtext.fontset': 'custom',
    104                            'mathtext.bf'   : f'{textfont}:bold',
    105                            'mathtext.bfit' : f'{textfont}:italic:bold',
    106                            'mathtext.it'   : f'{textfont}:italic',
    107                            'mathtext.rm'   : f'{textfont}'})
    108    else:
    109        # Set the math font to the value provided
    110        mpl.rcParams['mathtext.fontset'] = fontname
    111
    112def grid_off():
    113    '''Turn off grid lines'''
    114    mpl.rcParams['axes.grid'] = False
    115
    116def grid_on(axis='both'):
    117    '''Turn on grid lines
    118
    119    Parameters
    120    ----------
    121    axis : {'both', 'x', 'y'}
    122        specifies which axes should have grid lines
    123    '''
    124    mpl.rcParams['axes.grid'] = True
    125    mpl.rcParams['axes.grid.axis'] = axis
    126
    127def load_fonts():
    128    '''Load fonts contained in the acgc/fonts subdirectory'''
    129
    130    # User fonts
    131    fonts_pylib = mfonts.findSystemFonts(os.path.join(_PATH,'fonts'))
    132
    133    # Cached fonts
    134    fonts_cached = mfonts.fontManager.ttflist
    135    fonts_cached_paths = [ font.fname for font in fonts_cached ]
    136
    137    # Add fonts that aren't already installed
    138    rebuild = False
    139    for font in fonts_pylib:
    140        if font not in fonts_cached_paths:
    141            if rebuild is False:
    142                # Issue warning, first time only
    143                warnings.warn('Rebuilding font cache. This can take time.')
    144            rebuild = True
    145            mfonts.fontManager.addfont(font)
    146
    147    # Save font cache
    148    if rebuild:
    149        cache = os.path.join(
    150                        mpl.get_cachedir(),
    151                        f'fontlist-v{mfonts.FontManager.__version__}.json'
    152                    )
    153        mfonts.json_dump(mfonts.fontManager, cache)
    154
    155def load_crameri_colormaps(noprefix=True):
    156    '''Load Fabio Crameri's Scientific color maps
    157
    158    https://www.fabiocrameri.ch/colourmaps/
    159    https://github.com/callumrollo/cmcrameri
    160
    161    Parameters
    162    ----------
    163    noprefix : bool, default=True
    164        If True, remove the 'cmc.' prefix from the colormap names
    165    '''
    166
    167    # Import the colormaps; The registered names will be prefixed with 'cmc.'
    168    try:
    169        from cmcrameri import cm
    170    except ImportError:
    171        warnings.warn('Scientific colormaps not found. Install with `conda install cmcrameri` if desired.', ImportWarning)
    172        return
    173
    174    # Remove the 'cmc.' prefix from the colormap names
    175    for name in list(mpl.colormaps):
    176        if name[:4]=='cmc.':
    177
    178            # Register the colormap without the prefix
    179            try:
    180                mpl.colormaps.register( mpl.colormaps[name], name=name[4:] )
    181            except ValueError:
    182                pass
    183
    184            # Unregister the original colormap
    185            if noprefix:
    186                mpl.colormaps.unregister(name)
    187
    188###
    189_rcParams_old = mpl.rcParams.copy()
    190load_fonts()
    191load_crameri_colormaps()
    192activate_style()

def activate_style(grid=True, gridaxis='both', mathfont='regular'): View Source

    33def activate_style(grid=True,gridaxis='both',mathfont='regular'):
    34    '''Activate style sheet
    35
    36    Parameters
    37    ----------
    38    grid : bool, default=True
    39        turn grid lines on (True) or off (False)
    40    gridaxis : str, default='both'
    41        specifies which axes should have grid lines
    42    mathfont : str, default='regular'
    43        sets font used in mathtext, 'regular' uses same font as regular text.
    44        see `set_mathfont` for all options
    45    '''
    46    # Load settings from style file
    47    mstyle.use(os.path.join(_PATH,'acgc.mplstyle'))
    48
    49    # Set mathtext font
    50    set_mathfont(mathfont)
    51
    52    # Turn grid on or off
    53    if grid:
    54        grid_on(axis=gridaxis)
    55
    56    # Use high quality for inline images; Only use this if the inline backend is active
    57    # 'png' is default, 'svg' is also good
    58    if 'inline' in mpl.get_backend():
    59        matplotlib_inline.backend_inline.set_matplotlib_formats('retina')

Activate style sheet

###### Parameters

- grid (bool, default=True): turn grid lines on (True) or off (False)
- gridaxis (str, default='both'): specifies which axes should have grid lines
- mathfont (str, default='regular'): sets font used in mathtext, 'regular' uses same font as regular text. see `set_mathfont` for all options

def deactivate_style(): View Source

    61def deactivate_style():
    62    '''Restore rcParams prior to importing figstyle'''
    63    mpl.rcParams = _rcParams_old

Restore rcParams prior to importing figstyle

def set_mathfont(fontname=None): View Source

     65def set_mathfont(fontname=None):
     66    '''Set the font used for typsetting math in Matplotlib
     67
     68    Parameters
     69    ----------
     70    fontname : str, default=None
     71        Should be one of
     72        - None         : Restore mathtext font to settings before importing figstyle
     73        - 'regular'    : Use same font as regular text in math expressions (default).
     74                       Same as using \\mathregular or \\mathdefault in math expressions.
     75                       Best for mixing regular and math text for superscripts and subscripts.
     76                       May lack or have poor positioning of some math symbols (e.g. integrals).
     77                       This will overwrite mathtext.bf, mathtext.bfit, mathtext.it,
     78                       mathtext.rm in rcParams.
     79        - 'custom'     : Uses custom settings from rcParams (mathtext.bf, .bfit, .it, .rm)
     80        - 'cm'         : Computer Modern (i.e. LaTeX default)
     81        - 'stix'       : STIX serif
     82        - 'stixsans'   : STIX sans-serif; best for sans-serif math
     83        - 'dejavuserif': DejaVu Serif (not recommended)
     84        - 'dejavusans' : DejaVu Sans (not recommended)
     85    '''
     86
     87    # Check that input has an allowed value
     88    allowedvalues = ['None','regular','custom','cm','stix','stixsans','dejavusans','dejavuserif']
     89    if (fontname not in allowedvalues) and (fontname is not None):
     90        raise ValueError('Font name should be one of the allowed values: '+','.join(allowedvalues))
     91
     92    if fontname is None:
     93        # Restore old mathtext settings
     94        mpl.rcParams.update( {key:_rcParams_old[key] for key in
     95                              ['mathtext.fontset','mathtext.bf','mathtext.bfit',
     96                               'mathtext.it','mathtext.rm']})
     97
     98    elif fontname == 'regular':
     99        # Set the math font to the font used for regular text
    100
    101        # Name of the text font
    102        textfont = mpl.rcParams[f'font.{mpl.rcParams["font.family"][0]:s}'][0]
    103        # Use the same font for math
    104        mpl.rcParams.update({'mathtext.fontset': 'custom',
    105                            'mathtext.bf'   : f'{textfont}:bold',
    106                            'mathtext.bfit' : f'{textfont}:italic:bold',
    107                            'mathtext.it'   : f'{textfont}:italic',
    108                            'mathtext.rm'   : f'{textfont}'})
    109    else:
    110        # Set the math font to the value provided
    111        mpl.rcParams['mathtext.fontset'] = fontname

Set the font used for typsetting math in Matplotlib

###### Parameters

- fontname (str, default=None): Should be one of
  - None : Restore mathtext font to settings before importing figstyle
  - 'regular' : Use same font as regular text in math expressions (default). Same as using \mathregular or \mathdefault in math expressions. Best for mixing regular and math text for superscripts and subscripts. May lack or have poor positioning of some math symbols (e.g. integrals). This will overwrite mathtext.bf, mathtext.bfit, mathtext.it, mathtext.rm in rcParams.
  - 'custom' : Uses custom settings from rcParams (mathtext.bf, .bfit, .it, .rm)
  - 'cm' : Computer Modern (i.e. LaTeX default)
  - 'stix' : STIX serif
  - 'stixsans' : STIX sans-serif; best for sans-serif math
  - 'dejavuserif': DejaVu Serif (not recommended)
  - 'dejavusans' : DejaVu Sans (not recommended)

def grid_off(): View Source

    113def grid_off():
    114    '''Turn off grid lines'''
    115    mpl.rcParams['axes.grid'] = False

Turn off grid lines

def grid_on(axis='both'): View Source

    117def grid_on(axis='both'):
    118    '''Turn on grid lines
    119
    120    Parameters
    121    ----------
    122    axis : {'both', 'x', 'y'}
    123        specifies which axes should have grid lines
    124    '''
    125    mpl.rcParams['axes.grid'] = True
    126    mpl.rcParams['axes.grid.axis'] = axis

Turn on grid lines

###### Parameters

- axis ({'both', 'x', 'y'}): specifies which axes should have grid lines

def load_fonts(): View Source

    128def load_fonts():
    129    '''Load fonts contained in the acgc/fonts subdirectory'''
    130
    131    # User fonts
    132    fonts_pylib = mfonts.findSystemFonts(os.path.join(_PATH,'fonts'))
    133
    134    # Cached fonts
    135    fonts_cached = mfonts.fontManager.ttflist
    136    fonts_cached_paths = [ font.fname for font in fonts_cached ]
    137
    138    # Add fonts that aren't already installed
    139    rebuild = False
    140    for font in fonts_pylib:
    141        if font not in fonts_cached_paths:
    142            if rebuild is False:
    143                # Issue warning, first time only
    144                warnings.warn('Rebuilding font cache. This can take time.')
    145            rebuild = True
    146            mfonts.fontManager.addfont(font)
    147
    148    # Save font cache
    149    if rebuild:
    150        cache = os.path.join(
    151                        mpl.get_cachedir(),
    152                        f'fontlist-v{mfonts.FontManager.__version__}.json'
    153                    )
    154        mfonts.json_dump(mfonts.fontManager, cache)

Load fonts contained in the acgc/fonts subdirectory

def load_crameri_colormaps(noprefix=True): View Source

    156def load_crameri_colormaps(noprefix=True):
    157    '''Load Fabio Crameri's Scientific color maps
    158
    159    https://www.fabiocrameri.ch/colourmaps/
    160    https://github.com/callumrollo/cmcrameri
    161
    162    Parameters
    163    ----------
    164    noprefix : bool, default=True
    165        If True, remove the 'cmc.' prefix from the colormap names
    166    '''
    167
    168    # Import the colormaps; The registered names will be prefixed with 'cmc.'
    169    try:
    170        from cmcrameri import cm
    171    except ImportError:
    172        warnings.warn('Scientific colormaps not found. Install with `conda install cmcrameri` if desired.', ImportWarning)
    173        return
    174
    175    # Remove the 'cmc.' prefix from the colormap names
    176    for name in list(mpl.colormaps):
    177        if name[:4]=='cmc.':
    178
    179            # Register the colormap without the prefix
    180            try:
    181                mpl.colormaps.register( mpl.colormaps[name], name=name[4:] )
    182            except ValueError:
    183                pass
    184
    185            # Unregister the original colormap
    186            if noprefix:
    187                mpl.colormaps.unregister(name)

Load Fabio Crameri's Scientific color maps

https://www.fabiocrameri.ch/colourmaps/ https://github.com/callumrollo/cmcrameri

###### Parameters

- noprefix (bool, default=True): If True, remove the 'cmc.' prefix from the colormap names