Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Change behavior of `font.*` rcParams so they take effect only on to-b…

…e-created text objects
  • Loading branch information...
commit cc617006f7f0a18396cecf4a9f1e222f1ee5204e 1 parent edb1526
@mdboom mdboom authored
View
7 doc/api/api_changes.rst
@@ -15,7 +15,12 @@ For new features that were added to matplotlib, please see
Changes in 1.3.x
================
-* Fixed a bug in setting the position for the right/top spine with data
+* The `font.*` rcParams now affect only text objects created after the
+ rcParam has been set, and will not retroactively affect already
+ existing text objects. This brings their behavior in line with most
+ other rcParams.
+
+* Fixed a bug in setting the position for the right/top spine with data
position type. Previously, it would draw the right or top spine at
+1 data offset.
View
7 doc/users/whats_new.rst
@@ -33,6 +33,13 @@ simply call `pyplot.xkcd` before creating your plot.
.. plot:: mpl_examples/showcase/xkcd.py
+Changes to font rcParams
+------------------------
+The `font.*` rcParams now affect only text objects created after the
+rcParam has been set, and will not retroactively affect already
+existing text objects. This brings their behavior in line with most
+other rcParams.
+
``axes.xmargin`` and ``axes.ymargin`` added to rcParams
-------------------------------------------------------
``rcParam`` values (``axes.xmargin`` and ``axes.ymargin``) were added
View
60 lib/matplotlib/font_manager.py
@@ -808,11 +808,10 @@ def set_family(self, family):
'fantasy', or 'monospace', or a real font name.
"""
if family is None:
- self._family = None
- else:
- if is_string_like(family):
- family = [family]
- self._family = family
+ family = rcParams['font.family']
+ if is_string_like(family):
+ family = [family]
+ self._family = family
set_name = set_family
def set_style(self, style):
@@ -820,6 +819,8 @@ def set_style(self, style):
Set the font style. Values are: 'normal', 'italic' or
'oblique'.
"""
+ if style is None:
+ style = rcParams['font.style']
if style not in ('normal', 'italic', 'oblique', None):
raise ValueError("style must be normal, italic or oblique")
self._slant = style
@@ -829,6 +830,8 @@ def set_variant(self, variant):
"""
Set the font variant. Values are: 'normal' or 'small-caps'.
"""
+ if variant is None:
+ variant = rcParams['font.variant']
if variant not in ('normal', 'small-caps', None):
raise ValueError("variant must be normal or small-caps")
self._variant = variant
@@ -840,14 +843,15 @@ def set_weight(self, weight):
'regular', 'book', 'medium', 'roman', 'semibold', 'demibold',
'demi', 'bold', 'heavy', 'extra bold', 'black'
"""
- if weight is not None:
- try:
- weight = int(weight)
- if weight < 0 or weight > 1000:
- raise ValueError()
- except ValueError:
- if weight not in weight_dict:
- raise ValueError("weight is invalid")
+ if weight is None:
+ weight = rcParams['font.weight']
+ try:
+ weight = int(weight)
+ if weight < 0 or weight > 1000:
+ raise ValueError()
+ except ValueError:
+ if weight not in weight_dict:
+ raise ValueError("weight is invalid")
self._weight = weight
def set_stretch(self, stretch):
@@ -857,14 +861,15 @@ def set_stretch(self, stretch):
'semi-expanded', 'expanded', 'extra-expanded' or
'ultra-expanded', or a numeric value in the range 0-1000.
"""
- if stretch is not None:
- try:
- stretch = int(stretch)
- if stretch < 0 or stretch > 1000:
- raise ValueError()
- except ValueError:
- if stretch not in stretch_dict:
- raise ValueError("stretch is invalid")
+ if stretch is None:
+ stretch = rcParams['font.weight']
@pelson Collaborator
pelson added a note

Was this supposed to be 'font.stretch'? Relates to #2006

@mdboom Owner
mdboom added a note

Indeed. Sorry about that -- didn't take long to find, though. Fix in de956ef

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ try:
+ stretch = int(stretch)
+ if stretch < 0 or stretch > 1000:
+ raise ValueError()
+ except ValueError:
+ if stretch not in stretch_dict:
+ raise ValueError("stretch is invalid")
self._stretch = stretch
def set_size(self, size):
@@ -873,12 +878,13 @@ def set_size(self, size):
'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'
or an absolute font size, e.g., 12.
"""
- if size is not None:
- try:
- size = float(size)
- except ValueError:
- if size is not None and size not in font_scalings:
- raise ValueError("size is invalid")
+ if size is None:
+ size = rcParams['font.size']
+ try:
+ size = float(size)
+ except ValueError:
+ if size is not None and size not in font_scalings:
+ raise ValueError("size is invalid")
self._size = size
def set_file(self, file):
View
4 lib/matplotlib/rcsetup.py
@@ -262,7 +262,7 @@ def validate_colorlist(s):
def validate_stringlist(s):
'return a list'
- if type(s) is str:
+ if type(s) in (str, unicode):
return [v.strip() for v in s.split(',')]
else:
assert type(s) in [list, tuple]
@@ -513,7 +513,7 @@ def __call__(self, s):
## font props
- 'font.family': ['sans-serif', str], # used by text object
+ 'font.family': ['sans-serif', validate_stringlist], # used by text object
@leejjoon Owner

@mdboom : is this change necessary? This causes an error with texmanager.py, which expects rcParams["font.family"] to be a string. And I guess there are user codes that will fail with this change.

@mdboom Owner
mdboom added a note

Ah -- I missed that about texmanager. The other text handling handled this just fine without further changes. I think maybe we should try to fix texmanager to support a list (see #2012).

Here the use case that brought this about:

The xkcd function needs to change the font of all text that is created while it is in effect, and then go back to the previous settings afterward. If you set font.family to fantasy and change font.fantasy to Humor Sans, this doesn't work, because the lookup from a category name ('fantasy') to a concrete name is dynamic so when font.family is reverted, so is all of the text that was created in the xkcd context. I think this is the correct behavior for category names, as they are supposed to be dynamically updatable. So the only way to make the font setting on a text object permanent is to not use the category names but to use an actual concrete font name. And ideally that should be provided as a list so that we can account for users who don't have a particular font installed.

I'm not sure what user code would fail because of this change -- if it does, I think it's probably a real corner case. I know there is a lot of code that sets font.family as a single name, but that will continue to work. But I think it's much less common that user code will read this value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
'font.style': ['normal', str],
'font.variant': ['normal', str],
'font.stretch': ['normal', str],
@pelson

Was this supposed to be 'font.stretch'? Relates to #2006

@mdboom

Indeed. Sorry about that -- didn't take long to find, though. Fix in de956ef

@leejjoon

@mdboom : is this change necessary? This causes an error with texmanager.py, which expects rcParams["font.family"] to be a string. And I guess there are user codes that will fail with this change.

@mdboom

Ah -- I missed that about texmanager. The other text handling handled this just fine without further changes. I think maybe we should try to fix texmanager to support a list (see #2012).

Here the use case that brought this about:

The xkcd function needs to change the font of all text that is created while it is in effect, and then go back to the previous settings afterward. If you set font.family to fantasy and change font.fantasy to Humor Sans, this doesn't work, because the lookup from a category name ('fantasy') to a concrete name is dynamic so when font.family is reverted, so is all of the text that was created in the xkcd context. I think this is the correct behavior for category names, as they are supposed to be dynamically updatable. So the only way to make the font setting on a text object permanent is to not use the category names but to use an actual concrete font name. And ideally that should be provided as a list so that we can account for users who don't have a particular font installed.

I'm not sure what user code would fail because of this change -- if it does, I think it's probably a real corner case. I know there is a lot of code that sets font.family as a single name, but that will continue to work. But I think it's much less common that user code will read this value.

Please sign in to comment.
Something went wrong with that request. Please try again.