8000 Added a find_all method to the RcParams dictionary. by pelson · Pull Request #1861 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Added a find_all method to the RcParams dictionary. #1861

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 3 commits into from
Apr 18, 2013
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Updated RcParams.find_all to use re. Added a str and repr for RcParam…
…s & added some tests.
  • Loading branch information
pelson committed Apr 12, 2013
commit f8d289405caedc5d0bae0c2c7bf094b845d606c7
15 changes: 15 additions & 0 deletions doc/users/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,21 @@ used, 10000 which, in the case of straight contours was sometimes quite distant
from the requested location. Much more precise label positioning is now
possible.

Quickly find rcParams
---------------------
Phil Elson made it easier to search for rcParameters by passing a
valid regular expression to :func:`matplotlib.RcParams.find_all`.
:class:`matplotlib.RcParams` now also has a pretty repr and str representation
so that search results are printed prettily:

>>> import matplotlib
>>> print(matplotlib.rcParams.find_all('\.size'))
RcParams({'font.size': 12,
'xtick.major.size': 4,
'xtick.minor.size': 2,
'ytick.major.size': 4,
'ytick.minor.size': 2})

.. _whats-new-1-2-2:

new in matplotlib 1.2.2
Expand Down
25 changes: 19 additions & 6 deletions lib/matplotlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -706,8 +706,8 @@ class RcParams(dict):
:mod:`matplotlib.rcsetup`
"""

validate = dict([ (key, converter) for key, (default, converter) in \
defaultParams.iteritems() ])
validate = dict((key, converter) for key, (default, converter) in \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this has been merged already, but I only just saw this trailing backslash.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for finding. I have just fixed directly on 1.3.x in `
207469f

defaultParams.iteritems())
msg_depr = "%s is deprecated and replaced with %s; please use the latter."
msg_depr_ignore = "%s is deprecated and ignored. Use %s"

Expand Down Expand Up @@ -738,6 +738,17 @@ def __getitem__(self, key):
key = alt
return dict.__getitem__(self, key)

def __repr__(self):
import pprint
class_name = self.__class__.__name__
indent = len(class_name) + 1
repr_split = pprint.pformat(dict(self), indent=1, width=80 - indent).split('\n')
repr_indented = ('\n' + ' ' * indent).join(repr_split)
return '{}({})'.format(class_name, repr_indented)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this style of formatting is not supported in python2.6

In [5]: '{}({})'.format('sorry', '>= 2.7 only')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-b84304fedd68> in <module>()
----> 1 '{}({})'.format('sorry', '>= 2.7 only')

ValueError: zero length field name in format

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ivanov - travis spotted this one too - I'm always making this mistake! Bring on ending support for 2.6 😉

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Phil Elson, on 2013-04-12 12:32, wrote:

Thanks @ivanov - travis spotted this one too -

Good thing Travis spotted it as well, though sometimes it's easy
to ignore that person, since, as we've seen in the past, Travis
isn't always very reliable ;)

Bring on ending support for 2.6 😉

You won't hear complaints from me about it. Machines where I'm
still running 2.6 are not ones I will be updating matplotlib.


def __str__(self):
return '\n'.join('{}: {}'.format(k, v) for k, v in sorted(self.items()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above (>= 2.7 only)


def keys(self):
"""
Return sorted list of keys.
Expand All @@ -750,22 +761,24 @@ def values(self):
"""
Return values in order of sorted keys.
"""
return [self[k] for k in self.iterkeys()]
return [self[k] for k in self.keys()]

def find_all(self, key_contains):
def find_all(self, pattern):
"""
Return the subset of this RcParams dictionary for which the given
``key_contains`` string is found somewhere in the key.
``pattern`` string is found, by :func:`re.search`, somewhere in the key.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this a little bit unclear.

Maybe just say "pattern is a Python regular expression".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mdboom. I'll change to:

Return the subset of this RcParams dictionary whose keys match,
using :func:`re.search`, the given "pattern".

I'm happy to iterate on this though if you have further improvements?


.. note::

Changes to the returned dictionary are *not* propagated to
the parent RcParams dictionary.

"""
import re
pattern_re = re.compile(pattern)
return RcParams((key, value)
for key, value in self.items()
if key_contains in key)
if pattern_re.search(key))


def rc_params(fail_on_error=False):
Expand Down
20 changes: 20 additions & 0 deletions lib/matplotlib/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from __future__ import print_function
from matplotlib import rcParams, rcdefaults, use

import difflib


_multiprocess_can_split_ = True


def setup():
use('Agg', warn=False) # use Agg backend for these tests

Expand All @@ -13,3 +17,19 @@ def setup():
rcParams['font.family'] = 'Bitstream Vera Sans'
rcParams['text.hinting'] = False
rcParams['text.hinting_factor'] = 8


def assert_str_equal(reference_str, test_str,
format_str='String {str1} and {str2} do not match:\n{differences}'):
"""
Assert the two strings are equal. If not, fail and print their diffs using difflib.

"""
if reference_str != test_str:
diff = difflib.unified_diff(reference_str.splitlines(1),
test_str.splitlines(1),
'Reference', 'Test result',
'', '', 0)
raise ValueError(format_str.format(str1=reference_str,
str2=test_str,
differences=''.join(diff)))
39 changes: 38 additions & 1 deletion lib/matplotlib/tests/test_rcparams.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import os

import matplotlib as mpl
from matplotlib.tests import assert_str_equal


mpl.rc('text', usetex=False)
mpl.rc('lines', linewidth=22)

Expand Down Expand Up @@ -34,5 +37,39 @@ def test_rcparams():
mpl.rcParams['lines.linewidth'] = linewidth


def test_RcParams_class():
rc = mpl.RcParams({'font.cursive': ['Apple Chancery',
'Textile',
'Zapf Chancery',
'cursive'],
'font.family': 'sans-serif',
'font.weight': 'normal',
'font.size': 12})


expected_repr = """
RcParams({'font.cursive': ['Apple Chancery',
'Textile',
'Zapf Chancery',
'cursive'],
'font.family': 'sans-serif',
'font.size': 12,
'font.weight': 'normal'})""".lstrip()

assert_str_equal(expected_repr, repr(rc))

expected_str = """
font.cursive: ['Apple Chancery', 'Textile', 'Zapf Chancery', 'cursive']
font.family: sans-serif
font.size: 12
font.weight: normal""".lstrip()

assert_str_equal(expected_str, str(rc))

# test the find_all functionality
assert ['font.cursive', 'font.size'] == sorted(rc.find_all('i[vz]').keys())
assert ['font.family'] == rc.find_all('family').keys()

if __name__ == '__main__':
test_rcparams()
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
0