Skip to content

Add easy style sheet selection #2236

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

Merged
merged 36 commits into from
Nov 18, 2013
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
643c74b
Add easy style sheet selection.
tonysyu Jul 21, 2013
3270aa4
Add rc_params_in_file to return partially-filled RcParams
tonysyu Jul 21, 2013
d83a03c
Rename style files to `*.style`
tonysyu Jul 21, 2013
c8cc486
Allow style.use to open URLs
tonysyu Jul 21, 2013
455b54c
Remove pyplot import
tonysyu Jul 21, 2013
7769b29
Add style context manager and tests
tonysyu Jul 23, 2013
3914089
Change style extension to *.mplstyle
tonysyu Jul 23, 2013
c3fae2e
Got a little crazy with the whitespace
tonysyu Jul 23, 2013
a3de231
Add style package and data to setupext.py
tonysyu Jul 25, 2013
d56f73e
Move test so that it actually runs.
tonysyu Sep 19, 2013
ec6ce6b
Use explicit string check
tonysyu Sep 19, 2013
5fdc037
Hide rc_params_in_file from parent namespace
tonysyu Sep 19, 2013
0c7437c
Remove usage of import *
tonysyu Sep 19, 2013
200d2e0
Clarify docstring
tonysyu Sep 19, 2013
7392ce6
added `matplotlib.style` to pyplot import list
tacaswell Sep 27, 2013
ea63c99
fix url rc specification
adrn Sep 17, 2013
eaa23ee
fixed divergent naming scheme
tacaswell Sep 27, 2013
5f80ca1
pep8 clean up
tacaswell Sep 27, 2013
f5ecf5e
Add docs for style package
tonysyu Sep 29, 2013
a8ef5bf
Import style package for easy use.
tonysyu Sep 29, 2013
dc291e0
Use style package from pyplot
tonysyu Sep 29, 2013
c5b5bb4
Fix test
tonysyu Sep 29, 2013
7ac26ee
pep8
tacaswell Oct 18, 2013
46a725b
Clear style settings between tests
mdboom Sep 30, 2013
d372a35
Add note that style sheets are experimental.
tonysyu Oct 19, 2013
e714c77
added python3 emulation code + six + fixed up print calls
tacaswell Oct 27, 2013
512b77c
removed unneeded print statements
tacaswell Oct 31, 2013
17282c8
Attempt to fix python 3 test errors on Travis CI
tonysyu Nov 13, 2013
a6142fc
Remove test from list to test Travis CI failure.
tonysyu Nov 14, 2013
19e7bed
Remove test file to test Travis CI failure
tonysyu Nov 14, 2013
c604498
Revert commits used to test Travis CI test failures.
tonysyu Nov 14, 2013
0b098e2
Fix import for python 3
tonysyu Nov 17, 2013
7e2bffb
Use iteritems from `six` module
tonysyu Nov 17, 2013
1d87f34
Add compatibility layer for Python 3's urlopen
tonysyu Nov 17, 2013
79f83c9
Fix _fix_url on Python 2.6
mdboom Nov 18, 2013
246c348
Merge pull request #6 from mdboom/style/py26-fixes
tonysyu Nov 18, 2013
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
Prev Previous commit
Next Next commit
Add style context manager and tests
  • Loading branch information
tonysyu committed Nov 17, 2013
commit 7769b2940768ee81ca2ed031f51ef6b3ed61e3e8
44 changes: 39 additions & 5 deletions lib/matplotlib/style/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,30 @@

``use``
Select style sheet to override the current matplotlib settings.
``context``
Context manager to use a style sheet temporarily.
``available``
List available style sheets.
``library``
A dictionary of style names and matplotlib settings.
"""
import os
import re
import contextlib

import numpy as np
import matplotlib as mpl


__all__ = ['use', 'available', 'library']
__all__ = ['use', 'context', 'available', 'library', 'reload_library']


_here = os.path.abspath(os.path.dirname(__file__))
BASE_LIBRARY_PATH = os.path.join(_here, 'stylelib')
# Users may want multiple library paths, so store a list of paths.
USER_LIBRARY_PATHS = [os.path.join('~', '.matplotlib', 'stylelib')]
STYLE_FILE_PATTERN = re.compile('([\S]+).style$')
STYLE_EXTENSION = 'style'
STYLE_FILE_PATTERN = re.compile('([\S]+).%s$' % STYLE_EXTENSION)


def is_style_file(filename):
Expand All @@ -31,7 +35,7 @@ def is_style_file(filename):


def use(name):
"""Use matplotlib rc parameters from a pre-defined name or from a file.
"""Use matplotlib style settings from a known style sheet or from a file.

Parameters
----------
Expand All @@ -55,6 +59,28 @@ def use(name):
mpl.rcParams.update(library[style])


@contextlib.contextmanager
def context(name, after_reset=False):
"""Context manager for using style settings temporarily.

Parameters
----------
name : str or list of str
Name of style or path/URL to a style file. For a list of available
style names, see `style.available`. If given a list, each style is
applied from first to last in the list.
after_reset : bool
If True, apply style after resetting settings to their defaults;
otherwise, apply style on top of the current settings.
"""
initial_settings = mpl.rcParams.copy()
if after_reset:
mpl.rcdefaults()
use(name)
yield
mpl.rcParams.update(initial_settings)


def load_base_library():
"""Load style library defined in this package."""
library = dict()
Expand Down Expand Up @@ -114,5 +140,13 @@ def update_nested_dict(main_dict, new_dict):
# Load style library
# ==================
_base_library = load_base_library()
library = update_user_library(_base_library)
available = library.keys()

library = None
available = []

def reload_library():
"""Reload style library."""
global library, available
library = update_user_library(_base_library)
available[:] = library.keys()
reload_library()
61 changes: 61 additions & 0 deletions lib/matplotlib/style/tests/test_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import os
import shutil
import tempfile
from contextlib import contextmanager

import matplotlib as mpl
from matplotlib import style
from matplotlib.style.core import USER_LIBRARY_PATHS, STYLE_EXTENSION


PARAM = 'image.cmap'
VALUE = 'pink'
DUMMY_SETTINGS = {PARAM: VALUE}


@contextmanager
def temp_style(style_name, settings=None):
"""Context manager to create a style sheet in a temporary directory."""
settings = DUMMY_SETTINGS
temp_file = '%s.%s' % (style_name, STYLE_EXTENSION)

# Write style settings to file in the temp directory.
tempdir = tempfile.mkdtemp()
with open(os.path.join(tempdir, temp_file), 'w') as f:
for k, v in settings.iteritems():
f.write('%s: %s' % (k, v))

# Add temp directory to style path and reload so we can access this style.
USER_LIBRARY_PATHS.append(tempdir)
style.reload_library()

try:
yield
finally:
shutil.rmtree(tempdir)


def test_available():
with temp_style('_test_', DUMMY_SETTINGS):
assert '_test_' in style.available


def test_use():
mpl.rcParams[PARAM] = 'gray'
with temp_style('test', DUMMY_SETTINGS):
style.use('test')
assert mpl.rcParams[PARAM] == VALUE


def test_context():
mpl.rcParams[PARAM] = 'gray'
with temp_style('test', DUMMY_SETTINGS):
with style.context('test'):
assert mpl.rcParams[PARAM] == VALUE
# Check that this value is reset after the exiting the context.
assert mpl.rcParams[PARAM] == 'gray'


if __name__ == '__main__':
from numpy import testing
testing.run_module_suite()